接口与抽象类(在特定情况下)

时间:2013-02-07 08:45:22

标签: c# .net

我在这个网站上做了一些搜索,以避免重复,但大多数问题都是关于接口和抽象类之间的抽象比较。

我的问题更多是针对我的具体情况,特别是我的同事,我不同意同样的方法。

我有3个班级

  1. 节点(文件夹结构中的抽象节点)
  2. 文件夹(包含子文件夹和文件)
  3. 文件
  4. 我们使用复合模式获取所有文件夹及其每个用户/组的权限

    Node,它应该是接口还是Abstract类? FolderFile继承自Node。

    在我看来,我认为Node应该是摘要,因为File不应该包含Folder所有的所有方法,例如AddFolder(Node node)

    我的同事说最好使用界面进行更好的编码。

    编辑:  我重写了我的节点如下:

    public abstract class Node 
    {
        public string Name { get; set; }
        public string FullName { get; set; }
        public Node Parent { get; set; }
    
        public List<PermissionEntry> Permissions { get; set; }
    
        protected Node(string fullName)
        {
            FullName = fullName;
            Permissions = new List<PermissionEntry>();
        }
    
        public void AssignPermission()
        {
           // some Codes
        }
    }
    

5 个答案:

答案 0 :(得分:6)

这里没有正确答案。这真的归结为这个问题

Node FileFolder共有 实施 吗?”

如果答案是,那么需要一个抽象类,可选择使用描述其行为的接口

如果答案是,那么您可以将其设为接口,可选择使用抽象基础实现。

所以你看 - 它的方式基本相同。


此外,没有什么可以阻止Folder添加Node File无法分享的其他方法。

例如

public interface INode
{
   void SomethingCommon();
}

public File: INode
{
    public void SomethingCommon(){...}  // I must implement this   
}

public Folder : INode
{
    public void SomethingCommon(){...}  // I must implement this   
    public void AddFolder(string name)
    {
        // File doesnt need this method, its not on the interface!
    }
}

答案 1 :(得分:5)

你拒绝接口的理由似乎没有了。如果File是一个抽象类,为什么AddFolder会有一个方法Node,而如果它是一个接口呢?

如果您拥有所有孩子共享的通用功能,通常会选择创建一个抽象类。在这种情况下,这个通用功能将由抽象基类实现,因此不必在所有子类中实现。

在许多情况下,你甚至同时拥有:

  1. 描述合同的界面
  2. 实现接口和一些常用功能的抽象类

答案 2 :(得分:1)

从你说的话......

Node是一个接口还是类,如果它有方法&#34; AddFolder&#34;在它上面,文件无法实现,然后你就会遇到设计问题。

问题是,Node不够抽象,你需要将其缩小到公共接口。

答案 3 :(得分:1)

你为什么Node应该是abstractis的论点,因为File不应该和Folder有相同的方法。为什么使节点成为接口意味着它们将具有相同的方法? INode可以是文件和文件夹都实现的标记接口。如果文件夹有一组不同的操作(它可以这样做),那么我将为该IFolder设置另一个接口,并定义这些操作。

从简短的问题我个人会在这种场景中使用接口,因为通过使用继承,很容易在Node上定义一些文件将继承哪些不属于文件。

答案 4 :(得分:1)

我通常使用这条规则:

如果两个类有一些常用方法,但它们的实现方式不同,请使用接口。

如果两个类有一些共同的方法,并且它们共享一些常见的实现,则使用抽象类作为基类。