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