是否在Java中继承了静态方法?

问题

我正在阅读Khalid Mughal的程序员Java™SCJP认证指南。

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

成员的继承与其声明的可访问性密切相关。如果超类成员可以通过其子类中的简单名称访问(不使用任何额外的语法,如super),则该成员被视为继承

它还提到静态方法不是继承的。但是下面的代码非常好:

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();
    }
}

我怎么能直接使用display()在classB?甚至更多,B.display()也有效。

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


#1 热门回答(148 赞)

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

来自Sun JavaTutorials

子类继承其父级的所有公共成员和受保护成员,无论子类在哪个包中。如果子类与其父类在同一个包中,它还继承父类的包私有成员。你可以按原样使用继承的成员,替换它们,隐藏它们,或用新成员补充它们

与继承的静态(类)方法和继承的非静态(实例)方法的唯一区别在于,当你使用相同的签名编写新的静态方法时,旧的静态方法只是隐藏,而不是被覆盖。

从最重要和隐藏的区别来看.page

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


#2 热门回答(10 赞)

如果这就是这本书的真实含义,那就错了。[1]

TheJava Language Specification #8.4.8states:

8.4.8继承,覆盖和隐藏类C从其直接超类继承超类的所有具体方法m(静态和实例),以下所有条件都为真:m是C的直接超类的成员.m是公共的,受保护的,或者在与C相同的包中声明包访问。在C中声明的方法的签名是m的签名的子签名(第8.4.2节)。

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


#3 热门回答(8 赞)

你可以体验以下代码中的差异,这稍微修改了你的代码。

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()将调用各自类的方法。