[英]Returning derived class instance from a base class
標題可能不清楚,但請看下面的模式
public abstract class Animal
{
public abstract Dog GetDog { get; }
public abstract Cat GetCat { get; }
}
public class Dog : Animal
{
public override Dog GetDog {
get { return this; }
}
public override Cat GetCat {
get { return null; }
}
}
這被認為是在基類中具有屬性,返回派生類型的不良做法。 或者我應該做些什么
public abstract AnimalTypeEnum AnimalType { get; }
編輯:根據評論,我想我應該更清楚我想要實現的目標。 Dog
或Cat
類的新實例將由基於特定條件的單獨函數創建,然后將Animal
類型返回給調用者。 調用方法將檢查返回實例的類型並相應地使用它。
public Animal CreateAnimal(string path)
{
//Process the document in path and create either a new instance of dog or cat
Dog dg = new Dog();
return dg;
}
如果你只想要你從中獲得的動物可以這樣做:
public abstract class Animal<T> where T: Animal<T>
{
public T GetAnimal
{
get { return (T)this; }
}
}
public class Dog : Animal<Dog>
{
}
public class Cat : Animal<Cat>
{
}
public class Giraffe : Animal<Giraffe>
{
}
你這樣稱呼:
var cat = new Cat();
var dog = new Dog();
var giraffe = new Giraffe();
Cat cat2 = cat.GetAnimal;
Dog dog2 = dog.GetAnimal;
Giraffe giraffe2 = giraffe.GetAnimal;
調用方法將檢查返回實例的類型並相應地使用它。
這是你的問題。 這需要代碼氣味。 你應該能夠把它只是一個對象,而不是以不同的方式對待狗和貓。
如果你需要顯示任何一個動物的內容,那么在兩個類上重寫ToString
方法,只需在動物上調用ToString
。 如果您需要知道狗或貓的名字,那么將一個Name
屬性添加到Animal
。 如果你可能的話,你應該在這里使用多態,這樣無論使用什么對象,它都只是一個Animal
並且只是涉及由於同一方法的不同實現而發生的不同事情。
如果你真的,確實需要知道Animal
是Dog
還是Cat
那么你可以使用is
或as
運算符; 您不需要添加您在OP中顯示的所有代碼。
不,你做錯了。
更好的方法是使用單一方法。
public abstract Animal getAnimal();
任何派生類都將知道如何返回自己。 我希望這是有道理的。 但是我不認為你會想要歸還動物。 沒有意義。
Animal dog = new Dog() ;
dog.getAnimal();
混淆吧?
你可以有一個動物/列表數組,遍歷集合並檢查如下:
if(animal is Dog)
但你還在檢查類型。 如果你想使用一個基類讓它有意義並暴露一個常見的方法。
這是一個真正的基礎設計,因為它違反了開放封閉原則 。 您希望您的類可以打開以進行擴展,但不能修改。 如果明天你想要添加另一個課程,會發生什么?
public class Donkey : Animal
{
}
您將不得不去更改基類,因此它將具有GetDonkey
屬性。 您還必須更改所有使用您的類的類並添加if (animal.GetDonkey == null)
你應該做的是使用這樣的工廠設計模式:
public static class AnimalFactory
{
public static Dog GetDog()
{
return new Dog();
}
public static Cat GetCat()
{
return new Cat();
}
}
或者你應該使用@Lews Therin建議的虛擬方法。
擁有只返回被調用對象的屬性似乎沒有用。
也許你只是在尋找一種從超類轉向子類的方法? 如果是這樣,只需使用強制轉換:
Animal a = new Cat();
try
{
Dog d = (Dog)a;
}
catch (InvalidCastException)
{
try
{
Cat c = (Cat)a;
}
catch (InvalidCastException)
{
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.