2

継承の単純な階層と単一のインターフェースがあります。クラスBによって拡張されるクラスAについて考えてみます。両方のクラスでインターフェイスIを実装し、クラスAを抽象化することを望みます。Javaでは、おおよそ次のようになります。

public interface I {
    public double foobar();
    public void print();
}

public abstract class A implements I {
    @Override public double foobar() { /*return foo*/}
    @Override public void print() {
        System.out.print(foobar());   
    }
}

public class B extends A {
    @Override public double foobar() { /*return bar*/ }
    @Override public void print() {
        super.print();
        System.out.print(foobar);
    }
}

私の意図は、タイプBのオブジェクトをインスタンス化してそのprint()を呼び出すときに、タイプBのオブジェクトに最初にクラスAのfooを出力させ、次にクラスBのbarを出力させることです。ただし、このコードを実行してコンパイルすると、どちらの場合もクラスBからfoobar()が呼び出されます。たとえば、fooが1に等しく、barが2に等しい場合、上記のコードの出力は次のようになります。

2 2

でも12にしたいです

さまざまな型キャストでメソッドを呼び出してみましたが、うまくいきませんでした。助言がありますか?

編集:多くの提案をありがとう、そして明確にするために、私はAの潜在的なサブクラスのそれぞれにIを実装してもらいたいと思います、そして私はそれを明示的に述べなかったことをお詫びします。さらに、私は現在、AのprintとAのfoobarの両方によって呼び出されるprivateFooBar()に追加のメソッドを追加することにより、動作するコードを持っています。ただし、このタスクを実行するためのより洗練された方法があるかどうかはまだ疑問です。

4

4 に答える 4

3

foobar()はクラスBでオーバーライドされます。したがって、クラスBのインスタンスで呼び出されるたびに、クラスBバージョンのメソッドが呼び出されます。それがポリモーフィズムのすべてです。

Aのfoobar()メソッドが常にAのバージョンのfoobarを返し、サブクラスのメソッドがそれを変更したくない場合は、Afoobar()で作成する必要があります。final

privateまたは、Aのメソッドに委任することもできます。

public abstract class A implements I {
    @Override 
    public double foobar() { 
        return privateFoobar();
    }

    private double privateFoobar() {
        /* return foo */
    }

    @Override public void print() {
        System.out.print(privateFoobar());   
    }
}

public class B extends A {
    @Override public double foobar() { /*return bar*/ }
    @Override public void print() {
        super.print();
        System.out.print(foobar());
    }
}
于 2013-03-10T08:28:21.650 に答える
0

クラスBとして、クラスAのfoobarメソッドをオーバーライドします。クラスBは、常にクラスBバージョンのfoobarを呼び出します。

クラスBがそのメソッドの動作を変更して、super.print()を呼び出さずにfooとbarの両方の値を出力するようにしたい場合。

クラスAのメソッドをオーバーライドする代わりに、クラスBのバーの新しいメソッドを定義します。

public class B extends A {
    public double bar() { /*return bar*/ }
    @Override public void print() {
        System.out.print(bar());
        System.out.print(foobar());
    }
}

print()メソッドを変更するときは、foobar()メソッドではなくprint()をオーバーライドするのが正しいです。

于 2013-03-10T08:59:27.743 に答える
0

クラスAでは、クラスBでオーバーライドされるfoobar()を呼び出しています。

public abstract class A implements I {
    @Override public double foobar() { /*return foo*/}
    @Override public void print() {
        System.out.print(foobar()); // HERE 
    }
}

メソッドをfinalまたはprivateにすることができます

于 2013-03-10T08:33:41.893 に答える
0

これはfoobarへのラウンドアバウトです。Bからsuper.foobar()を呼び出して、オーバーライドされたprint()メソッドを調整できます。メソッドをオーバーライドできないため、finalまたはprivateは機能しません。コードは次のとおりです。

PS:「foo」と「bar」を返すように戻りタイプをStringに変更しました:)

public class P4  {
    public static void main (String[] args) {
    new B().print();
    System.out.println();
}}

interface I {
    public String foobar();
    public void print();
}

abstract class A implements I {
    @Override public String foobar() { return "foo";}
    @Override public void print() {
        System.out.print(foobar());   
    }
}

class B extends A {
    @Override public String foobar() { return "bar"; }
    @Override public void print() {
        System.out.print(super.foobar());
        super.print();
    }
}
于 2013-03-10T08:45:55.640 に答える