6

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

我的问题更多是针对我的具体情况,尤其是我的同事和我,我们不同意相同的方法。

我有 3 节课

  1. 节点(文件夹结构中的抽象节点)
  2. 文件夹(包含子文件夹和文件)
  3. 文件

我们使用复合模式来获取每个用户/组的所有文件夹及其权限

Node,应该是接口还是抽象类? FolderFile从节点继承。

在我看来,我认为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
    }
}
4

5 回答 5

6

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

“是否Node有任何与和通用的实现?”FileFolder

如果答案是肯定的,那么需要一个抽象类,可选地带有一个描述其行为的接口

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

所以你看 - 这两种方式基本相同。


此外,没有什么可以阻止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!
    }
}
于 2013-02-07T08:49:33.467 回答
5

您拒绝该界面的理由似乎不对。如果是抽象类为什么File会有方法,但如果它是接口则没有?AddFolderNode

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

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

  1. 描述合约的接口
  2. 实现接口和一些常用功能的抽象类
于 2013-02-07T08:49:13.390 回答
1

从你说的......

无论Node是接口还是类,如果它上面有“AddFolder”方法,而File不能实现,那么你的设计就有问题。

问题是,Node 不够抽象,你需要把它缩小到通用接口。

于 2013-02-07T08:49:42.513 回答
1

您关于为什么 Node 应该是抽象的论点是因为 File 不应该具有与 Folder 相同的方法。为什么使节点成为接口意味着它们将具有相同的方法?INode 可以是 File 和 Folder 都实现的标记接口。如果文件夹具有一组不同的操作(它会自动执行),那么我将为该 IFolder 提供另一个接口,其中定义了这些操作。

从简短的问题来看,我会在这种情况下亲自使用接口,因为通过使用继承,很容易在 Node 上定义 File 将继承的不属于文件的东西。

于 2013-02-07T08:53:18.463 回答
1

我通常使用这个规则:

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

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

于 2013-02-07T08:58:57.313 回答