Java에서는 부모 클래스에서 최종 멤버를 선언하고 하위 클래스에서 그 값을 설정할 수없는 이유는 무엇입니까? 어떻게해야합니까?

StackOverflow https://stackoverflow.com/questions/663512

  •  20-08-2019
  •  | 
  •  

문제

Java 프로그램에는 부모로부터 상속되는 여러 하위 클래스가 있습니다 (추상). 나는 모든 어린이에게 한 번만 설정된 회원이 있어야한다고 표현하고 싶었습니다 (제작자로부터 할 계획이었습니다). 내 계획은 S.th를 코딩하는 것이 었습니다. 이와 같이:

public abstract class Parent {
    protected final String birthmark;
}

public class Child extends Parent {
    public Child(String s) {
        this.birthmark = s;
    }
}

그러나 이것은 자바 신들을 기쁘게하지 않는 것 같습니다. 부모 수업에서 나는 다음과 같은 메시지를받습니다. birthmark "초기화되지 않았을 수도 있습니다", 어린이 수업에서 나는 "최종 필드를 얻는다" birthmark 액세스 할 수 없습니다 ".

그래서 이것의 자바 방식은 무엇입니까? 내가 무엇을 놓치고 있습니까?

도움이 되었습니까?

해결책

부모 클래스를 비교하는 동안 컴파일러는 서브 클래스가 초기화 될 것이라고 확신 할 수 없기 때문에 할 수 없습니다. 부모의 생성자에서 초기화하고 자녀가 부모의 생성자에게 전화하도록해야합니다.

public abstract class Parent {
    protected final String birthmark;
    protected Parent(String s) {
        birthmark = s;
    }
}

public class Child extends Parent {
    public Child(String s) {
        super(s);
        ...
    }
}

다른 팁

부모 생성자에게 전달하십시오.

public abstract class Parent {
    private final String birthmark;
    public Parent(String s) {
        birthmark = s;
    }
}

public class Child extends Parent {
    public Child(String s) {
        super(s);
    }
}

이 작업을 수행하는 또 다른 Java-ish 방법은 아마도 상위 클래스가 추상적 인 "getter"를 정의하고 아이들이 그것을 구현하도록하는 것입니다. 이 경우에는 그렇게하는 좋은 방법은 아니지만 경우에 따라 정확히 원하는 것이 될 수 있습니다.

나는 이것처럼 할 것이다 :

public abstract class Parent 
{
    protected final String birthmark;

    protected Parent(final String mark)
    {
        // only if this makes sense.
        if(mark == null)
        {
            throw new IllegalArgumentException("mark cannot be null");
        }

        birthmark = mark;
    }
}

public class Child 
    extends Parent 
{
    public Child(final String s) 
    {
        super(s);
    }
}

최종은 변수를 인스턴스 당 한 번 초기화 할 수 있음을 의미합니다. 컴파일러는 모든 서브 클래스가 모반에 할당을 제공하여 부모 클래스의 생성자에서 할당이 발생하도록 할 수 없습니다.

나는 당신이 각 cosntructor가 아닌 한 곳에서 인수를 확인할 수 있다는 이점을 얻을 수 있음을 보여주기 위해 NULL 검사를 추가했습니다.

초기화를 메소드로 위임하지 않는 이유는 무엇입니까? 그런 다음 부모 클래스에서 메소드를 무시하십시오.

public class Parent {
   public final Object x = getValueOfX();
   public Object getValueOfX() {
      return y;
   }
}
public class Child {
  @Override
  public Object getValueOfX() {
     // whatever ...
  }
}

이를 통해 사용자 정의 초기화를 허용해야합니다.

그렇습니다. 최종 회원은 선언 된 수업에 배정됩니다. 부모에게 문자열 인수가있는 생성자를 추가해야합니다.

서브 클래스에서 호출되는 슈퍼 클래스에서 생성자를 선언하십시오. 필드를 슈퍼 클래스로 설정하여 초기화되었는지 확인하거나 컴파일러가 필드가 초기화되어 있는지 확인할 수 없습니다.

부모 클래스에서 최종 최종이 항상 초기화되도록 부모 (String Bympark) 생성자를 갖기를 원할 것입니다. 그런 다음 자녀 () 생성자로부터 Super (Borthmark)를 호출 할 수 있습니다.

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