정적 메소드는 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 ()가 작동합니다. 자세한 내용은 여기를 참조 하십시오 .
주목해야 할 또 다른 사항은 정적 메서드를 재정의 할 수 없으며 하위 클래스가 동일한 서명으로 정적 메서드를 선언하도록 할 수 있지만 그 동작은 예상과 다를 수 있습니다. 이것이 아마도 상속 된 것으로 간주되지 않는 이유 일 것입니다. 여기서 문제가되는 시나리오와 설명을 확인할 수 있습니다 .
이 개념은보기에는 쉽지 않습니다. 상속없이 정적 멤버에 액세스 할 수 있습니다. 이는 HasA 관계입니다. 부모 클래스도 확장하여 정적 멤버에 액세스 할 수 있습니다. 그렇다고 ISA 관계 (상속)라는 의미는 아닙니다. 실제로 정적 멤버는 클래스에 속하며 static은 액세스 수정자가 아닙니다. 액세스 수정자가 정적 멤버에 대한 액세스를 허용하는 한 다른 클래스에서 사용할 수 있습니다. 공개 된 것처럼 동일한 패키지 내부 및 패키지 외부에서 액세스 할 수 있습니다. 개인을 위해 우리는 그것을 어디서나 사용할 수 없습니다. 기본적으로 패키지 내에서만 사용할 수 있습니다. 그러나 보호를 위해 수퍼 클래스를 확장해야합니다. 따라서 정적 메소드를 다른 클래스로 가져 오는 것은 정적 인 것에 의존하지 않습니다. 액세스 수정 자에 따라 다릅니다. 제 생각에는 액세스 수정자가 허용하면 정적 멤버에 액세스 할 수 있습니다. 그렇지 않으면 Hasa-relation에서 사용하는 것처럼 사용할 수 있습니다. 그리고 관계는 상속이 아닙니다. 다시 정적 메서드를 재정의 할 수 없습니다. 우리가 다른 방법을 사용할 수는 있지만 무시할 수 없다면 HasA- 관계입니다. 우리가 그것들을 무시할 수 없다면 그것은 상속이 아니기 때문에 작가는 100 % 정확했습니다.
정적 메소드는 Java로 상속되지만 다형성에는 참여하지 않습니다. 정적 메소드를 재정의하려고 시도하면 슈퍼 클래스 정적 메소드를 재정의하는 대신 숨길 수 있습니다.
정적 메소드는 서브 클래스에서 상속되지만 다형성이 아닙니다. 정적 메서드의 구현을 작성할 때 부모의 클래스 메서드는 재정의되지 않고 숨겨져 있습니다. 상속되지 않으면 어떻게 액세스하지 않고 액세스 할 수 classname.staticMethodname();
있습니까?
모든 공용 및 보호 된 멤버는 모든 클래스에서 상속 될 수 있지만 기본 또는 패키지 멤버는 수퍼 클래스와 동일한 패키지 내의 클래스에서 상속 될 수도 있습니다. 정적 멤버인지 또는 비 정적 멤버인지에 의존하지 않습니다.
그러나 정적 멤버 함수가 동적 바인딩에 참여하지 않는 것도 사실입니다. 해당 정적 메서드의 서명이 부모 클래스와 자식 클래스 모두에서 동일하면 다형성이 아닌 그림자 개념이 적용됩니다.
정적 메서드를 재정의 할 수 있지만 다형성을 사용하려고하면 클래스 범위에 따라 작동합니다 (일반적으로 예상되는 것과 달리).
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의 정적 방법에서"입니다. # 정적 방법-다형성을 고려하지 않습니다
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
We can declare static methods with same signature in subclass, but it is not considered overriding as there won’t be any run-time polymorphism.Because since all static members of a class are loaded at the time of class loading so it decide at compile time(overriding at run time) Hence the answer is ‘No’.
Many have voiced out their answer in words. This is an extended explanation in codes:
public class A {
public static void test() {
System.out.println("A");
}
public static void test2() {
System.out.println("Test");
}
}
public class B extends A {
public static void test() {
System.out.println("B");
}
}
// Called statically
A.test();
B.test();
System.out.println();
// Called statically, testing static inheritance
A.test2();
B.test2();
System.out.println();
// Called via instance object
A a = new A();
B b = new B();
a.test();
b.test();
System.out.println();
// Testing inheritance via instance call
a.test2();
b.test2();
System.out.println();
// Testing whether calling static method via instance object is dependent on compile or runtime type
((A) b).hi();
System.out.println();
// Testing whether null instance works
A nullObj = null;
nullObj.hi();
Results:
A
B
Test
Test
A
B
Test
Test
A
A
Therefore, this is the conclusion:
- When we call the static in a static manner via ., it will look for the static defined in that class, or the class nearest to that in the inheritance chain. This proves that static methods are inherited.
- When static method is called from an instance, it calls the static method defined in the compile-time type.
- Static method can be called from a
null
instance. My guess is that the compiler will use the variable type to find the class during compilation, and translate that to the appropriate static method call.
Static members are universal members. They can be accessed from anywhere.
Static members will not be inherited to subclass because inheritance is only for non-static members.. And static members will be loaded inside static pool by class loader. Inheritance is only for those members which are loaded inside the object
참고URL : https://stackoverflow.com/questions/10291949/are-static-methods-inherited-in-java
'development' 카테고리의 다른 글
Meyers의 Singleton 패턴 스레드 구현은 안전합니까? (0) | 2020.07.04 |
---|---|
rbindlist가 rbind보다“더 나은”이유는 무엇입니까? (0) | 2020.07.04 |
iOS : HTTP POST 요청을 수행하는 방법? (0) | 2020.07.04 |
http 핸들러 인터페이스에서 bool IsReusable의 중요성 (0) | 2020.07.04 |
Android 애플리케이션의 모든 버튼에 스타일을 적용하는 방법 (0) | 2020.07.04 |