【问题标题】:Static methods between inheritance classes - Java继承类之间的静态方法 - Java
【发布时间】:2019-12-04 06:54:25
【问题描述】:

以下代码:

public class NewClass { 
    public static class superclass { 
        static void print() 
        { 
            System.out.println("print in superclass."); 
        } 
    } 
    public static class subclass extends superclass { 
        static void print() 
        { 
            System.out.println("print in subclass."); 
        } 
    } 

    public static void main(String[] args) 
    { 
        superclass A = new superclass(); 
        superclass B = new subclass(); 
        A.print(); 
        B.print(); 
    } 
}

这里B.print() 打印-->“在超类中打印。”,但我希望它打印“在子类中打印”。因为'B'是子类的对象。

但是,如果我将static void print() 更改为void print(),那么它会正确打印“在子类中打印。”。

谁能帮助理解这一点?

【问题讨论】:

  • 方法覆盖仅存在于实例方法中。静态方法不能被覆盖。
  • 动态绑定不适用于静态方法。
  • 静态方法始终属于其定义的类,因此您不会调用继承的方法。
  • @mkemmerz,但是superclass B = new subclass(); 会创建子类的对象,对吧?
  • @GarimaAgarwal 确实如此!但是,您没有调用实例方法。这很令人困惑,因为您打破了 java 命名约定。 B.print() 不是调用你声明的对象 B,而是调用 B 的静态方法。

标签: java inheritance static


【解决方案1】:

我们可以在子类中声明具有相同签名的静态方法,但它不会被视为重写,因为不会有任何运行时多态性。

如果派生类定义了与基类中的静态方法具有相同签名的静态方法,则派生类中的方法会隐藏基类中的方法。

/* Java program to show that if static method is redefined by 
   a derived class, then it is not overriding. */

// Superclass 
class Base { 

    // Static method in base class which will be hidden in subclass  
    public static void display() { 
        System.out.println("Static or class method from Base"); 
    } 

     // Non-static method which will be overridden in derived class  
     public void print()  { 
         System.out.println("Non-static or Instance method from Base"); 
    } 
} 

// Subclass 
class Derived extends Base { 

    // This method hides display() in Base  
    public static void display() { 
         System.out.println("Static or class method from Derived"); 
    } 

    // This method overrides print() in Base  
    public void print() { 
         System.out.println("Non-static or Instance method from Derived"); 
   } 
} 

// Driver class 
public class Test { 
    public static void main(String args[ ])  { 
       Base obj1 = new Derived(); 

       // As per overriding rules this should call to class Derive's static  
       // overridden method. Since static method can not be overridden, it  
       // calls Base's display()  
       obj1.display();   

       // Here overriding works and Derive's print() is called  
       obj1.print();      
    } 
}   

输出:

来自 Base
的静态或类方法 非静态或实例方法来自 派生的

以下是 Java 中方法覆盖和静态方法的一些要点。

1) 对于类(或静态)方法,根据引用的类型调用方法,而不是根据被引用的对象,也就是说方法调用是在编译时决定的。

2)对于实例(或非静态)方法,方法是根据被引用对象的类型调用的,而不是根据引用的类型,这意味着方法调用是在运行时决定的。

3) 实例方法不能覆盖静态方法,静态方法不能隐藏实例方法。例如,以下程序有两个编译器错误。

4) 在子类(或派生类)中,我们可以重载继承自超类的方法。这样的重载方法既不会隐藏也不会覆盖超类方法——它们是新方法,是子类独有的。

Source

【讨论】:

    【解决方案2】:

    静态方法不是继承树的一部分。它们的存在仅与它们的类相关,而与它们的子类或对象无关。为了减少编译错误,Java 允许您调用它们,就好像它们属于子类或对象一样,但它们不属于。

    为了提高可读性,您应该遵循常见的 Java 命名约定: 类名以大写字母开头的驼峰式命名,变量和成员以小写字母开头的驼峰式命名。

    【讨论】:

      【解决方案3】:

      当您为超类初始化对象时,它会返回超类方法,请参见下面的代码

      public class NewClass { 
      public static class superclass { 
          static void print() 
          { 
              System.out.println("print in superclass."); 
          } 
      } 
      public static class subclass extends superclass { 
          static void print() 
          { 
              System.out.println("print in subclass."); 
          } 
      } 
      
      public static void main(String[] args) 
      { 
          superclass A = new superclass(); 
          subclass B = new subclass(); 
          A.print(); 
          B.print(); 
      } 
      

      }

      【讨论】:

        【解决方案4】:

        静态方法调用由其静态声明类型决定在编译时:容器(变量)类型。

        非静态方法在运行时由它的实际类型决定:用'new'创建的对象的类。

        在运行时通过实际类型(而不是容器类型)动态选择目标方法的能力称为多态性

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-03-03
          • 1970-01-01
          • 2012-05-04
          • 1970-01-01
          • 2012-06-21
          • 2015-03-20
          相关资源
          最近更新 更多