简体   繁体   中英

Interface vs. Abstract class (in specific case)

I have done some search on this website to avoid duplication, however most of the questions were about an abstract comparison between interface and abstract class.

My question is more to my specific situation especially my colleague and I we don't agree about the same approach.

I have 3 classes

  1. Node (Abstract node in a folder structure)
  2. Folder (Contains sub folders and files)
  3. File

We use the composite pattern to get all folders and their permissions per user/group

The class Node , should it be interface or Abstract class? Folder and File inherit from Node.

In my opinion i think Node should be an abstract because File should not have all methods that Folder has for example AddFolder(Node node)

My colleague said that it's better to use interface for better coding.

Edit: I rewrote my Node as follow:

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
    }
}

There is no right answer here. It really boils down to this question

"Does Node have any implementation that is common to File and Folder ?"

If the answer is yes , then need an Abstract class, optionally with an Interface which describes its behaviour

If the Answer is no , then you could make it an Interface, optionally with an Abstract base implementation.

So you see - its basically the same either way.


Besides, there is nothing stopping Folder adding additional methods not defined on Node which File would not share.

eg,

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!
    }
}

Your reasoning for rejecting the interface seems off. Why would File have a method AddFolder if Node were an abstract class but not if it were an interface?

You normally choose to create an abstract class if you have common functionality that all children share. In this case, this common functionality will be implemented by the abstract base class so it doesn't have to be implemented in all children.

In many cases, you even have both:

  1. An interface that describes the contract
  2. An abstract class that implements the interface and some common functionality

From what you are saying....

Whether Node is an interface or class, if it has the method "AddFolder" on it, and File can't implement that, then you have problem with the design.

The problem is, Node isn't abstract enough, you need to narrow it down to the common interface.

Your argument for why Node should be abstractis because File should not have the same methods as Folder. Why does making node an interface imply they will have the same methods? INode could be a marker interface that File and Folder both implement. If folder has a distinct set of operations (which it proberly does) then I would have another interface for that IFolder with those operations defined.

From the short question I would personally use interfaces in this scenario as by using inheritance it's very easy for something to be defined on Node that File will inherit which does not belong on a file.

I normally use this rule:

If two classes have some common methods but their implementation is different use an interface.

If two classes have some common methods and they share some common implementation use an abstract class as a base class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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