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

Alg*_*ist 134 java inheritance static

我正在阅读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();
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么能display()在课堂上直接使用B?更重要的是,B.display()也有效.

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

yin*_*ash 173

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

来自Sun Java 教程:

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

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

页面上覆盖和隐藏的区别.

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

  • @Algorithmist不完全没有.你的子类在层次结构中进一步看到的所有东西都是你的类继承的东西.但是,继承的静态方法不能被覆盖,只能隐藏(使用相同的签名"重新声明").因此,您也可以将静态方法声明为final,这无关紧要.将在编译时知道将调用哪个静态方法.使用非final实例方法时,必须将解析延迟到运行时,因为它们可能会被覆盖. (2认同)
  • 你的最后一段完全被破坏了!“被调用的重写方法的版本是子类中的版本”,这是不正确的:比方说:被调用的重写方法的版本仅在运行时由与哪个对象创建了相关的 JVM 确定。称呼 :) (2认同)

use*_*421 15

如果这就是这本书的真实内容,那就错了.[1]

Java语言规范8.4.8#状态:

8.4.8继承,覆盖和隐藏

类C从其直接超类继承超类的所有具体方法m(静态和实例),以下所有条件都为真:

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

  • m是与C相同的包中的公共,受保护或声明的包访问.

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

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


小智 11

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

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();
        // prints: Inside static method of this class
        b.display();

        A a = new B();
        // prints: Inside static method of superclass
        a.display();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @ LucasC.Feijo实际上我确实可以。至少在我的IDE中(日食)。我刚刚得到警告。虽然它可能不是很好的风格……但这是另外一回事了。 (2认同)
  • 不建议在实例上使用@ LucasC.Feijo调用静态方法。但是,其作用与在类名上调用静态方法相同。 (2认同)

小智 8

Java 中的静态方法是继承的,但不能被覆盖。如果在子类中声明相同的方法,则隐藏超类方法而不是覆盖它。静态方法不是多态的。在编译时,静态方法将被静态链接。

例子:

public class Writer {
    public static void write() {
        System.out.println("Writing");
    }
}

public class Author extends Writer {
    public static void write() {
        System.out.println("Writing book");
    }
}

public class Programmer extends Writer {

    public static void write() {
        System.out.println("Writing code");
    }

    public static void main(String[] args) {
        Writer w = new Programmer();
        w.write();

        Writer secondWriter = new Author();
        secondWriter.write();

        Writer thirdWriter = null;
        thirdWriter.write();

        Author firstAuthor = new Author();
        firstAuthor.write();
    }
}
Run Code Online (Sandbox Code Playgroud)

您将获得以下信息:

Writing
Writing
Writing
Writing book
Run Code Online (Sandbox Code Playgroud)


Kai*_*Kai 5

B.display()有效,因为静态声明使方法/成员属于类,而不是任何特定的类实例(又称Object).你可以在这里阅读更多相关信息.

另外需要注意的是,您不能覆盖静态方法,您可以让子类声明具有相同签名的静态方法,但其行为可能与您期望的不同.这可能是它不被认为是遗传的原因.您可以在此处查看有问题的方案和解释.