2017-07-06 19 views
0

子クラスの関数が抽象的な親クラスのクラスであることを強制したいと思います。例:ここでは抽象クラスでの子クラス型の変数の宣言

abstract class Animal { 
    public abstract void Add(Animal animal); 
} 

class Cat: Animal { 
    public override void Add(Cat cat) { 
     //Do cat things 
    } 
} 

class Dog: Animal { 
    //This should not be allowed 
    public override void Add(Animal dog) { 
     //Do dog things 
    } 
} 

我々はCat型オブジェクトがDog.Addに渡すことができることを参照してください。関数を実行してDogとする方法はありますか?

私はそれが実行時にチェックされる方法があると信じていますが、可能であれば、コンパイラエラーが多くなるでしょう。

+2

これを行うと、子クラスは動物クラスのAddメソッドを実装しないため、これは不可能です。基本クラスで抽象メソッドを宣言する場合、このメソッドは子クラスで実装する必要があります。あなたの要件は何か、なぜこれをやりたいのかを指定できますか? –

+0

ええと、それは良い点です。私は同じクラスの他のインスタンスを取るいくつかのメソッドを持つユーザーのための抽象的な 'Effect'クラスを提供しています。しかし、ユーザーがメソッドを定義しているので、ユーザーがさまざまな種類の「エフェクト」を通過させたいというユースケースがあると思います。 –

答えて

1

を使用してインターフェイスを宣言し、ジェネリックを使用する場合は、という制約があります。

public abstract class Animal 
{ 
} 

public interface IAnimalCollection<T> where T : Animal 
{ 
    void Add<T>(T animal); 
} 

public class Cat : Animal, IAnimalCollection<Cat> 
{ 
    public void Add(Cat animal) 
    { 
    } 
} 

public class Dog : Animal, IAnimalCollection<Dog> 
{ 
    // won't compile 
    public void Add(Animal animal) 
    { 
    } 
} 

public class Ferret : IAnimalCollection<Ferret> 
{ 
    public void Add(Ferret animal) 
    { 
    } 

    public void Add(Animal animal) 
    { 
    } 
} 

// won't compile 
public class Foo : IAnimalCollection<Foo> 
{ 
    public void Add(Foo animal) 
    { 
    } 
} 
+0

問題は、 'public class Cat:Animal、IAnimalCollection 'が有効であるということです。 –

+0

おそらく、私は犬を捕まえる猫を実装したかったのです! – Jasen

+0

各エフェクトサブクラスが異なるビヘイビアを持っている場合は、それらのビヘイビアをベースクラスではなくインターフェイスにカプセル化する必要があります。 – Jasen

関連する問題