You already know about classes, and inheritance. Suppose you had two completely separate classes, in different inheritance hierarchies. Let's call them Customer and CreditCard. Both of these have addresses. Some customers may have multiple credit cards, some of which may have different billing addresses - guys don't want the bills for their mistress's credit cards sent to their home address, for example.
C#, VB.NET, and Java only allow single inheritance, and Customer and CreditCard are quite different objects, so we don't want to have them both inheriting from the same superclass just so that we can capitalise on the shared behaviour in address handling.
By using an interface, we can specify a contract that describes the name and signature of one or more methods, with the expected results. In our case, we can create an interface IAddress with a method getAddress() that always returns an address.
We then make both classes implement IAddress. They both have a method getAddress() that returns an address object. But they might implement this in completely different ways. The underlying data may even be on different machines around the globe. The Customer object might simply return the address, but the CreditCard may check to see if it has a billing address. If so, it returns it, but if not, it could ask the associated Customer object for its address, and return that instead.
What does this buy us? Well, any object that implements IAddress can be treated as an IAddress object. So we could put a number of Customer and CreditCard objects into a collection, and iterate over them as if they were all IAddress objects, as long as we only want to ask them for their addresses. This allows us to treat objects from different parts of the hierarchy as if they were the same, without having to have a really deep and complex hierarchy which is difficult to extend and maintain. We can loosen up our hierarchy, as the interface allows use to specify what needs to be done, without having to specify which objects will actually be doing it at run time. As long as they keep to the contract, everything is fine.
If you subsequently need to branch out into InsurancePolicy, you can add a new class for it, implement IAddress, and any existing code that uses IAddress objects can work with your insurance policies too.
Because a class can implement a number of interfaces, this gives you the possibility to simulate multiple inheritance a la C++ without all the problems that go with it.
Sorry about the length of the post...