Java中是否inheritance了静态方法?

我正在阅读Khalid Mughal 编写的Java™SCJPauthentication程序员指南

在inheritance章节中,它解释了这一点

成员的传承与他们宣称的可及性密切相关。 如果超类成员可以通过其子类中的简单名称访问(不使用任何额外的语法,如超级),该成员被视为inheritance

它还提到静态方法不被inheritance。 但下面的代码是完美的罚款:

class A { public static void display() { System.out.println("Inside static method of superclass"); } } class B extends A { public void show() { // This works - accessing display() by its simple name - // meaning it is inherited according to the book. display(); } } 

我如何能够直接在B类中使用display()B.display()B.display()也可以。

本书的解释仅适用于实例方法吗?

所有可访问的方法都由子类inheritance。

从Sun Java 教程 :

子类inheritance父类的所有公共和受保护成员,不pipe子类是什么包。如果子类与其父类位于同一个包中,它也inheritance父类的包私有成员。 您可以按原样使用inheritance的成员,replace它们,隐藏它们,或者用新成员来补充它们

与inheritance的静态(类)方法和inheritance的非静态(实例)方法的唯一区别在于,当您编写具有相同签名的新静态方法时,旧的静态方法只是隐藏,不会覆盖。

从页面上的重写和隐藏的区别。

隐藏和压倒性之间的区别具有重要的意义。 被调用的重写方法的版本是子类中的版本。 被调用的隐藏方法的版本取决于它是从超类还是子类调用

如果这就是这本书真正的说法,这是错误的。

Java语言规范#8.4.8规定:

8.4.8inheritance,重写和隐藏

C类从它的直接超类inheritance了超类的所有具体方法m(包括静态和实例),以下所有情况都是正确的:

  • m是C的直接超类的成员

  • m在与C相同的包中是公开的,受保护的或者声明为包访问

  • 在C中声明的方法没有一个是m的签名的子签名(第8.4.2节)的签名。

[1]在我的副本中没有说2000年第1版。

B.display()工作,因为静态声明使方法/成员属于类,而不是任何特定的类实例(又名对象)。 你可以在这里阅读更多。

另外要注意的是,你不能重写一个静态方法,你可以让你的子类声明一个具有相同签名的静态方法,但是它的行为可能与你期望的不同。 这可能是它不被视为inheritance的原因。 你可以在这里查看有问题的场景和解释。

您可以在下面的代码中体验到差异,这是对代码的稍微修改。

 class A { public static void display() { System.out.println("Inside static method of superclass"); } } class B extends A { public void show() { display(); } public static void display() { System.out.println("Inside static method of this class"); } } public class Test { public static void main(String[] args) { B b = new B(); b.display(); A a = new B(); a.display(); } } 

这是由于静态方法是类方法。

A.display()和B.display()将调用它们各自的类的方法。

这个概念并不像看起来那么容易。 我们可以访问没有inheritance的静态成员,这是HasA关系。 我们也可以通过扩展父类来访问静态成员。 这并不意味着它是一个ISA关系(inheritance)。 实际上,静态成员属于类,静态不是访问修饰符。 只要访问修饰符允许访问静态成员,我们可以在其他类中使用它们。 就像它是公开的那样,它可以在同一个包里面,也可以在包外面访问。 对于私人我们不能在任何地方使用它。 默认情况下,我们只能在包中使用它。 但为了保护,我们必须延长超级class。 所以得到其他类的静态方法不依赖于静态。 这取决于访问修饰符。 所以,在我看来,如果访问修饰符允许,静态成员可以访问。 否则,我们可以像Hasa-relation一样使用它们。 而且有一个关系不是inheritance。 我们再次不能重写静态方法。 如果我们可以使用其他方法,但不能覆盖它,那么它是HasA关系。 如果我们不能覆盖它们,那就不是inheritance。所以作者是100%正确的。

静态方法在Java中被inheritance,但不参与多态。 如果我们尝试重写静态方法,他们将隐藏超类静态方法,而不是覆盖它们。

静态方法在子类中inheritance,但不是多态。 当你编写静态方法的实现时,父类的方法隐藏起来,而不是被覆盖。 想想,如果它没有被inheritance,那么如果没有classname.staticMethodname();你怎么能够访问classname.staticMethodname();

所有公共和受保护的成员都可以从任何类inheritance,而默认或包成员也可以在与超类相同的包中从类inheritance。 它不依赖于它是静态还是非静态成员。

但静态成员函数不参与dynamic绑定也是如此。 如果该静态方法的签名在父类和子类中都是相同的,那么应用Shadowing的概念,而不是多态。

你可以重载静态方法,但是如果你尝试使用多态性,那么它们按照类范围工作(与我们通常所期望的相反)。

 public class A { public static void display(){ System.out.println("in static method of A"); } } public class B extends A { void show(){ display(); } public static void display(){ System.out.println("in static method of B"); } } public class Test { public static void main(String[] args){ B obj =new B(); obj.show(); A a_obj=new B(); a_obj.display(); } } 

在第一种情况下,o / p是“在B的静态方法”#成功覆盖第二种情况下,o / p是“在静态方法的A”#静态方法 – 不会考虑多态

静态成员是普遍成员。 他们可以从任何地方访问。

静态成员将不会被inheritance到子类,因为inheritance只适用于非静态成员。静态成员将通过类加载器加载到静态池中。 inheritance仅适用于在对象中加载的成员

我们可以在子类中声明具有相同签名的静态方法,但不会被认为是重写的,因为不会有任何运行时多态性。因为一个类的所有静态成员都是在类加载时加载的,所以它决定在编译时间(在运行时覆盖)因此答案是“否”。