Related
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does it mean to “program to an interface”?
I keep coming across this term:
Program to an interface.
What exactly does it mean? A real life design scenario would be highly appreciated.
To put it simply, instead of writing your classes in a way that says
I depend on this specific class to do my work
you write it in a way that says
I depend on any class that does this stuff to do my work.
The first example represents a class that depends on a specific concrete implementation to do its work. Inherently, that's not very flexible.
The second example represents a class written to an interface. It doesn't care what concrete object you use, it just cares that it implements certain behavior. This makes the class much more flexible, as it can be provided with any number of concrete implementations to do its work.
As an example, a particular class may need to perform some logging. If you write the class to depend on a TextFileLogger, the class is forever forced to write out its log records to a text file. If you want to change the behavior of the logging, you must change the class itself. The class is tightly coupled with its logger.
If, however, you write the class to depend on an ILogger interface, and then provide the class with a TextFileLogger, you will have accomplished the same thing, but with the added benefit of being much more flexible. You are able to provide any other type of ILogger at will, without changing the class itself. The class and its logger are now loosely coupled, and your class is much more flexible.
An interface is a collection of related methods, that only contains the signatures of those methods - not the actual implementation.
If a class implements an interface (class Car implements IDrivable) it has to provide code for all signatures defined in the interface.
Basic example:
You have to classes Car and Bike. Both implement the interface IDrivable:
interface IDrivable
{
void accelerate();
void brake();
}
class Car implements IDrivable
{
void accelerate()
{ System.out.println("Vroom"); }
void brake()
{ System.out.println("Queeeeek");}
}
class Bike implements IDrivable
{
void accelerate()
{ System.out.println("Rattle, Rattle, ..."); }
void brake()
{ System.out.println("..."); }
}
Now let's assume you have a collection of objects, that are all "drivable" (their classes all implement IDrivable):
List<IDrivable> vehicleList = new ArrayList<IDrivable>();
list.add(new Car());
list.add(new Car());
list.add(new Bike());
list.add(new Car());
list.add(new Bike());
list.add(new Bike());
If you now want to loop over that collection, you can rely on the fact, that every object in that collection implements accelerate():
for(IDrivable vehicle: vehicleList)
{
vehicle.accelerate(); //this could be a bike or a car, or anything that implements IDrivable
}
By calling that interface method you are not programming to an implementation but to an interface - a contract that ensures that the call target implements a certain functionality.
The same behavior could be achieved using inheritance, but deriving from a common base class results in tight coupling which can be avoided using interfaces.
Polymorphism depends on programming to an interface, not an implementation.
There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.
This so greatly reduces implementation dependencies between subsystems that it leads to this principle of programming to an interface.
See the Factory Method pattern for further reasoning of this design.
Source: "Design Patterns: Elements of Reusable Object-Oriented Software" by G.O.F.
Also See: Factory Pattern. When to use factory methods?
Real-world examples are applenty. One of them:
For JDBC, you are using the interface java.sql.Connection. However, each JDBC driver provides its own implementation of Connection. You don't have to know anything about the particular implementation, because it conforms to the Connection interface.
Another one is from the java collections framework. There is a java.util.Collection interface, which defines size, add and remove methods (among many others). So you can use all types of collections interchangeably. Let's say you have the following:
public float calculateCoefficient(Collection collection) {
return collection.size() * something / somethingElse;
}
And two other methods that invoke this one. One of the other methods uses a LinkedList because it's more efficient for it's purposes, and the other uses a TreeSet.
Because both LinkedList and TreeSet implement the Collection interface, you can use only one method to perform the coefficient calculation. No need to duplicate your code.
And here comes the "program to an interface" - you don't care how exactly is the size() method implemented, you know that it should return the size of the collection - i.e. you have programmed to the Collection interface, rather than to LinkedList and TreeSet in particular.
But my advice is to find a reading - perhaps a book ("Thinking in Java" for example) - where the concept is explained in details.
Every object has an exposed interface. A collection has Add, Remove, At, etc. A socket may have Send, Receive, Close and so on.
Every object you can actually get a reference to has a concrete implementation of these interfaces.
Both of these things are obvious, however what is somewhat less obvious...
Your code shouldn't rely on the implementation details of an object, just its published interface.
If you take it to an extreme, you'd only code against Collection<T> and so on (rather than ArrayList<T>). More practically, just make sure you could swap in something conceptually identical without breaking your code.
To hammer out the Collection<T> example: you have a collection of something, you're actually using ArrayList<T> because why not. You should make sure you're code isn't going to break if, say, you end up using LinkedList<T> in the future.
"Programming to an interface" happens when you use libraries, other code you depend upon in your own code. Then, the way that other code represents itself to you, the method names, its parameters, return values etc make up the interface you have to program to. So it's about how you use third-party code.
It also means, you don't have to care about the internals of the code you depend on, as long as the interface stays the same, your code is safe (well, more or less...)
Technically there are finer details, like language concepts called "interfaces" in Java for example.
If you want to find out more, you could ask what "Implementing an Interface" means...
I think this is one of Erich Gamma's mantras. I can't find the first time he described it (before the GOF book), but you can see it discussed in an interview at: http://www.artima.com/lejava/articles/designprinciples.html
It basically means that the only part of the library which you're going to use you should rely upon is it's API (Application programming interface) and that you shouldn't base your application on the concrete implementation of the library.
eg. Supposed you have a library that gives you a stack. The class gives you a couple of methods. Let's say push, pop, isempty and top. You should write your application relying only on these. One way to violate this would be to peek inside and find out that the stack is implemented using an array of some kind so that if you pop from an empty stack, you'd get some kind of Index exception and to then catch this rather than to rely on the isempty method which the class provides. The former approach would fail if the library provider switched from using an array to using some kind of list while the latter would still work assuming that the provider kept his API still working.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does it mean to “program to an interface”?
I keep coming across this term:
Program to an interface.
What exactly does it mean? A real life design scenario would be highly appreciated.
To put it simply, instead of writing your classes in a way that says
I depend on this specific class to do my work
you write it in a way that says
I depend on any class that does this stuff to do my work.
The first example represents a class that depends on a specific concrete implementation to do its work. Inherently, that's not very flexible.
The second example represents a class written to an interface. It doesn't care what concrete object you use, it just cares that it implements certain behavior. This makes the class much more flexible, as it can be provided with any number of concrete implementations to do its work.
As an example, a particular class may need to perform some logging. If you write the class to depend on a TextFileLogger, the class is forever forced to write out its log records to a text file. If you want to change the behavior of the logging, you must change the class itself. The class is tightly coupled with its logger.
If, however, you write the class to depend on an ILogger interface, and then provide the class with a TextFileLogger, you will have accomplished the same thing, but with the added benefit of being much more flexible. You are able to provide any other type of ILogger at will, without changing the class itself. The class and its logger are now loosely coupled, and your class is much more flexible.
An interface is a collection of related methods, that only contains the signatures of those methods - not the actual implementation.
If a class implements an interface (class Car implements IDrivable) it has to provide code for all signatures defined in the interface.
Basic example:
You have to classes Car and Bike. Both implement the interface IDrivable:
interface IDrivable
{
void accelerate();
void brake();
}
class Car implements IDrivable
{
void accelerate()
{ System.out.println("Vroom"); }
void brake()
{ System.out.println("Queeeeek");}
}
class Bike implements IDrivable
{
void accelerate()
{ System.out.println("Rattle, Rattle, ..."); }
void brake()
{ System.out.println("..."); }
}
Now let's assume you have a collection of objects, that are all "drivable" (their classes all implement IDrivable):
List<IDrivable> vehicleList = new ArrayList<IDrivable>();
list.add(new Car());
list.add(new Car());
list.add(new Bike());
list.add(new Car());
list.add(new Bike());
list.add(new Bike());
If you now want to loop over that collection, you can rely on the fact, that every object in that collection implements accelerate():
for(IDrivable vehicle: vehicleList)
{
vehicle.accelerate(); //this could be a bike or a car, or anything that implements IDrivable
}
By calling that interface method you are not programming to an implementation but to an interface - a contract that ensures that the call target implements a certain functionality.
The same behavior could be achieved using inheritance, but deriving from a common base class results in tight coupling which can be avoided using interfaces.
Polymorphism depends on programming to an interface, not an implementation.
There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.
This so greatly reduces implementation dependencies between subsystems that it leads to this principle of programming to an interface.
See the Factory Method pattern for further reasoning of this design.
Source: "Design Patterns: Elements of Reusable Object-Oriented Software" by G.O.F.
Also See: Factory Pattern. When to use factory methods?
Real-world examples are applenty. One of them:
For JDBC, you are using the interface java.sql.Connection. However, each JDBC driver provides its own implementation of Connection. You don't have to know anything about the particular implementation, because it conforms to the Connection interface.
Another one is from the java collections framework. There is a java.util.Collection interface, which defines size, add and remove methods (among many others). So you can use all types of collections interchangeably. Let's say you have the following:
public float calculateCoefficient(Collection collection) {
return collection.size() * something / somethingElse;
}
And two other methods that invoke this one. One of the other methods uses a LinkedList because it's more efficient for it's purposes, and the other uses a TreeSet.
Because both LinkedList and TreeSet implement the Collection interface, you can use only one method to perform the coefficient calculation. No need to duplicate your code.
And here comes the "program to an interface" - you don't care how exactly is the size() method implemented, you know that it should return the size of the collection - i.e. you have programmed to the Collection interface, rather than to LinkedList and TreeSet in particular.
But my advice is to find a reading - perhaps a book ("Thinking in Java" for example) - where the concept is explained in details.
Every object has an exposed interface. A collection has Add, Remove, At, etc. A socket may have Send, Receive, Close and so on.
Every object you can actually get a reference to has a concrete implementation of these interfaces.
Both of these things are obvious, however what is somewhat less obvious...
Your code shouldn't rely on the implementation details of an object, just its published interface.
If you take it to an extreme, you'd only code against Collection<T> and so on (rather than ArrayList<T>). More practically, just make sure you could swap in something conceptually identical without breaking your code.
To hammer out the Collection<T> example: you have a collection of something, you're actually using ArrayList<T> because why not. You should make sure you're code isn't going to break if, say, you end up using LinkedList<T> in the future.
"Programming to an interface" happens when you use libraries, other code you depend upon in your own code. Then, the way that other code represents itself to you, the method names, its parameters, return values etc make up the interface you have to program to. So it's about how you use third-party code.
It also means, you don't have to care about the internals of the code you depend on, as long as the interface stays the same, your code is safe (well, more or less...)
Technically there are finer details, like language concepts called "interfaces" in Java for example.
If you want to find out more, you could ask what "Implementing an Interface" means...
I think this is one of Erich Gamma's mantras. I can't find the first time he described it (before the GOF book), but you can see it discussed in an interview at: http://www.artima.com/lejava/articles/designprinciples.html
It basically means that the only part of the library which you're going to use you should rely upon is it's API (Application programming interface) and that you shouldn't base your application on the concrete implementation of the library.
eg. Supposed you have a library that gives you a stack. The class gives you a couple of methods. Let's say push, pop, isempty and top. You should write your application relying only on these. One way to violate this would be to peek inside and find out that the stack is implemented using an array of some kind so that if you pop from an empty stack, you'd get some kind of Index exception and to then catch this rather than to rely on the isempty method which the class provides. The former approach would fail if the library provider switched from using an array to using some kind of list while the latter would still work assuming that the provider kept his API still working.
This question already has answers here:
Interface vs Abstract Class (general OO)
(36 answers)
Closed 8 years ago.
I haven't done OOP in a while so I'm a bit rusty.
For an example, i have a client with a rental subscription, and it exist 3 type of subscription. How can i choose between abstract class and interface for my "Subscription" class?
Each subscription must have the price, maximum Rental Duration and maximum Rental Count.
From what I remember, I would use interface here but how can I force other classes that implements subscription to specify the value(constant) of these 3 properties?
If you're thinking of defining fields that are common to all implementations, you can't use an interface, because an interface does not contain state. It can just declare methods and constants. State is considered part of an implementation, not type information.
You could, however, define three abstract getter methods - getPrice(), getDuration() and getCount() or something like that, and leave the actual implementation of how those work to the implementing classes. In that case, you could use either an interface or an abstract class.
You'd choose an abstract class if you have some implementation that you want to have which is common to all subclasses. For example, if you have a specific way to perform "rent out", or "send reminder to renter" or other operations. Those methods will be concrete, and only the above three getters will be abstract.
If you don't have any common operations, and you find yourself just having the abstract methods and nothing else, an interface will probably serve you best, especially so because Java is single-inheritance, and using an interface will allow you to extend another class when you are creating your concrete classes.
These are just rules of thumb, though, not rules set in stone.
I think an abstract class makes more sense in this case. Use abstract classes when your classes all deal with the same data/methods but may slightly differ in method logic.
Interfaces may be more useful when you have several classes which have large differences but should always be constrained to a set of methods(the interface methods)
In general you use abstraction in case of inheritance and polymorphism. When you have an object that can have different behavior based on its internal type. Interfaces are used when there is a need for a contract. In general abstraction is best for objects that are closely related, while interfaces are chosen for their functionality.
In your case abstraction makes sense. You can keep the mutual properties in your base class and derive other classes from it. Eliminates some redundant code.
Here is what MS suggested:Here are some recommendations to help you to decide whether to use an interface or an abstract class to provide polymorphism for your components.
*If you anticipate creating multiple versions of your component, create an abstract class. Abstract classes provide a simple and easy way to version your components. By updating the base class, all inheriting classes are automatically updated with the change. Interfaces, on the other hand, cannot be changed once created. If a new version of an interface is required, you must create a whole new interface.
*If the functionality you are creating will be useful across a wide range of disparate objects, use an interface. Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing common functionality to unrelated classes.
*If you are designing small, concise bits of functionality, use interfaces. If you are designing large functional units, use an abstract class.
*If you want to provide common, implemented functionality among all implementations of your component, use an abstract class. Abstract classes allow you to partially implement your class, whereas interfaces contain no implementation for any members.
https://msdn.microsoft.com/en-us/library/scsyfw1d(v=vs.71).aspx
Why do many Collection classes in Java extend the Abstract class and also implement the interface (which is also implemented by the given abstract class)?
For example, class HashSet extends AbstractSet and also implements Set, but AbstractSet already implements Set.
It's a way to remember that this class really implements that interface.
It won't have any bad effect and it can help to understand the code without going through the complete hierarchy of the given class.
From the perspective of the type system the classes wouldn't be any different if they didn't implement the interface again, since the abstract base classes already implement them.
That much is true.
The reason they do implement it anyways is (probably) mostly documentation: a HashSet is-a Set. And that is made explicit by adding implements Set to the end, although it's not strictly necessary.
Note that the difference is actually observable using reflection, but I'd be hard-pressed to produce some code that would break if HashSet didn't implement Set directly.
This may not matter much in practice, but I wanted to clarify that explicitly implementing an interface is not exactly the same as implementing it by inheritance. The difference is present in compiled class files and visible via reflection. E.g.,
for (Class<?> c : ArrayList.class.getInterfaces())
System.out.println(c);
The output shows only the interfaces explicitly implemented by ArrayList, in the order they were written in the source, which [on my Java version] is:
interface java.util.List
interface java.util.RandomAccess
interface java.lang.Cloneable
interface java.io.Serializable
The output does not include interfaces implemented by superclasses, or interfaces that are superinterfaces of those which are included. In particular, Iterable and Collection are missing from the above, even though ArrayList implements them implicitly. To find them you have to recursively iterate the class hierarchy.
It would be unfortunate if some code out there uses reflection and depends on interfaces being explicitly implemented, but it is possible, so the maintainers of the collections library may be reluctant to change it now, even if they wanted to. (There is an observation termed Hyrum's Law: "With a sufficient number of users of an API, it does not matter what you promise in the contract; all observable behaviors of your system will be depended on by somebody".)
Fortunately this difference does not affect the type system. The expressions new ArrayList<>() instanceof Iterable and Iterable.class.isAssignableFrom(ArrayList.class) still evaluate to true.
Unlike Colin Hebert, I don't buy that people who were writing that cared about readability. (Everyone who thinks standard Java libraries were written by impeccable gods, should take look it their sources. First time I did this I was horrified by code formatting and numerous copy-pasted blocks.)
My bet is it was late, they were tired and didn't care either way.
From the "Effective Java" by Joshua Bloch:
You can combine the advantages of interfaces and abstract classes by adding an abstract skeletal implementation class to go with an interface.
The interface defines the type, perhaps providing some default methods, while the skeletal class implements the remaining non-primitive interface methods atop the primitive interface methods. Extending a skeletal implementation takes most of the work out of implementing an interface. This is the Template Method pattern.
By convention, skeletal implementation classes are called AbstractInterface where Interface is the name of the interface they implement. For example:
AbstractCollection
AbstractSet
AbstractList
AbstractMap
I also believe it is for clarity. The Java Collections framework has quite a hierarchy of interfaces that defines the different types of collection. It starts with the Collection interface then extended by three main subinterfaces Set, List and Queue. There is also SortedSet extending Set and BlockingQueue extending Queue.
Now, concrete classes implementing them is more understandable if they explicitly state which interface in the heirarchy it is implementing even though it may look redundant at times. As you mentioned, a class like HashSet implements Set but a class like TreeSet though it also extends AbstractSet implements SortedSet instead which is more specific than just Set. HashSet may look redundant but TreeSet is not because it requires to implement SortedSet. Still, both classes are concrete implementations and would be more understandable if both follow certain convention in their declaration.
There are even classes that implement more than one collection type like LinkedList which implements both List and Queue. However, there is one class at least that is a bit 'unconventional', the PriorityQueue. It extends AbstractQueue but doesn't explicitly implement Queue. Don't ask me why. :)
(reference is from Java 5 API)
Too late for answer?
I am taking a guess to validate my answer. Assume following code
HashMap extends AbstractMap (does not implement Map)
AbstractMap implements Map
Now Imagine some random guy came, Changed implements Map to some java.util.Map1 with exactly same set of methods as Map
In this situation there won't be any compilation error and jdk gets compiled (off course test will fail and catch this).
Now any client using HashMap as Map m= new HashMap() will start failing. This is much downstream.
Since both AbstractMap, Map etc comes from same product, hence this argument appears childish (which in all probability is. or may be not.), but think of a project where base class comes from a different jar/third party library etc. Then third party/different team can change their base implementation.
By implementing the "interface" in the Child class, as well, developer's try to make the class self sufficient, API breakage proof.
In my view,when a class implements an interface it has to implement all methods present in it(as by default they are public and abstract methods in an interface).
If we don't want to implement all methods of interface,it must be an abstract class.
So here if some methods are already implemented in some abstract class implementing particular interface and we have to extend functionality for other methods that have been unimplemented,we will need to implement original interface in our class again to get those remaining set of methods.It help in maintaining the contractual rules laid down by an interface.
It will result in rework if were to implement only interface and again overriding all methods with method definitions in our class.
I suppose there might be a different way to handle members of the set, the interface, even when supplying the default operation implementation does not serve as a one-size-fits-all. A circular Queue vs. LIFO Queue might both implement the same interface, but their specific operations will be implemented differently, right?
If you only had an abstract class you couldn't make a class of your own which inherits from another class too.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What does it mean to “program to an interface”?
I keep coming across this term:
Program to an interface.
What exactly does it mean? A real life design scenario would be highly appreciated.
To put it simply, instead of writing your classes in a way that says
I depend on this specific class to do my work
you write it in a way that says
I depend on any class that does this stuff to do my work.
The first example represents a class that depends on a specific concrete implementation to do its work. Inherently, that's not very flexible.
The second example represents a class written to an interface. It doesn't care what concrete object you use, it just cares that it implements certain behavior. This makes the class much more flexible, as it can be provided with any number of concrete implementations to do its work.
As an example, a particular class may need to perform some logging. If you write the class to depend on a TextFileLogger, the class is forever forced to write out its log records to a text file. If you want to change the behavior of the logging, you must change the class itself. The class is tightly coupled with its logger.
If, however, you write the class to depend on an ILogger interface, and then provide the class with a TextFileLogger, you will have accomplished the same thing, but with the added benefit of being much more flexible. You are able to provide any other type of ILogger at will, without changing the class itself. The class and its logger are now loosely coupled, and your class is much more flexible.
An interface is a collection of related methods, that only contains the signatures of those methods - not the actual implementation.
If a class implements an interface (class Car implements IDrivable) it has to provide code for all signatures defined in the interface.
Basic example:
You have to classes Car and Bike. Both implement the interface IDrivable:
interface IDrivable
{
void accelerate();
void brake();
}
class Car implements IDrivable
{
void accelerate()
{ System.out.println("Vroom"); }
void brake()
{ System.out.println("Queeeeek");}
}
class Bike implements IDrivable
{
void accelerate()
{ System.out.println("Rattle, Rattle, ..."); }
void brake()
{ System.out.println("..."); }
}
Now let's assume you have a collection of objects, that are all "drivable" (their classes all implement IDrivable):
List<IDrivable> vehicleList = new ArrayList<IDrivable>();
list.add(new Car());
list.add(new Car());
list.add(new Bike());
list.add(new Car());
list.add(new Bike());
list.add(new Bike());
If you now want to loop over that collection, you can rely on the fact, that every object in that collection implements accelerate():
for(IDrivable vehicle: vehicleList)
{
vehicle.accelerate(); //this could be a bike or a car, or anything that implements IDrivable
}
By calling that interface method you are not programming to an implementation but to an interface - a contract that ensures that the call target implements a certain functionality.
The same behavior could be achieved using inheritance, but deriving from a common base class results in tight coupling which can be avoided using interfaces.
Polymorphism depends on programming to an interface, not an implementation.
There are two benefits to manipulating objects solely in terms of the interface defined by abstract classes:
Clients remain unaware of the specific types of objects they use, as long as the objects adhere to the interface that clients expect.
Clients remain unaware of the classes that implement these objects. Clients only know about the abstract class(es) defining the interface.
This so greatly reduces implementation dependencies between subsystems that it leads to this principle of programming to an interface.
See the Factory Method pattern for further reasoning of this design.
Source: "Design Patterns: Elements of Reusable Object-Oriented Software" by G.O.F.
Also See: Factory Pattern. When to use factory methods?
Real-world examples are applenty. One of them:
For JDBC, you are using the interface java.sql.Connection. However, each JDBC driver provides its own implementation of Connection. You don't have to know anything about the particular implementation, because it conforms to the Connection interface.
Another one is from the java collections framework. There is a java.util.Collection interface, which defines size, add and remove methods (among many others). So you can use all types of collections interchangeably. Let's say you have the following:
public float calculateCoefficient(Collection collection) {
return collection.size() * something / somethingElse;
}
And two other methods that invoke this one. One of the other methods uses a LinkedList because it's more efficient for it's purposes, and the other uses a TreeSet.
Because both LinkedList and TreeSet implement the Collection interface, you can use only one method to perform the coefficient calculation. No need to duplicate your code.
And here comes the "program to an interface" - you don't care how exactly is the size() method implemented, you know that it should return the size of the collection - i.e. you have programmed to the Collection interface, rather than to LinkedList and TreeSet in particular.
But my advice is to find a reading - perhaps a book ("Thinking in Java" for example) - where the concept is explained in details.
Every object has an exposed interface. A collection has Add, Remove, At, etc. A socket may have Send, Receive, Close and so on.
Every object you can actually get a reference to has a concrete implementation of these interfaces.
Both of these things are obvious, however what is somewhat less obvious...
Your code shouldn't rely on the implementation details of an object, just its published interface.
If you take it to an extreme, you'd only code against Collection<T> and so on (rather than ArrayList<T>). More practically, just make sure you could swap in something conceptually identical without breaking your code.
To hammer out the Collection<T> example: you have a collection of something, you're actually using ArrayList<T> because why not. You should make sure you're code isn't going to break if, say, you end up using LinkedList<T> in the future.
"Programming to an interface" happens when you use libraries, other code you depend upon in your own code. Then, the way that other code represents itself to you, the method names, its parameters, return values etc make up the interface you have to program to. So it's about how you use third-party code.
It also means, you don't have to care about the internals of the code you depend on, as long as the interface stays the same, your code is safe (well, more or less...)
Technically there are finer details, like language concepts called "interfaces" in Java for example.
If you want to find out more, you could ask what "Implementing an Interface" means...
I think this is one of Erich Gamma's mantras. I can't find the first time he described it (before the GOF book), but you can see it discussed in an interview at: http://www.artima.com/lejava/articles/designprinciples.html
It basically means that the only part of the library which you're going to use you should rely upon is it's API (Application programming interface) and that you shouldn't base your application on the concrete implementation of the library.
eg. Supposed you have a library that gives you a stack. The class gives you a couple of methods. Let's say push, pop, isempty and top. You should write your application relying only on these. One way to violate this would be to peek inside and find out that the stack is implemented using an array of some kind so that if you pop from an empty stack, you'd get some kind of Index exception and to then catch this rather than to rely on the isempty method which the class provides. The former approach would fail if the library provider switched from using an array to using some kind of list while the latter would still work assuming that the provider kept his API still working.