我有一组来自第三方图书馆的课程。这些类使用继承结构来共享逻辑。我想在继承树的中间添加一个抽象层,以便向所有的子实现(具体的)实现添加功能。
下面是第三方库中类的简化示例:
public interface IAnimal
{
bool IsMammal { get; }
}
public abstract class Animal : IAnimal
{
public abstract bool IsMammal { get; }
public string Name { get; set; }
}
public class Cat : Animal
{
public override bool IsMammal { get { return true; } }
public void Pur() {}
}
public class Dog : Animal
{
public override bool IsMammal { get { return true; } }
public void Fetch() {}
}
public class Snake : Animal
{
public override bool IsMammal { get { return false; } }
public void ShedSkin() {}
}我想添加AnimalWithSuperPower的概念。这些类型的动物应该有一个额外的属性;SuperPower。我希望能够拥有像CatWithSuperPower这样的类,这些类派生自Cat、AnimalWithSuperPower和Animal,这样我就可以访问这些类的所有功能。
以下是SuperPower的定义:
public enum SuperPower { Invisibility, SuperStrength, XRayVision }我的第一个想法是使用多重继承。但是不幸的是,C#不支持多个基类。
private abstract class AnimalWithSuperPower : Animal
{
public SuperPower SuperPower { get; set; }
}
// doesn't compile because you can't extend 2 classes
private class DogWithSuperPower : AnimalWithSuperPower, Dog {}我的下一次尝试使用继承、组合和泛型的组合来尝试交付基类的功能。
private abstract class AnimalWithSuperPower<TAnimalType> : Animal where TAnimalType : IAnimal
{
public SuperPower SuperPower { get; set; }
protected readonly TAnimalType Animal;
protected AnimalWithSuperPower()
{
Animal = (TAnimalType) Activator.CreateInstance(typeof(TAnimalType));
}
}
private class SuperCat : AnimalWithSuperPower<Cat>
{
public override bool IsMammal { get { return Animal.IsMammal; } }
}
private class SuperCatWithPur : AnimalWithSuperPower<Cat>
{
public override bool IsMammal { get { return Animal.IsMammal; } }
public void Pur() // needing duplicate pass-through methods/properties like this is painful :(
{
Animal.Pur();
}
}
private static void ExampleUsage()
{
var invisibleCat = new SuperCat { SuperPower = SuperPower.Invisibility };
invisibleCat.Pur(); // doesn't compile - can't access Pur() method because doesn't extend Cat
var xrayCat = new SuperCatWithPur { SuperPower = SuperPower.XRayVision };
xrayCat.Pur(); // only works because I exposed the method with the EXACT same signature
}这一解决办法不是很好(海事组织),因为这些原因:
SuperCat和SuperCatWithPur实际上不是Cat的实例Cat中使用的任何方法都需要在容器类中进行镜像。AnimalWithSuperPower是一个Animal,但它也有一个Animal类型参数我也尝试过使用扩展方法来完成这个任务,但是它并没有比上面的两次尝试更好:
private abstract class AnimalWithSuperPower : Animal
{
public SuperPower SuperPower { get; set; }
}
private static AnimalWithSuperPower WithSuperPower(this Animal animal, SuperPower superPower)
{
var superAnimal = (AnimalWithSuperPower) animal;
superAnimal.SuperPower = superPower;
return superAnimal;
}
private static void ExampleUsage()
{
var dog = new Dog { Name = "Max" };
var superDog = dog.WithSuperPower(SuperPower.SuperStrength);
superDog.Fetch(); // doesn't compile - superDog isn't an instance of Dog
}如果我控制了第三方类,我很可能会在继承树的中间引入一个新类,但我做不到
我如何对AnimalWithSuperPower建模,以便:
Cat (或适当的子类)、Animal和AnimalWithSuperPower。发布于 2013-07-26 20:45:44
你为什么不直接使用接口呢?
如果您关心共享功能,可以使用扩展方法作为您的伪基类。这并不完全是理想的,但它应该得到你想要做的事情。
与…有关的东西:
public interface IAnimalWithSuperPower {
public SuperPower power { get; set; }
}
public class SuperCat : Cat, IAnimalWithSuperPower {
public SuperPower power { get; set; }
public SuperCat() {
SuperPower = SuperPower.SuperStrength;
}
}
public static void UseSuperPower(this IAnimalWithSuperPower animal) {
animal.power.doSomething();
}https://softwareengineering.stackexchange.com/questions/206205
复制相似问题