Inheritance and interfaces
This is somewhat of a follow-up question to this question.
Suppose I have an inheritance tree as follows:
Car -> Ford -> Mustang -> MustangGT
Is there a benefit to defining interfaces for each of these classes? Example:
ICar -> IFord -> IMustang -> IMustangGT
I can see that maybe other classes (like Chevy
) would want to implement Icar
or IFord
and maybe even IMustang
, but probably not IMustangGT
because it is so specific. Are the interfaces superfluous in this case?
Also, I would think that any class that would want to implement IFord
would definitely want to use its one inheritance by inheriting from Ford
so as not to duplicate code. If that is a given, what is the benefit of also implementing IFord
?
In my experience, interfaces are best used when you have several classes which each need to respond to the same method or methods so that they can be used interchangeably by other code which will be written against those classes' common interface. The best use of an interface is when the protocol is important but the underlying logic may be different for each class. If you would otherwise be duplicating logic, consider abstract classes or standard class inheritance instead.
And in response to the first part of your question, I would recommend against creating an interface for each of your classes. This would unnecessarily clutter your class structure. If you find you need an interface you can always add it later. Hope this helps!
Adam
I also agree with adamalex's response that interfaces should be shared by classes that should respond to certain methods.
If classes have similar functionality, yet are not directly related to each other in an ancestral relationship, then an interface would be a good way to add that function to the classes without duplicating functionality between the two. (Or have multiple implementations with only subtle differences.)
While we're using a car analogy, a concrete example. Let's say we have the following classes:
Car -> Ford -> Escape -> EscapeHybrid
Car -> Toyota -> Corolla -> CorollaHybrid
Cars have wheels
and can Drive()
and Steer()
. So those methods should exist in the Car
class. (Probably the Car
class will be an abstract class.)
Going down the line, we get the distinction between Ford
and Toyota
(probably implemented as difference in the type of emblem on the car, again probably an abstract class.)
Then, finally we have a Escape
and Corolla
class which are classes that are completely implemented as a car.
Now, how could we make a Hybrid vehicle?
We could have a subclass of Escape
that is EscapeHybrid
which adds a FordsHybridDrive()
method, and a subclass of Corolla
that is CorollaHybrid
with ToyotasHybridDrive()
method. The methods are basically doing the same thing, but yet we have different methods. Yuck. Seems like we can do better than that.
Let's say that a hybrid has a HybridDrive()
method. Since we don't want to end up having two different types of hybrids (in a perfect world), so we can make an IHybrid
interface which has a HybridDrive()
method.
So, if we want to make an EscapeHybrid
or CorollaHybrid
class , all we have to do is to implement the IHybrid
interface .
For a real world example, let's take a look at Java. A class which can do a comparison of an object with another object implements the Comparable
interface. As the name implies, the interface should be for a class that is comparable, hence the name "Comparable".
Just as a matter of interest, a car example is used in the Interfaces lesson of the Java Tutorial.
You shouldn't implement any of those interfaces at all.
Class inheritance describes what an object is (eg: it's identity). This is fine, however most of the time what an object is, is far less important than what an object does. This is where interfaces come in.
An interface should describe what an object does) , or what it acts like. By this I mean it's behavior, and the set of operations which make sense given that behaviour.
As such, good interface names should usually be of the form IDriveable
, IHasWheels
, and so on. Sometimes the best way to describe this behaviour is to reference a well-known other object, so you can say "acts like one of these" (eg: IList
) but IMHO that form of naming is in the minority.
Given that logic, the scenarios where interface inheritance makes sense are completely and entirely different from the scenarios where object inheritance makes sense - often these scenarios don't relate to eachother at all.
Hope that helps you think through the interfaces you should actually need :-)
链接地址: http://www.djcxy.com/p/38146.html上一篇: 为什么C#不允许静态方法来实现接口?
下一篇: 继承和接口