You have the concepts upside down.
Inheritance, as the word says is when you "take" from an existing object the functionality. This is know as IS-A relationship. For instance a Truck IS-A Vehicle.
In your first sample that's not inheritance, because you are not taking anything from the list. In your sample you are "implementing" that list not "extending" it.
Composition is when you build an object using others ( you're combining objects ). This is know as HAS-A relationship. For instance a Truck HAS-A wheel ( but is not a wheel ). In your sample you are "extending" ( inheriting ) from other object
Finally interface in OOP is the "contract" an object is commited to fulfill. What functions or messages an object will respond.
In Java "interface" is also an artifact where the methods an object will respond are defined.
So, for a stack you would have to define the methods an Stack has ( the interface )
public interface Stack {
public void push( Object o );
public Object pop();
}
Then using inheritance you can create the stack implementation. To do this you'll have to extend ( or inherit ) functionality from other class. Let's say ArrayList
/**
* Sample stack implementation using inheritance
*/
public class ArrayListStack extends ArrayList implements Stack {
// you use the keyword extends because you're inheriting from ArrayList
// and the keyword implements because you claim to respond to push and pop methods.
public void push( Object o ) {
this.add( o ); // add inherited from ArrayList
}
public Object pop() {
return this.remove( this.size() -1 ); // remove inherited from ArrayList
}
}
Since you're "inheriting" from ArrayList, most the what you need is already there. But, does this represents a IS-A relatioship? Is it true that a Stack IS-An ArrayList always?
To implement the stack using composition you have to "combine" your object with another.
/**
* Sample stack implementation using composition
*/
public class ComposedStack implements Stack {
// you didn't extend anything here
// But you'll need another object to help you
// to do the work.
private ArrayList holder = .... // Should be declared as List holder = ....
public void push( Object o ) {
this.holder.add( o );
}
public Object pop() {
return this.holder.remove( this.holder.size() -1 );
}
}
The implementation is very similar, you're using "add" and "remove" methods from the ArrayList
The difference is the in the first case using inheritance you are not only using these two methods, but you are coupling your object completely to the ArrayList itself ( because you have also inherit all the other methods, and attribute the ArrayList has )
When you use composition, you don't couple your object to the arraylist ( or the coupling is low, which is a good thing ) You are simply using another object to help you to do the work. In this case it was an ArrayList.
From the outside ( using composition ) , you don't see there is an ArrayList inside, that's information hiding. The user ( the client ) of your class only see two methods available "push" and "pop" and there's nothing more that could be done with your class. It looks like a "real" Stack.
With inheritance ( using extends keyword ), the client of the class see's also all the methods from ArrayList although you may want that only pop and push are used, nothing prevents from the client to use "removeRange" for instance.
Conclusión: Understanding the differences between is-a and has-a relationships is essential for OO technology. I hope this help you.