5

多重継承を許可しない言語で次のシナリオを処理する方法について、理論的な質問があります。

基本クラスFooがあり、そこから 3 つのサブクラスを作成したいとします。

  • Class BarはFooを継承し、機能「A」を実装します
  • クラスBazはFooを継承し、機能「B」を実装します
  • クラスQux はFooを継承し、機能 "A" と "B" を実装します

機能「A」と「B」を実装するコードが常に同じであると想像してください。「A」と「B」のコードを一度だけ記述してから、適切なクラスに適用 (または「継承」) させる方法はありますか?

4

4 に答える 4

3

これのより一般的な用語はMixinです。ScalaやDなど、すぐに使用できるサポートを提供する言語もあります。ただし、他の言語でも同じ結果を得るにはさまざまな方法があります。

C#で疑似ミックスインを作成する1つの方法は、空のインターフェイスを使用し、メソッドに拡張メソッドを提供することです。

interface A { }
static class AMixin {
    public static void aFunc(this A inst) {
        ... //implementation to work for all A.
    }
}

interface B { }
static class BMixin {
    public static void bFunc(this B inst) {
        ...
    }
}

class Qux : Foo, A, B {
    ...
}
于 2012-05-27T14:02:26.757 に答える
3

C#/Java でこれを達成する唯一の方法は、コンポジションによるものです。このことを考慮:

class Foo {

}

interface A {
    public void a();
}

interface B {
    public void b();
}

class ImplA implements A {
    @Override
    public void a() {
        System.out.println("a");
    }
}

class ImplB implements B {
    @Override
    public void b() {
        System.out.println("b");
    }
}

class Bar extends Foo {
    A a = new ImplA();

    public void a() {
        a.a();
    }
}

class Baz extends Foo {
    B b = new ImplB();

    public void b() {
        b.b();
    }       
}

class Qux extends Foo {

    A a = new ImplA();
    B b = new ImplB();

    public void b() {
        b.b();
    }

    public void a() {
        a.a();          
    }       
}

現在、通常の継承によるQux機能だけでなく、合成による実装も備えています。FooAB

于 2012-05-27T13:07:28.497 に答える
1

このようなことを行うにはいくつかの方法があります。より具体的には、継承の側面を一時的に放棄した場合、ユニットを1回だけ記述しながら、同じ機能ユニットを異なるクラスに導入する方法があります。

さて、私はAOPフレームワークが大好き で、多くの言語に存在します(C#とJavaにはいくつかあります)。AOPフレームワークでは、基本的に、継承構造全体のさまざまなクラスに自己完結型の機能を追加できます。

C#の場合はPostSharpがあり、Javaの場合はAspectJがあります。

多くのAOPフレームワークでは、継承を使用せずに「ハイジャック」または「オーバーライド」メソッド呼び出しを許可しています。

于 2012-05-27T14:20:23.057 に答える
1

これは、トレイトを提供する言語で実現できます (ここでは ):

class Foo {
    def fooM() {}
}

trait A {
    def aFunc() {}
}

trait B {
    def bFunc() {}
}

class Bar extends Foo with A {}

class Baz extends Foo with B {}

class Qux extends Foo with A with B {}

Scala は Java の上で実行されるため (多重継承もトレイトもありません)、次のように (簡略化して) 変換されます。Java/C# で手動で実装する方法のヒントになるかもしれません。

class Foo {
}

interface A {
    void aFunc();
}

interface B {
    void bFunc();
}

class Bar extends Foo implements A {

    public void aFunc() {
        $A.aFunc();
    }
}

class Baz extends Foo implements B {

    public void bFunc() {
        $B.bFunc();
    }
}

class Qux extends Foo implements A, B {

    public void aFunc() {
        $A.aFunc();
    }

    public void bFunc() {
        $B.bFunc();
    }
}

class $A {

    public static void aFunc() {}
}

class $B {

    public static void bFunc() {}
}
于 2012-05-27T13:03:03.693 に答える