Suppose, I have 2 configurations.
First one:
interface I {
...
}
class A implements I {
...
}
class B implements I {
...
}
class Component {
I i;
Component (I i) {
this.i = i;
}
}
Second one:
class C {
...
}
class A extends C {
...
}
class B extends C {
...
}
class Component {
C c;
Component (C c) {
this.c = c;
}
}
What in the difference between those two configurations which are using two different loose coupling mechanisms (based on interface and based on class)?
Why should I need to use interface over class?
Mainly, using classes is a more heavy approach. Base classes usually contain concrete (non-abstract) methods. And if you derive from them you will need also to inherit such concrete methods, which you may not want.
For example, imagine that you want to benefit from composition design patterns like the decorator pattern. Here, your decorator needs also to derive from the base class and will inherit the concrete methods. However, your decorator will not need the concrete method to function.
In summary, it is more hard/unclean to do object composition if your abstractions are class-based.
Abstraction through interfaces on the other hand, does not force implementing classes to inherit any concrete method implementation. Therefore, it is more clean.
An object can implements multiple interfaces but can only extends one class, so sometimes the user of your loose coupled library may not be able to extends your class.
when you extends, you incorporate the code of the superclass into yours, sometimes there is no code to incorporate so implements is better suited.
Finally it is not the same paradigm, when you write "B extends A" you say "I am A, I do the same things, but I can also make other things". When you write "B implements A" you say "I am B, but you can treat me as an A".
Long story short, the only practical reason would be the first.
A hierarchy based upon interfaces is a good desing approach, because it eases implementation: You can always implement an interface, but not always you can extend a class (for example, a final class). Or, in the other hand, not always a class' author want it to be extended.
So, you are highly interested on using interfaces over classes, because in this way you may accept a wider set of implementations. For example:
Using classes:
class Component
{
AbstractList c;
Component (AbstractList c){...}
}
... Component would accept ArrayList or Vector.
Instead, using interfaces:
class Component
{
List c;
Component (List c){...}
}
... Component would be able to accept ArrayList, Vector, CopyOnWriteArrayList...
Related
I've been reading a lot about interfaces and class inheritance in Java, and I know how to do both and I think I have a good feel for both. But it seems that nobody ever really compares the two side by side and explains when and why you would want to use one or the other. I have not found a lot of times when implementing an interface would be a better system than extending a superclass.
So when do you implement an interface and when do you extend a superclass?
Use an interface if you want to define a contract. I.e. X must take Y and return Z. It doesn't care how the code is doing that. A class can implement multiple interfaces.
Use an abstract class if you want to define default behaviour in non-abstract methods so that the endusers can reuse it without rewriting it again and again. A class can extend from only one other class. An abstract class with only abstract methods can be as good definied as an interface. An abstract class without any abstract method is recognizeable as the Template Method pattern (see this answer for some real world examples).
An abstract class in turn can perfectly implement an interface whenever you want to provide the enduser freedom in defining the default behaviour.
You should choose an interface if all you want is to define a contract i.e. method signatures that you want the inheriting classes to implement. An interface can have no implementation at all. The inheriting classes are free to choose their own implementation.
Sometimes you want to define partial implementation in a base type and want to leave the rest to inheriting classes. If that is the case, choose an abstract class. An abstract class can define method implementations and variables while leaving some methods as abstract. Extending classes can choose how to implement the abstract methods while they also have the partial implementation provided by the superclass.
One extreme of abstract classes is a pure abstract class - one that has only abstract methods and nothing else. If it comes to pure abstract class vs. an interface, go with the interface. Java allows only single implementation inheritance whereas it allows multiple interface inheritance meaning that a class can implement multiple interfaces but can extend only one class. So choosing a pure abstract class over the interface will mean that the subclass will not be allowed to extend any other class while implementing the abstract methods.
Use an interface to define behavior. User (abstract) classes (and subclasses) to provide implementation. They are not mutually exclusive; they can all work together.
For example, lets say you are defining a data access object. You want your DAO to be able to load data. So put a load method on the interface. This means that anything that wants to call itself a DAO must implement load. Now lets say you need to load A and B. You can create a generic abstract class that is parameterized (generics) to provide the outline on how the load works. You then subclass that abstract class to provide the concrete implementations for A and B.
The main reason for using abstract classes and interfaces are different.
An abstract class should be used when you have classes that have identical implementations for a bunch of methods, but vary in a few.
This may be a bad example, but the most obvious use of abstract classes in the Java framework is within the java.io classes. OutputStream is just a stream of bytes. Where that stream goes to depends entirely on which subclass of OutputStream you're using... FileOutputStream, PipedOutputStream, the output stream created from a java.net.Socket's getOutputStream method...
Note: java.io also uses the Decorator pattern to wrap streams in other streams/readers/writers.
An interface should be used when you just want to guarantee that a class implements a set of methods, but you don't care how.
The most obvious use of interfaces is within the Collections framework.
I don't care how a List adds/removes elements, so long as I can call add(something) and get(0) to put and get elements. It may use an array (ArrayList, CopyOnWriteArrayList), linked list (LinkedList), etc...
The other advantage in using interfaces is that a class may implement more than one. LinkedList is an implementation of both List and Deque.
No one?
http://mindprod.com/jgloss/interfacevsabstract.html
EDIT: I should supply more than a link
Here's a situation. To build on the car example below, consider this
interface Drivable {
void drive(float miles);
}
abstract class Car implements Drivable {
float gallonsOfGas;
float odometer;
final float mpg;
protected Car(float mpg) { gallonsOfGas = 0; odometer = 0; this.mpg = mpg; }
public void addGas(float gallons) { gallonsOfGas += gallons; }
public void drive(float miles) {
if(miles/mpg > gallonsOfGas) throw new NotEnoughGasException();
gallonsOfGas -= miles/mpg;
odometer += miles;
}
}
class LeakyCar extends Car { // still implements Drivable because of Car
public addGas(float gallons) { super.addGas(gallons * .8); } // leaky tank
}
class ElectricCar extends Car {
float electricMiles;
public void drive(float miles) { // can we drive the whole way electric?
if(electricMiles > miles) {
electricMiles -= miles;
odometer += miles;
return; // early return here
}
if(electricMiles > 0) { // exhaust electric miles first
if((miles-electricMiles)/mpg > gallonsOfGas)
throw new NotEnoughGasException();
miles -= electricMiles;
odometer += electricMiles;
electricMiles = 0;
}
// finish driving
super.drive(miles);
}
}
I think that interfaces work best when you use them to express that the object has a certain property or behavior, that spans multiple inheritance trees, and is only clearly defined for each class.
For example think of Comparable. If you wanted to create a class Comparable to be extended by other classes, it would have to be very high on the inheritance tree, possible right after Object, and the property it expresses is that two objects of that type can be compared, but there's no way to define that generally (you can't have an implementation of compareTo directly in the Comparable class, it's different for every class that implements it).
Classes work best when they define something clear, you know what properties and behaviors they have, and have actual implementations for methods, that you want to pass down to the children.
So classes work when you need to define a concrete object like a human, or a car, and interfaces work better when you need more abstract behavior that's too general to belong to any inheritance tree, like the ability to be compared (Comparable) or to be run (Runnable).
One method of choosing between an interface and a base class is the consideration of code ownership. If you control all the code then a base class is a viable option. If on the other hand many different companies might want to produce replaceable components, that is define a contract then an interface is your only choice.
I found some articles, particularly some who describe why you should not use implementation inheritance (i.e. superclasses):
Why extends is evil
Inheritance of implementation is evil
Implementation inheritance
Implementation inheritance
Java inheritance FAQ
I guess I'll give the classic car example.
When you have a car interface, you can create a Ford, a Chevy, and an Oldsmobile. In other words, you create different kinds of cars from a car interface.
When you have a car class, you can then extend the car class to make a truck, or a bus. In other words, you add new attributes to the sub classes while keeping the attributes of the base or super class.
You can think of extending from a super class if the derived class is of the same type.I mean that when a class extends an abstract class, they both should be of the same type, the only difference being that the super class has a more general behavior and the sub class has a more specific behavior. An interface is a totally different concept. When a class implements an interface, its either to expose some API(contract) or to get certain behavior. To give an example, I would say that Car is an abstract class. You can extend many classes from it like say Ford, Chevy and so on which are each of type car. But then if you need certain specific behavior like say you need a GPS in a car then the concrete class, eg Ford should implement GPS interface.
If you only want to inherit method signatures (name, arguments, return type) in the subclasses, use an interface, but if you also want to inherit implementation code, use a superclass.
Consider the following two classes:
class A {
String _name;
char _type;
public A(String name, char type) {
_name = name; _type = type;
}
public int method1() {
do_something...;
}
public String method2() {
make_something...;
}
}
and
class B extends A {
public B(String name) {
super(name, 'a');
}
#Override
public int method1() {
do_something_else...;
}
#Override
public String method2() {
String answer = super.method2();
answer += more_processing...;
}
}
I am using inheritance here because the classes share many things in common. However, because I am overriding every single methods from the superclass, is it a good idea to use inheritance here?
That depends on the context. If you are going to use many features of the class (attributes and methods), you must use inheritance and override those few methods you need to change. If you are going to use just few features and need to override almost all methods, you better create a new class. Another case could be if a particular method of the class is very difficult to code or had a very important implementation, again it depends on the context.
Inheritance should be used whenever you can replace an instance of the super-type A with an instance of the sub-type B, without breaking anything. This is also known as the Liskov substitution principle.
Another kind of hacky but still valid case for inheritance is when you need to access otherwise unaccessible methods or properties of the super-type A. In this case, I prefer to not directly let B extend the super-type A but to use an inner class B.ChildOfA that extends the super-type A. This will prevent B from being used as an instance of A where this is not appropriate.
In general, you should prefer composition over inheritance.
To answer your question: It does not depend on whether you overwrite everything but on how your sub-class can or should be used.
If you override everything from A in B and you don't delegate to the super-type A, but both types should still be exchangeable like defined by the Liskov substitution principle, then you also have a third option: You can declare a common super-type I and let both classes inherit it. The newly introduced super-type I can be an interface or a class. Of course, this is only possible if you own the class A, because you need to change it to inherit the new super-type I.
You'll have to ask yourself the question:
Is Class B a subclass of Class A?
Overriding the methods doesn't really matter as long as you understand what inheritance is used for. (i.e Class B is a subtype of Class A but does things a little differently)
The crucial question you have to ask is:
"Is B an A?"
If so, then using inheritance is likely to be a good idea.
Although you may not have any methods that have the same implementation in both classes, that could change in the future as you and others working on your codebase could add new methods.
Another question you have to ask is, does each method and it's overridden version differ by WHAT they do, or just by HOW they behave? If it's the latter then again inheritance is probably the way to go.
Where I work we consider it best practice to mostly use interfaces (composition) over inheritance where possible. This is partly because one class can implement multiple interfaces in Java, but can only extend one class using inheritance. There are other reasons but I don't want to go too off-topic. However if the relationship between the classes you've written is more that they just HAVE similar members, rather than have an "is-a" relationship, then you might want to consider putting those shared members (methods and fields) in an interface instead of using inheritance.
In this case, where B does not actually inherit anything from A it may make more sense to use a common interface that both A and B implement in their own way. Context is important when making these types of inheritance decisions.
public interface SomeInterface {
public int method1();
public String method2();
}
A:
public class A implements SomeInterface {
B:
public class B implements SomeInterface {
Say I have an interface A and a class B that implements it.
Now, I also have some class C which extends class D (which means that it can't also extends B) but I also need there the functionality of interface A.
The solution I know is to have a member of A instantiated by B in C (which will implement A) and when implementing the functions of A call the matching function from the member of A.
Is there any way to create some connection between the functions of A and the member inside C? (so that java will know that every time it needs to call a function from A it will directly go and and run the matching function from the A member without me needing to write the code for it for every function of A)
A big thank you is waiting to each one of the helpers...
No. As already stated delegation must be implemented manually.
Having said that, you have a few options to simplify this: If you're working with Eclipse, select Source|Generate Delegate Methods... and select your member variable. Eclipse will then generate all the delegate methods for you. I don't know about other IDEs, but I would be surprised, if NetBeans et al. would not have a similar feature.
Another option, if you actually want to decorate existing collection classes, consider Google Guava's Google Guava's Collection Helpers.
Last, but not least, you could consider restructing your code and decorate your classes using Advices. Advices stem from Aspect Oriented Programming (AOP) and typically use a proxying mechanism to enrich original target classes. This is a rather advanced technique, but if you are determined to go down this road, have a look at Spring's AOP support.
So to sum up, here is your class hierarchies:
package common;
public interface A
{
void doStuff();
}
package commom.impl;
public class B implements A
{
void doStuff() {}
}
package real.service;
public class D
{
void doSomeRealStuff() {}
}
package real.service;
public class C extends D
{
void doSomeRealStuffForGood() {}
}
Assuming that each class is declared in its own source file.
Just to recall from the OP, I assume you need B stuff in C and not really A stuff. Because A is nothing but a contract and you need then the real implemting class to be fetched inside your C class in order to call the declared methods on.
In such a case, you may need to use the Inversion of Responsability approach, so that you declare an instacne of type B inside your C clas then you layer each method from B with a one having the same signature and that do nothing but delegate the real call to the instance member:
package real.service;
import common.A;
import common.impl.B;
public class C extends D
{
private A delegate;
public C ()
{
delegate = new B();
}
void doStuff() {
delegate.doStuff(); // Call the real delegate method when doStuff is called on an isntance of C.
}
void doSomeRealStuffForGood() {}
}
Note that this is a legal OO concept, since you are following an HAS-a even though some could consider it a high coupling.
Otherwise if you are not tied to the B class, and you may drop the declare methods in there for some others, you can declare an inner class that implements the A interface the way you need.
Edit:
Java does not support multiple inheritance, though you have provided a common contract in your A interface, so if you need all those methods (behavior) to be availble in your C class, it would be better to implement it directely and override all the interface methods.
I was thinking about programming to interfaces and not to concrete classes, but I had a doubt: should any interface method be able to hold references to concrete classes?
Suppose the following scenarios:
1)
public interface AbsType1 {
public boolean method1(int a); // it's ok, only primitive types here
}
2)
public interface AbsType2 {
public boolean method2(MyClass a); // I think I have some coupling here
}
Should I choose a different design here in order to avoid the latter? e.g.
public interface MyInterface {} // yes, this is empty
public classe MyClass implements MyInterface {
// basically identical to the previous "MyClass"
}
public interface AbsType2 {
public boolean method2(MyInterface a); // this is better (as long as the
// interface is really stable)
}
But there's still something that doesn't convince me... I feel uncomfortable with declaring an empty interface, though I saw someone else doing so.
Maybe and Abstract Class would work better here?
I am a little bit confused.
EDIT:
Ok, I'll try to be more specific by making an example. Let's say I'm desining a ShopCart and I want of course to add items to the cart:
public interface ShopCart {
public void addArticle(Article a);
}
Now, if Article were a concrete class, what if its implementation changes over time? This is why I could think of making it an Interface, but then again, it's probably not suitable at least at a semantic level because interfaces should specify behaviours and an Article has none (or almost none... I guess it's a sort of entity class).
So, probably I'm ending up right now to the conclusion that making Article an abstract class in this case would be the best thing... what do you think about it?
I would use interfaces because composition is much better than inheritance. "Should any interface method be able to hold references to concrete classes ?", why it shouldn't? Some classes within package are coupled, it's a fact and common use technique. When you marked this relation in interface then you see on which classes is dependent your implementation. Dependency or composition relations are not inheritance so a i would avoid abstract class.
In my opinion Interfaces are fine for all types where the implementation may vary. But if you define a module which introduces a new type, that isn't intended to have alternative implementations then there is no need to define it as an Interface in the first place. Often this would be over-design in my opinion. It depends on the problem domain and often on the way how support testing or AOP-weaving.
For example consider a 2D problem domain where you need to model a Location as a type. If it is clear that a Location is always represented by a x and y coordinate, you may provide it as a Class. But if you do not know which properties a Location could have (GPS data, x, y, z coordinates, etc.) but you rely on some behavior like distance(), you should model it as an Interface instead.
If there are no public methods which AbsType would access in MyClass then the empty interface is probably not a good way to go.
There is no interface declaration (contract) for static methods, which otherwise might make sense here.
So, if AbsType is not going to use any methods from MyClass/MyInterface, then I assume it's basically only storing the class object for some other purpose. In this case, consider using generics to make clear how you want AbsType to be used without coupling closely to the client's code, like
public class AbsType3<C extends Class<?>> {
public boolean method3(T classType) {...}
}
Then you can restrict the types of classes to allow if needed by exchanging the <C extends Class<?>> type parameter for something else which may also be an interface, like
<C extends Class<Collection<?>>>.
Empty interfaces are somewhat like boolean flags for classes: Either a class implements the interface (true) or it doesn't (false). If at all, these marker interfaces should be used to convey an significant statement about how a class is meant to be (or not to be) used, see Serializable for example.
I have an interface and I am promised by someone to provide its implementation.
I have to now design a class s.t I can extend "someone's" implementation. However I do not know the name of that implementation.
eg.
interface X{ void methodA(int); int methodB();}
class A implements X { /*impl code here*/}
Now, I don't know , what class is going to implement X. But I want to incorporate those implementations into my code
class B extends <Anyclass that implements interface X>
{/*other impl here*/}
How do I go about doing this? I know in generics you can specify when using Comparator. I want to know if there is anything available for this case?
So you want an instance of X that has the same interface as the class that you get at runtime, but allows you to specify how certain methods of X behave?
If you have an instance of A at runtime, you can use proxy classes to create an object that implements all the interfaces that the class implements, including X, and that overrides some methods of X to do what you want, and delegates the rest to the instance.
Proxy classes are not great efficiency wise and the kind of dynamism they provide is usually easier to achieve by more normal means, so don't overuse them, but where you need a bit of flexible glue at the boundary between two parts of a system, they can really help.
Also note, that the resulting object is not an A, it just implements the same interfaces as A.
Here's your interface:
interface X{ void methodA(int); int methodB();}
Make an abstract super class:
abstract class A implements X { /*impl code here*/}
Now B (and every other class that extends A) promises to implement the interface:
class B extends A {/*other impl here*/}
Is there a reason you want to avoid composition here? You aren't going to have access to the mystery implementation without the name. You can't extend ? extends X, but you can have an instance of it. This is rather trivial using composition:
interface X
{
void methodA( int param );
int methodB();
}
class YourImpl<T extends X> implements X
{
private T delegate;
public YourImpl( T delegate )
{
this.delegate = delegate;
}
void methodA( int param )
{
delegate.methodA( param );
}
int methodB()
{
return delegate.methodB();
}
}
You don't stand to gain much in this example, but if you do additional processing before/after delegation, there's a lot to be gained.
Generally speaking, people gravitate towards inheritance to solve their problems, even when composition is more appropriate. I would suggest reconsidering whether composition is an okay solution for you. Another thing to consider is whether the mystery implementation can use your implementation, rather than vice versa.
I have to now design a class s.t I can extend "someone's" implementation. However I do not know the name of that implementation.
That is not possible. Java does not allow you to extend a generic type parameter. You can only extend a named class.
To achieve what you are trying to achieve, you will need to use some kind of proxying, delegation or wrappering. For example:
public class B implements X {
private X x;
public B(X x) {
this.x = x;
}
// delegate each method in the X interface as required; e.g.
public int someMethod(String s) {
return x.someMethod(s);
}
// add any implementations of B-specific methods.
}
This is not exactly "composition", but I suspect it is the kind of thing you are trying to avoid. Unfortunately (for you), there's no real alternative. The Java language and the JVM both require that every class apart from Object has a single definite super-class.