标题可能不清楚,但请查看下面的模式
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)
{
}
}