【问题标题】:Why cannot we override static method in the derived class [duplicate]为什么我们不能在派生类中覆盖静态方法[重复]
【发布时间】:2012-07-24 11:16:10
【问题描述】:

可能重复:
Can we override static method in Java?

我们不能覆盖基类的静态方法。

其实我试过这样的:

// Base class
public class StaticExampleImpl {
    protected String name="overriding";
    public static void display(){
        System.out.println("static method display : base class");
    }
}

那么派生类如下:

//derived class
public class StaticDemo extends StaticExampleImpl {
    // cannot override the static methods...
    //@Override
    public static void display(){
        System.out.println("child!!! static method display");
    }
    public static void main(String[] args) {
        StaticDemo d=new StaticDemo();
        d.display(); // derived class display is called rather than Base class.
    }
}

所以,当我取消注释 @Override 方法时,它会给出错误,因为“静态方法不能被覆盖”。但评论它工作正常。因此,当我们创建对象并使用实例调用静态方法时,它们可以正常工作。那么有什么区别呢??

【问题讨论】:

  • 您尝试做的事情毫无意义。为什么你想要另一个与现有方法同名的静态方法?改个名字就好了。

标签: java


【解决方案1】:

因为静态方法不会被继承。

当您取消注释 @Override 时,这意味着您正在尝试覆盖 不可能的静态方法,这就是为什么你得到一个 错误。

但是当你评论 //@Override 这意味着你正在声明一个新的 子类中的方法。

【讨论】:

  • 不,它被继承了,对于上面的例子,注释子类的显示,然后如果你调用,d.display(),即使它可以工作
  • @ lakshmi 静态在 Java 中不被继承。相反,类中声明的静态成员(受“访问”限制)在派生类的命名空间中直接可见,除非它们被派生类中的声明“隐藏”。
【解决方案2】:

静态方法不属于类的实例,它属于实际的类。

当您调用d.display(); 时,您实际上是在调用StaticDemo d 引用的静态方法的静态方法。

如果你这样做了:

StaticExampleImpl d2 = new StaticDemo();d2.display(),你会发现它调用了基类的显示。

但是,不要这样做。这会导致代码混乱,并且是一种糟糕的继承实现方式。

【讨论】:

    【解决方案3】:

    Overriding 依赖于一个类的实例。 polymorphism是您可以子类化一个类,实现这些subclasses的对象对于超类中定义的那些方法(以及子类中的overridden)具有不同的行为。static方法不属于一个类,所以这个概念不适用。

    【讨论】:

      【解决方案4】:

      静态方法不能被继承。如果你想调用'base'类的静态方法,你必须显式调用StaticExampleImpl.display()

      【讨论】:

      • 您可以通过其子类访问静态方法,因为它确实会被继承
      【解决方案5】:

      静态方法绑定到无法继承的类,这就是为什么派生类中不能有基类静态方法的原因。

      【讨论】:

        【解决方案6】:

        如果您尝试覆盖静态方法,则您的设计可能有问题。

        OOP 和多态允许您执行以下操作:

        public class MyClass1 {
        
           public String toString() { return "MyClass1 Instance"; }
        
        }
        
        public class MyClass2  extends MyClass1 {
        
           @Override
           public String toString() { return "MyClass1 Instance"; }
        
        }
        
        public void printSomething(MyClass1 myclass1){
              System.out.println(myclass1);
        }
        

        在 printSomething 中,要调用的 toString 方法是 myClass1 的运行时类型的方法:当你在 printSomething 中传递一个 MyClass2 的实例时,它的编译类型将是 MyClass1,但它的运行时类型将是 MyClass2

        很明显,要使用多态性,您需要对象实例,其中实际运行时类型可能与编译类型不同。然而,静态方法不属于任何对象实例,而是属于类。你为什么不向我们解释你想要达到的目标?

        【讨论】:

          【解决方案7】:

          以下代码:

          StaticExampleImpl one = new StaticExampleImpl();
          StaticDemo two = new StaticDemo();
          StaticExampleImpl three = two;
          
          one.display();
          two.display();
          three.display();
          

          将产生以下输出:

          static method display : base class
          child!!! static method display
          static method display : base class
          

          如您所见,该方法不会被继承。这就是为什么它们被称为“静态方法”的原因:它们是静态调用的,而不是像实例方法那样动态调用的。调用静态方法时,类的编译时类型很重要,而不是运行时类型。

          这也是你不应该通过对象实例调用静态方法的原因。总是这样称呼他们:

          StaticExampleImpl.display();
          StaticDemo.display();
          

          这完全消除了人们期望继承适用于这些方法时可能(将会)出现的困惑。

          【讨论】:

            【解决方案8】:

            java中的任何静态块,可能是静态变量,类加载时加载方法。你可能知道java中的类加载器。所以事情是静态块(方法,变量或任何东西都是静态的)被加载一次。所以你实际上不能覆盖任何静态块。

            注释@Override 意味着您正在子类中编写另一个静态方法,而不仅仅是覆盖基类方法。

            【讨论】:

              猜你喜欢
              • 2013-12-15
              • 2017-10-06
              • 1970-01-01
              • 2014-09-28
              • 2016-06-14
              • 2011-09-16
              • 2016-03-17
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多