1

おそらく非常に基本的な Java の質問です。

私はそれを単純化する抽象クラスを持っています:

public abstract class A{
  private String value = "A" ; // I want it undeclared, but set it for testing purpouse

  public String getValue(){
    return value ;
  }
}

次に、それを拡張するクラスがあります。

public abstract class B{
  private String value = "B" ;
}

したがって、私が抱えている問題は、クラス A を介して B のインスタンスを作成し、getValue() を呼び出すと、常に「A」が返されることです。

A b = new B();
b.getValue(); // returns "A"

コードを複製することなく、自分のプロパティを使用してスーパーメソッドを呼び出す B を取得するにはどうすればよいですか? 現在は長すぎます。プロパティ値のみが異なる多くの異なるクラスに拡張され、それらはすべてスーパークラスと同じメソッドを使用します。

ありがとう!

編集:

申し訳ありませんが、私はそれほど具体的ではありませんでした。私は多くのプロパティと、それらのプロパティを処理するいくつかのメソッドを持っています。拡張クラスはこれらのプロパティを変更しますが、それらを 2 回宣言することなく、拡張クラスのインスタンス化されたオブジェクトでスーパー メソッドを使用したいと考えています。それが役立つ場合は、サーブレットのコンテキスト属性を使用しています。

Config.java

public abstract class Config {
    private String someValue1 ;
    ...
    private String someValuen ;

    public void export(ServletContext cxt){
        cxt.setAttribute("someValue1", someValue1);
        ...
        cxt.setAttribute("someValuen", someValuen);
    }
}

SomeConfig.java

public class SomeConfig {
    private String someValue1 = "something" ;
    ...
    private String someValuen = "something else" ;
}

SomeServlet.java

ServletContext cxt = getServletContext() ;
Config config = new SomeConfig();
config.export(cxt);

明確にするために、プロパティはすべて異なる名前を持っています。私はjspからそれらを次のように使用します: ${someValuen}

4

3 に答える 3

5

機能しない理由は、メソッドのみをオーバーライドできるためです-代わりに変数メンバーが非表示になっvalueています(Bクラスから印刷すると、"B".

その特定の例では、専用のコンストラクターを使用します (クライアント クラスがアクセスできないように保護しました)。

public abstract class A {
    private final String value;

    public A() { //for internal / testing use only
        value = "A";
    }

    protected A(String value) {
        this.value = value;
    }

    public String getValue(){
        return value ;
    }
}

次に、B は関連するコンストラクターを呼び出すだけです。

public class B extends A {
    public B() {
        super("B");
    }
}

編集

の例ConfigHolder:

public class ConfigHolder {

    String value1;
    String value2;
    String value3;

    public ConfigHolder value1(String value1) {
        this.value1 = value1;
        return this;
    }
    //same for other variables
}

次に、クラス A で:

public abstract class A {
    private final ConfigHolder config;

    public A() { 
        this.config = new ConfigHolder()
                 .value1("value1")
                 .value2("value2");
    }

    protected A(ConfigHolder config) { 
        this.config = config;
    }

    public void export(ServletContext cxt){
        cxt.setAttribute("someValue1", builder.value1);
        ...
        cxt.setAttribute("someValuen", builder.valuen);
    }
}

そしてBで:

public class B extends A {
    public B() {
        super(new ConfigBuilder()
                   .value1("value1InB")
                   .value2("value2InB"));
    }
}
于 2013-01-14T11:34:40.773 に答える
0

これを行うには: A b = new B();B は A のサブクラスでなければなりません

また、抽象クラスはインスタンス化できません。つまり、抽象クラス オブジェクトを作成できません。しようとすると、コンパイラはエラーを生成します。

public abstract class A{
  private String value = "A" ;

  public String getValue(){
    return value ;
  }
}


public class B extends A{
    private String value ;
    public B(){
        value = "B";
    }
}

今、あなたはすることができますB notAbstractClass = new B();

そして、notAbstractClass.getValue();それを行うときは「B」を返さなければなりません

于 2013-01-14T12:08:58.660 に答える
0

コンストラクターを使用してスーパークラスのプロパティを保護されたものに変更する簡単な方法を見つけました(@assyliasの回答に感謝します):Config.java

public abstract class Config {
    protected String someValue1 ;
    ...
    protected String someValuen ;

    public void export(ServletContext cxt){
        cxt.setAttribute("someValue1", someValue1);
        ...
        cxt.setAttribute("someValuen", someValuen);
    }
}

SomeConfig.java

public class SomeConfig {
  public SomeConfig(){
    someValue1 = "something";
    ...
    someValuen = "something else";
  }
}
于 2013-01-14T12:21:33.803 に答える