November 14, 2012

Interfaces

My teacher keeps talking about interfaces and Coding To The Interface and extending interfaces and implementing interfaces and faces faces faces.  While I'm still confused.. I get that they're sort of abstract classes that tell what the class should do without implementation.  But why are they different from inheritance, why are they better, when should we use either, what is inheritance anyway?  I guess that's a topic for another day.

Okay..

So interfaces are basically what separates the outside world from actual implementation.  Like a car, you can control how fast it goes (gas pedal), how much it turns (steering wheel), and.. that's pretty much it.  You don't need to know anything else.  An interface is a set of requirements (I'm gonna be repeating myself a lot here because I'm reading from at least three different sources, and repetition really helps to solidify the concepts in my poor sleep-deprived brain)

Interfaces provide you the abstract view of a class without showing you how it's implemented - provide methods without bodies.  Here is an example:

interface Doggy {
   void bark (int annoyingFactor);

   void chaseTail (int sillyFactor);

   void vomitOnCarpet (int grossFactor);

   int Size();

   int Age();

We don't need to know how the Doggy barks.  It could be loud, soft, annoying, less annoying, all we know is it barks.  Same with chaseTail, Doggy could be really silly or just a little silly.  And for vomitOnCarpet, we don't need to know what was in the vomit or what made the Doggy vomit.  All we know is all Doggy(s) bark, chaseTail, and vomitOnCarpet.

To implement Doggy, name of class would change to a particular breed of dog, for example Sheltie, and use the implements keyword in the class declaration

class Sheltie implements Doggy {

   // implement Doggy as Sheltie

}

Interfaces are basically a CONTRACT between class and outside world, and the contract is enforced at compile time.  For a class to implement an interface, it must include all the methods in the interface.

And to repeat myself, note that interfaces do NOT contain method bodies.  They also cannot be instantiated.  Don't be silly and try to instantiate a Doggy.  Not gonna work.  Must write a class, Sheltie, or GoldenRetriever, or Rottweiler, that provides a method body for each of the methods declared in the interface (tells you how annoying the implemented Doggy's bark will be, or how silly its chaseTail will be, or how gross vomitOnCarpet will be).

Note that in Java, a class can only inherit from one class but can implement more than one interface.  So Sheltie can implement Doggy but can also implement beAnnoying and beCute

public interface Doggy extends beAnnoying, beCute{
   void barkLoudly (int decibels);

   void chaseTail (int hours);

   void vomitOnCarpet (int grossFactor);

   int Size();

   int Age();

public indicates that the interface can be used by any class in the package.  Thank goodness anyone can use Doggy.

Declared v. Dynamic types: a declared type is set at COMPILE time (by declaration).  Dynamic type is set at RUN time (by new).  If I understand this right, and if I'm applying what I learned from my linked list implementation correctly, a Declared type is an object declared on the Stack while a Dynamic type is something declared on the Heap.  So basically Dynamic types are more annoying to deal with than Declared types.
-- Also, interfaces cannot be Dynamic types!  You can't instantiate them, they must be Declared (ok that's where they tie in)
-- Because the compiler cannot guess Dynamic types
-- A declared type (interface) determines which members can be used
-- But the DECLARED type of a variable can be an interface
      -- Doggy dog; // good dog
      -- dog = new Doggy(); // bad dog (compile-time error)
-- Only classes can be instantiated directly, but variable of type X can refer to an instance of a class that implements X
      -- class Sheltie implements Doggy { ... }
      -- Doggy dog = new Sheltie(); // good dog
      -- It's a bit like widening

Simple Rule (from the cse slides): Interfaces can ONLY be used as declared types.  No dynamic types, no new, no instantiation
-- All dynamic types are classes, and all run-time objects are constructed from a class, not an interface

Good Practice: Code to Interface (this keeps coming up again in the slides):
-- "Coding to the interface" means ALL declared types are interface types
-- All variable declarations and field declarations use interface types
      -- Doggy dog = new Sheltie();
-- All argument and return types in method signatures are interface types

Oracle says that "When you define a new interface, you are defining a new reference data type."  So a new interface defines a new classification that determines possible values, allowable operations, meaning of the data, and the way values of that type can be stored.

public Dog isMoreAnnoying (Dog aDog, Dog anotherDog) {
   Doggy toby = (Doggy) aDog;
   Doggy lassie = (Doggy) anotherDog;

   if (toby.Age() < lassie.Age() )
      return aDog;

   else
      return anotherDog;
}

This is a method that returns the more annoying Doggy, for ANY Dog that is instantiated from a class that implements Doggy (don't know if this is right or not.. This is the part about interfaces that confuses me the most, including it in code)
- By casting aDog to a Doggy type, it can invoke the Age() method

If I can implement Doggy in a lot of classes, the objects instantiate from ANY of these classes can be compared with the Age() method, if both objects are of the same class.  This works for any "Doggy" objects, no matter class inheritance.  When Doggy is implemented, the objects can be of their own class and a Doggy type, so they can have behavior from both a superclass and an interface.

Rewriting Interfaces: Don't do it.  All classes that implement Doggy will break because they don't implement the interface anymore.  If I wanted to write a legit Doggy class, I'd want to anticipate as many uses as I can, and extend it when I think of other uses later.

Ugh still don't completely understand all the details but at least I understand it a little better than I did before