[英]Interface with implementation without abstract class?
我正在写一个库,我想要一个界面
public interface ISkeleton
{
IEnumerable<IBone> Bones { get; }
void Attach(IBone bone);
void Detach(IBone bone);
}
对于每个ISkeleton,Attach()和Detach()实现实际上应该是相同的。 因此,它基本上可以是:
public abstract class Skeleton
{
public IEnumerable<IBone> Bones { get { return _mBones; } }
public List<IBone> _mBones = new List<IBone>();
public void Attach(IBone bone)
{
bone.Transformation.ToLocal(this);
_mBones.add();
}
public void Detach(IBone bone)
{
bone.Transformation.ToWorld(this);
_mBones.Remove(bone);
}
}
但是C#不允许多重继承。 因此,在各种问题中,用户每次想要实现Skeleton时都必须记住从Skeleton继承。
我可以使用扩展方法
public static class Skeleton
{
public static void Attach(this ISkeleton skeleton, IBone bone)
{
bone.Transformation.ToLocal(skeleton);
skeleton.Bones.add(bone);
}
public static void Detach(this ISkeleton skeleton, IBone bone)
{
bone.Transformation.ToWorld(this);
skeleton.Bones.Remove(bone);
}
}
但后来我需要
public interface ISkeleton
{
ICollection<IBone> Bones { get; }
}
这是我不想要的,因为它不是协变的,用户可以绕过Attach()和Detach()方法。
问题:我真的必须使用抽象的Skeleton类,还是有任何或技巧和方法?
如果需要在接口中公开Attach
和Detach
方法,总有一种方法可以绕过预期的实现,因为实现接口的所有对象都可以按照自己的样式实现它们。
您可以让抽象类Skeleton
实现ISkeleton
并且所有Skeletons类都继承自Skeleton
,因此它们也实现了ISkeleton
。
public interface ISkeleton { ... }
public abstract class Skeleton : ISkeleton { ... } // implement attach and detach
public class SampleSkeleton : Skeleton { ... }
通过这种方式,您可以将SampleSkeleton
用作ISkeleton
,只要从Skeleton
继承并将方法标记为sealed
就不必覆盖它们(只要它们是实例方法),就不必实现这些函数。
在一个侧节点上:在末尾用Base
命名你的抽象类,或者以其他方式标记基类(但这肯定取决于你)。
我会使骨骼成为实现IEnumerable<T>
的特殊类型。 这样就不会违反单一责任原则。
public interface ISkeleton
{
AttachableEnumerable<IBone> Bones { get; }
}
public class AttachableEnumerable<T> : IEnumerable<T>
{
// implementation needed.
void Attach(T item);
void Detach(T item);
}
如果要包装ISkeleton
行为,可以始终将其作为复合对象而不是继承行为:
public class Body : ISkeleton
{
private SkeletonImpl _skeleton = new SkeletonImpl;
public IEnumerable<IBone> Bones { get { return _skeleton.Bones; } }
public void Attach(IBone bone)
{
_skeleton.Attach(bone);
}
public void Detach(IBone bone)
{
_skeleton.Detach(bone);
}
}
可能你只需要在抽象的Skeleton类上使用密封方法? 这样他们就无法覆盖。
http://msdn.microsoft.com/en-us/library/aa645769(v=vs.71).aspx
您可以创建一个实现“Attach”和“Detach”方法的包装类,并将此功能注入您的接口。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.