Java에서는 부모 클래스에서 최종 멤버를 선언하고 하위 클래스에서 그 값을 설정할 수없는 이유는 무엇입니까? 어떻게해야합니까?
문제
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)를 호출 할 수 있습니다.