Interface or abstract class?

2019-01-03 18:07发布

For my new Pet-Project I have a question for design, that is decided already, but I want some other opinions on that too.

I have two classes (simplified):

class MyObject
{
  string name {get;set;}
  enum relation {get;set;}
  int value {get;set;}
}

class MyObjectGroup
{
  string name {get;set;}
  enum relation {get;set;}
  int value {get;set;}
  List<MyObject> myobjects {get;set;}
}

Later in the Project MyObjectGroup and MyObject should be used equally. For this I could go two ways:

  • Create an interface: IObject
  • Create an abstract class: ObjectBase

I decided to go the way of the interface, that I later in code must not write ObjectBase every time but IObject just for ease - but what are other positives for this way?

And second, what about adding IXmlSerializable to the whole story? Let the interface inherit from IXmlSerializable or does it have more positives to implement IXmlSerializable in abstract base class?

15条回答
小情绪 Triste *
2楼-- · 2019-01-03 18:44

Choosing interfaces and abstract classes is not an either/or proposition. If you need to change your design, make it an interface. However, you may have abstract classes that provide some default behavior. Abstract classes are excellent candidates inside of application frameworks.

Abstract classes let you define some behaviors; they force your subclasses to provide others. For example, if you have an application framework, an abstract class may provide default services such as event and message handling. Those services allow your application to plug in to your application framework. However, there is some application-specific functionality that only your application can perform. Such functionality might include startup and shutdown tasks, which are often application-dependent. So instead of trying to define that behavior itself, the abstract base class can declare abstract shutdown and startup methods. The base class knows that it needs those methods, but an abstract class lets your class admit that it doesn't know how to perform those actions; it only knows that it must initiate the actions. When it is time to start up, the abstract class can call the startup method. When the base class calls this method, Java calls the method defined by the child class.

Many developers forget that a class that defines an abstract method can call that method as well. Abstract classes are an excellent way to create planned inheritance hierarchies. They're also a good choice for nonleaf classes in class hierarchies.

查看更多
Anthone
3楼-- · 2019-01-03 18:45

Generally speaking, the approach I use in this kind of situation is to have both an interface and an abstract class. The interfaces defines, well, the interface. The abstract class is merely a helper.

You really can't go wrong with this approach. Interfaces give you the flexibility to change implementation. Abstract classes give you boilerplate and helper code that you aren't forced to use, which you otherwise would be if your methods were defined in terms of an abstract class explicitly.

查看更多
何必那么认真
4楼-- · 2019-01-03 18:49

The interface would be my default until there is a reason to use a base class, as it makes fewer decisions for us.

I wouldn't involve IXmlSerializable unless I had to though; it is a messy, tricky interface that is often a cause of woe.

What exactly are your serialization requirements? There may be better options... however, for many serializers a base-class would be easier than an interface. For example, for XmlSerializer you could have:

[XmlInclude(typeof(MyObject))] // : ObjectBase 
[XmlInclude(typeof(MyObjectGroup))] // : ObjectBase 
public abstract class ObjectBase { /*  */ }

(the exact approach depends on the serializer)

查看更多
Juvenile、少年°
5楼-- · 2019-01-03 18:53

There are two thing is in Architect’s mind when designing classes.

  1. Behavior of an object.
  2. object’s implementation.

If an entity has more than one implementation, then separating the behavior of an object from its implementation is one of the key for maintainability and decoupling. Separation can be achieved by either Abstract class or Interface but which one is the best? Lets take an example to check this.

Lets take a development scenario where things (request, class model, etc) are changing very frequently and you have to deliver certain versions of application.

Initial problem statement : you have to create a “Train” class for Indian railway which has behavior of maxSpeed in 1970 .

1. Business Modeling with abstract class

V 0.0 (Initial problem) Initial problem statement : you have to create a Train class for Indian railway which has behavior of maxSpeed in 1970 .

public abstract class Train {
    public int maxSpeed();
}

V 1.0 (Changed problem 1) changed problem statement : You have to create a Diesel Train class for Indian railway which has behavior of maxSpeed, in 1975.

public abstract class DieselTrain extends train {
     public int maxFuelCapacity ();
}

V 2.0 (Changed problem 2) chanded problem statement : you have to create a ElectricalTrain class for Indian railway which has behavior of maxSpeed , maxVoltage in 1980.

public abstract class ElectricalTrain extends train {
     public int maxvoltage ();
}

V 3.0 (Changed problem 3 )

chanded problem statement : you have to create a HybridTrain (uses both diesel and electrcity) class for Indian railway which has behavior of maxSpeed , maxVoltage,maxVoltage in 1985 .

public abstract class HybridTrain extends ElectricalTrain , DisealTrain {
    { Not possible in java }
}
{here Business modeling with abstract class fails}

2. Business Modeling with interface

Just change abstract word to interface and …… your Business Modeling with interface will succeeds.

http://javaqna.wordpress.com/2008/08/24/why-the-use-on-interfaces-instead-of-abstract-classes-is-encouraged-in-java-programming/

查看更多
Bombasti
6楼-- · 2019-01-03 18:53

If you have function in class,you should use abstact class instead of interface. In general,an interface is used to be on behalf of a type.

查看更多
迷人小祖宗
7楼-- · 2019-01-03 18:55

An Interface will allow you to define a 'contract' that the object will need to fulfil by delivering properties and methods as described by the interface. You can refer to objects by variables of interface-type which can cause some confusion as to what exactly is being offered.

A base class offers the opportunity to build an inheritance 'tree' where more complex classes (of a common 'type') are built on the foundations of a simpler 'base' classes. The classic and annoying example in OO is normally a base class of 'Shape' and which is inherited by Triangle, Square, etc.

The main point is that with an Interface you need to provide the entire contract with every class that implements it, with an inheritance tree (base classes) you are only changing/adding the properties and methods that are unique to the child class, common properties and methods remain in the base class.

In your example above I'd have the 'MyObjectGroup' object inherit the base 'MyObject' class, nothing to be gained from an interface here that I can see.

查看更多
登录 后发表回答