[java] 정적 메소드는 Java로 상속됩니까?

Khalid Mughal의 Java ™ SCJP 인증대한 프로그래머 안내서를 읽고있었습니다 .

상속 장에서는 다음과 같이 설명합니다.

회원의 상속은 선언 된 접근성과 밀접한 관련이 있습니다. 서브 클래스에서 단순한 이름으로 슈퍼 클래스 멤버에 액세스 할 수있는 경우 (슈퍼와 같은 추가 구문을 사용하지 않고) 해당 멤버는 상속 된 것으로 간주됩니다.

또한 정적 메소드가 상속되지 않는다고 언급합니다. 그러나 아래 코드는 완벽하게 좋습니다.

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()수업 시간에 B어떻게 직접 사용할 수 있습니까? 더, B.display()또한 작동합니다.

이 책의 설명은 인스턴스 메소드에만 적용됩니까?



답변

액세스 가능한 모든 메소드는 서브 클래스에 의해 상속됩니다.

Sun Java 자습서에서 :

서브 클래스는 서브 클래스에있는 패키지에 상관없이 부모의 모든 공용 및 보호 멤버를 상속받습니다. 서브 클래스가 부모와 동일한 패키지에있는 경우 서브 클래스는 또한 부모의 패키지 개인 멤버도 상속합니다. 상속 된 멤버를 그대로 사용하거나 바꾸거나 숨기거나 새 멤버로 보충 할 수 있습니다

상속 된 정적 (클래스) 메소드와 상속 된 비 정적 (인스턴스) 메소드와의 유일한 차이점은 동일한 서명으로 새 정적 메소드를 작성할 때 기존 정적 메소드가 대체되지 않고 숨겨져 있다는 것입니다.

재정의와 숨기기의 차이점에 대한 페이지 에서.

숨기기와 재정의의 차이점은 중요한 의미를 갖습니다. 호출 된 대체 메소드의 버전은 서브 클래스의 버전입니다. 호출되는 숨겨진 메소드의 버전은 수퍼 클래스 또는 서브 클래스에서 호출되는지 여부에 따라 다릅니다.


답변

그것이 그 책이 실제로 말하는 것이라면, 그것은 잘못된 것입니다. [1]

Java 언어 사양 # 8.4.8 상태 :

8.4.8 상속, 재정의 및 숨기기

클래스 C는 직접 수퍼 클래스로부터 다음의 모든 것이 참인 수퍼 클래스의 모든 구체적인 메소드 m (정적 및 인스턴스)을 상속합니다.

  • m은 C의 직접 수퍼 클래스의 멤버입니다.

  • m은 C와 동일한 패키지에서 패키지 액세스로 공개, 보호 또는 선언됩니다.

  • C로 선언 된 메소드에는 m의 서명에 대한 하위 서명 (§8.4.2) 인 서명이 없습니다.

[1] 2000 년 제 1 판에는 해당되지 않습니다.


답변

다음 코드의 차이를 경험할 수 있으며 이는 코드를 약간 수정 한 것입니다.

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

이것은 정적 메소드가 클래스 메소드이기 때문입니다.

A.display () 및 B.display ()는 해당 클래스의 메서드를 호출합니다.


답변

정적 선언은 메소드 / 멤버가 특정 클래스 인스턴스 (일명 Object)가 아닌 클래스에 속하기 때문에 B.display ()가 작동합니다. 자세한 내용은 여기를 참조 하십시오 .

주목해야 할 또 다른 사항은 정적 메서드를 재정의 할 수 없으며 하위 클래스가 동일한 서명으로 정적 메서드를 선언하도록 할 수 있지만 그 동작은 예상과 다를 수 있습니다. 이것이 아마도 상속 된 것으로 간주되지 않는 이유 일 것입니다. 여기서 문제가되는 시나리오와 설명을 확인할 수 있습니다 .


답변

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

당신은 다음을 얻을 것이다 :

Writing
Writing
Writing
Writing book


답변

정적 메소드는 Java로 상속되지만 다형성에는 참여하지 않습니다. 정적 메서드를 재정의하려고 시도하면 슈퍼 클래스 정적 메서드를 재정의하는 대신 숨길 수 있습니다.


답변

이 개념은보기에는 쉽지 않습니다. 상속없이 정적 멤버에 액세스 할 수 있습니다. 이는 HasA 관계입니다. 부모 클래스도 확장하여 정적 멤버에 액세스 할 수 있습니다. 그렇다고 ISA 관계 (상속)라는 의미는 아닙니다. 실제로 정적 멤버는 클래스에 속하며 static은 액세스 수정자가 아닙니다. 액세스 수정자가 정적 멤버에 대한 액세스를 허용하는 한 다른 클래스에서 사용할 수 있습니다. 공개 된 것처럼 동일한 패키지 내부 및 패키지 외부에서 액세스 할 수 있습니다. 개인을 위해 우리는 그것을 어디서나 사용할 수 없습니다. 기본적으로 패키지 내에서만 사용할 수 있습니다. 그러나 보호를 위해 수퍼 클래스를 확장해야합니다. 따라서 정적 메소드를 다른 클래스로 가져 오는 것은 정적 인 것에 의존하지 않습니다. 액세스 수정 자에 따라 다릅니다. 제 생각에는 액세스 수정자가 허용하면 정적 멤버에 액세스 할 수 있습니다. 그렇지 않으면 Hasa-relation에서 사용하는 것처럼 사용할 수 있습니다. 그리고 관계는 상속이 아닙니다. 다시 정적 메서드를 재정의 할 수 없습니다. 우리가 다른 방법을 사용할 수는 있지만 무시할 수 없다면 HasA- 관계입니다. 우리가 그것들을 무시할 수 없다면 그것은 상속이 아니기 때문에 작가는 100 % 정확했습니다.