문제

나는 정적 방법으로 수정자를 가지고 놀았으며 이상한 행동을 발견했습니다.

우리가 알고 있듯이, 정적 메소드는 인스턴스가 아닌 클래스와 연관되어 있기 때문에 무시할 수 없습니다.

아래 스 니펫이 있으면 잘 컴파일합니다.

//Snippet 1 - Compiles fine
public class A {
    static void ts() {
    }
}

class B extends A {
    static void ts() {
    }
}

그러나 클래스 A에 최종 수정 자에게 정적 메소드를 포함하면 컴파일이 실패합니다.b의 ts ()는 a에서 ts ()를 무시할 수 없습니다. 재정의 메소드는 정적 최종입니다.

정적 방법을 전혀 무시할 수 없을 때 왜 이런 일이 발생합니까?

도움이 되었습니까?

해결책

정적 메소드는 무시할 수 없지만 숨길 수 있습니다. 그만큼 ts() B의 방법 ts() 그러나 그것은 그것을 숨길 것입니다. 전화하면 ts() B에서 (아님 A.ts() 또는 B.ts() ... 단지 ts()), B 중 하나는 A가 아니고 A가 아닙니다. 이것은 다형성이 없기 때문에 전화 ts() A에서는 B의 B로 다시 방향을 바꾸지 않을 것입니다.

키워드 final 이 방법이 숨겨지는 것을 비활성화합니다. 따라서 숨길 수 없으며 그렇게하려는 시도는 컴파일러 오류가 발생합니다.

도움이 되었기를 바랍니다.

다른 팁

정적 메소드는 재정의 할 수 없습니다

이것은 정확히 사실이 아닙니다. 예제 코드는 실제로 B의 메소드 TS가 A의 메소드 TS를 숨긴다는 것을 의미합니다. 위에 Javaranch 좋은 설명이 있습니다.

정적 메소드는 인스턴스가 아니라 클래스에 속합니다.

A.ts() 그리고 B.ts() 항상 별도의 방법이 될 것입니다.

실제 문제는 Java를 사용하면 인스턴스 객체에서 정적 메소드를 호출 할 수 있다는 것입니다. 부모 클래스와 동일한 서명을 가진 정적 메소드는 다음과 같습니다. 숨겨진 서브 클래스 인스턴스에서 호출 할 때. 그러나 재정의/숨길 수 없습니다 최종 방법.

오류 메시지가 재정의 대신 숨겨진 단어를 사용한다고 생각할 것입니다 ...

다음을 고려하여 정적 방법을 최종적으로 만드는 것에 대해 생각할 위치에있을 수 있습니다.

다음 수업이 있습니다.

class A {
    static void ts() {
        System.out.print("A");
    }
}
class B extends A {
    static void ts() {
        System.out.print("B");
    }
}

이제 이러한 방법을 호출하는 '올바른'방법은

A.ts();
B.ts();

그 결과 AB 그러나 인스턴스에서 방법을 호출 할 수도 있습니다.

A a = new A();
a.ts();
B b = new B();
b.ts();

그 결과 AB 또한.

이제 다음을 고려하십시오.

A a = new B();
a.ts();

인쇄 할 것입니다 A. 실제로 수업 대상을 가지고 있기 때문에 놀랄 수도 있습니다. B. 하지만 유형의 참조에서 부르기 때문에 A, 그것은 전화 할 것입니다 A.ts(). 인쇄 할 수 있습니다 B 다음 코드로 :

A a = new B();
((B)a).ts();

두 경우 모두 당신이 가진 객체는 실제로 수업에서 나옵니다. B. 그러나 객체를 가리키는 포인터에 따라 A 또는 B.

이제 당신이 클래스 개발자라고 가정 해 봅시다. A 그리고 당신은 하위 클래스를 허용하고 싶습니다. 그러나 당신은 정말로 방법을 원합니다 ts(), 서브 클래스에서도 호출 할 때마다, 그것은 당신이 원하는 것을 수행하고 서브 클래스 버전으로 숨겨져 있지 않습니다. 그러면 당신은 그것을 만들 수 있습니다 final 서브 클래스에 숨겨져있는 것을 방지하십시오. 다음 코드가 수업에서 메소드를 호출 할 것입니다. A:

B b = new B();
b.ts();

좋아, 인기 적으로 그것은 어떻게 든 건설되었지만 어떤 경우에는 의미가있을 수 있습니다.

인스턴스에서 정적 메소드를 호출해서는 안되지만 클래스에서 직접 호출해야합니다. 그러면 해당 문제가 없습니다. 예를 들어 Intellij Idea는 인스턴스에서 정적 메소드를 호출하고 정적 메소드를 최종 최종적으로 만드는 경우 경고를 표시합니다.

컴파일 오류가 여기서 오해의 소지가 있다고 생각합니다. "재정의 방법은 정적 최종입니다."라고 말하지 말아야하지만 대신 "재정의 방법은 최종입니다"라고 말해야합니다. 정적 수정자는 여기서 관련이 없습니다.

B의 TS () 메소드는 A의 TS () 메소드를 재정의하지 않으며 단순히 또 다른 방법입니다. B 클래스는 정적이므로 TS () 메소드를 A에서 보지 않으므로 TS ()라는 자체 메소드를 선언 할 수 있습니다.

그러나 메소드가 최종 인 경우 컴파일러는 A에 TS () 메소드가있어서 B에서 재정의되지 않아야합니다.

정적이 아닌 방법과 달리 정적 방법은 Java에서 무시할 수 없습니다. 그러나 그들은 정적 및 비 정적 데이터 구성원처럼 상속됩니다. 그렇기 때문에 동일한 이름을 가진 비 정적 메소드가 부모 클래스에서 생성 할 수 없습니다.

class Writer { 
    public static void doo(){
        System.out.println("sth");
    } 
}
class Author extends Writer{ 
    public void doo(){
        System.out.println("ok"); // error overridden method is static
    }
}

그만큼 final 키워드는 메소드 호출마다 특정 메소드 본문이 실행되도록합니다. 이제 동일한 이름으로 하위 클래스에서 정적 메소드가 생성되고 메소드에 대한 호출이 이루어지면 서브 클래스의 메소드가 실행됩니다. . 따라서 최종 키워드는 아동 수업에서 동일한 이름으로 메소드 생성을 제한합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top