Programing

추상 필드가 아닌 이유는 무엇입니까?

crosscheck 2020. 9. 2. 14:22
반응형

추상 필드가 아닌 이유는 무엇입니까?


Java 클래스는 추상 메서드를 가질 수있는 것처럼 추상 필드를 가질 수없는 이유는 무엇입니까?

예 : 동일한 추상 기본 클래스를 확장하는 두 개의 클래스가 있습니다. 이 두 클래스는 각각 오류 메시지 인 String 상수를 제외하고 동일한 메서드를 포함합니다. 필드가 추상 일 수 있다면이 상수 추상을 만들고 메서드를 기본 클래스로 끌어 올 수 있습니다. 대신 getErrMsg()이 경우 호출되는 추상 메서드를 만들어야합니다. 이 메서드는 String을 반환하고 두 파생 클래스에서이 메서드를 재정의 한 다음 메서드 (이제 추상 메서드를 호출 함)를 가져올 수 있습니다.

필드를 추상적으로 시작할 수없는 이유는 무엇입니까? Java가이를 허용하도록 설계되었을 수 있습니까?


생성자 (unested 코드)에서 초기화 된 추상 클래스의 최종 필드를 사용하여 설명한 작업을 수행 할 수 있습니다.

abstract class Base {

    final String errMsg;

    Base(String msg) {
        errMsg = msg;
    }

    abstract String doSomething();
}

class Sub extends Base {

    Sub() {
        super("Sub message");
    }

    String doSomething() {

        return errMsg + " from something";
    }
}

자식 클래스가 슈퍼 생성자를 통해 최종 초기화를 "잊는"경우 컴파일러는 추상 메서드가 구현되지 않은 것처럼 경고를 표시 합니다.


나는 그것에 대해 아무 의미가 없다. 함수를 추상 클래스로 이동하고 일부 보호 된 필드를 재정의 할 수 있습니다. 이것이 상수와 함께 작동하는지 모르겠지만 효과는 동일합니다.

public abstract class Abstract {
    protected String errorMsg = "";

    public String getErrMsg() {
        return this.errorMsg;
    }
}

public class Foo extends Abstract {
    public Foo() {
       this.errorMsg = "Foo";
    }

}

public class Bar extends Abstract {
    public Bar() {
       this.errorMsg = "Bar";
    }
}

그래서 당신의 요점은 errorMsg하위 클래스에서 구현 / 재정의 / 무엇이든 강제하고 싶다는 것입니다 . 나는 당신이 기본 클래스에 메소드를 갖고 싶어하고 그 필드를 다루는 방법을 몰랐다고 생각했습니다.


Obviously it could have been designed to allow this, but under the covers it'd still have to do dynamic dispatch, and hence a method call. Java's design (at least in the early days) was, to some extent, an attempt to be minimalist. That is, the designers tried to avoid adding new features if they could be easily simulated by other features already in the language.


Reading your title, I thought you were referring to abstract instance members; and I couldn't see much use for them. But abstract static members is another matter entirely.

I have often wished that I could declare a method like the following in Java:

public abstract class MyClass {

    public static abstract MyClass createInstance();

    // more stuff...

}

Basically, I would like to insist that concrete implementations of my parent class provide a static factory method with a specific signature. This would allow me to get a reference to a concrete class with Class.forName() and be certain that I could construct one in a convention of my choosing.


Another option is to define the field as a public (final, if you like) in the base class, and then initialize that field in the constructor of the base class, depending upon which subclass is currently being used. It's a bit shady, in that it introduces a circular dependency. But, at least it's not a dependency that can ever change -- i.e., the subclass will either exist or not exist, but the subclass's methods or fields can not influence the value of field.

public abstract class Base {
  public final int field;
  public Base() {
    if (this instanceof SubClassOne) {
      field = 1;
    } else if (this instanceof SubClassTwo) {
      field = 2;
    } else {
      // assertion, thrown exception, set to -1, whatever you want to do 
      // to trigger an error
      field = -1;
    }
  }
}

참고URL : https://stackoverflow.com/questions/2211002/why-not-abstract-fields

반응형