我在这个网站上做了一些搜索,以避免重复,但大多数问题都是关于接口和抽象类之间的抽象比较。
我的问题更多是针对我的具体情况,特别是我的同事,我不同意同样的方法。
我有3个班级
我们使用复合模式获取所有文件夹及其每个用户/组的权限
类Node
,它应该是接口还是Abstract类?
Folder
和File
继承自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
}
}
答案 0 :(得分:6)
这里没有正确答案。这真的归结为这个问题
“Node
File
和Folder
共有 实施 吗?”
如果答案是是,那么需要一个抽象类,可选择使用描述其行为的接口
如果答案是否,那么您可以将其设为接口,可选择使用抽象基础实现。
所以你看 - 它的方式基本相同。
此外,没有什么可以阻止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
,而如果它是一个接口呢?
如果您拥有所有孩子共享的通用功能,通常会选择创建一个抽象类。在这种情况下,这个通用功能将由抽象基类实现,因此不必在所有子类中实现。
在许多情况下,你甚至同时拥有:
答案 2 :(得分:1)
从你说的话......
Node是一个接口还是类,如果它有方法&#34; AddFolder&#34;在它上面,文件无法实现,然后你就会遇到设计问题。
问题是,Node不够抽象,你需要将其缩小到公共接口。
答案 3 :(得分:1)
你为什么Node应该是abstractis的论点,因为File不应该和Folder有相同的方法。为什么使节点成为接口意味着它们将具有相同的方法? INode可以是文件和文件夹都实现的标记接口。如果文件夹有一组不同的操作(它可以这样做),那么我将为该IFolder设置另一个接口,并定义这些操作。
从简短的问题我个人会在这种场景中使用接口,因为通过使用继承,很容易在Node上定义一些文件将继承哪些不属于文件。
答案 4 :(得分:1)
我通常使用这条规则:
如果两个类有一些常用方法,但它们的实现方式不同,请使用接口。
如果两个类有一些共同的方法,并且它们共享一些常见的实现,则使用抽象类作为基类。