繁体   English   中英

没有抽象类的实现接口?

[英]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类,还是有任何或技巧和方法?

如果需要在接口中公开AttachDetach方法,总有一种方法可以绕过预期的实现,因为实现接口的所有对象都可以按照自己的样式实现它们。

您可以让抽象类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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM