Subscribe to Stuck in an Infiniteloop        RSS Feed
-----

Java Interfaces and OOP Relationships

Icon Leave Comment
To avoid any sense of bias in what I'm about to present, I will be substantiating every assertion I make with quotes directly from the interface portion(s) of Sun's The Java Tutorials. I can think of no better source from which to learn or verify information then the creators themselves (ask any C++ programmer worth his/her salt and they'll tell you they have Bjarne Stroustrup's book on their shelf). But I digress...

Java Interfaces

Definition: An interface is a reference type, similar to a class, that can contain only constants, method signatures, and nested types. There are no method implementations (bodies). They cannot be instantiated. They can only be implemented by classes and extended by other interfaces. (reference)

Uses: Interfaces can be used as types, as APIs, to simulate multiple inheritance, and generally act as controllers/definers of class/object behavior. (reference)

A Brief Incursion into OOP

Object Oriented Programming is all about relationships. How does this Object interact with this Object? What data is shared?, it is encapsulated?, so on and so forth. Two fundamental concepts are Inheritance and Polymorphism.

Inheritance:

The two major relationships in inheritance are IS-A and HAS-A.

IS-A: is-a is a relationship where a class is a subclass of another class. For example:

public class Fruit{
}

public class Apple extends Fruit{
}



Apple IS A Fruit. Ways to describe the relationship include: Apple is a special kind of fruit. Fruit is a generalization of Apple. Apple may inherit Fruit qualities. (It could also override and follow other paths[think of Tomatoes], but for the purpose of this discussion, it is a "standard" Fruit).

HAS-A: has-a is a relationship where one object "belongs" to another. Depending on whether it is destroyed when its owner is is the difference between composition and aggregation, but that is beyond the scope of what I want to cover today. In layman's terms, an object is a data member of another object:

public class Car{
	private Engine engine;
	//do stuff with the engine, like start()
}

public class Engine{
}



Ways to describe the relationship: A Car HAS A Engine. An Engine is part of a Car, so on and so forth.

Polymorphism:

Where inheritance is a relationship between implementations, polymorphism is relationship between types. It is used for objects to act based on their implementation during run time/on the fly. For example, having a base class point to a derived class will result in the correct behavior called (the derived class):

public class Employee {
	public Employee() {}
	public void pay() {System.out.println("Employee pay");}
}

//derived class
public class Janitor extends Employee {
	public Janitor() {}
	public void pay() {System.out.println("Janitor Pay");}
}

public static void main(String[] args){
	Employee bob = new Janitor();
	bob.pay(); //Janitor behavior called
}



Quote

In strongly typed languages, polymorphism usually means that type A somehow derives from type B, or type A implements an interface that represents type B. In weakly typed languages types are implicitly polymorphic.



Back To Interfaces

Where could this OOP information be helpful?

from the beginning of this post said:

An interface is a reference type


Thus, java interfaces allow polymorphic relationships among implementations. Classes that implement interfaces inherit nothing from the interface, how can they as interfaces contain nothing but a set of method signatures and constants at most? There is no basic functionality to inherit. The interface provides a way to behave. When a bunch of otherwise unrelated objects implement the same interface, they have an instant connection (which is incredibly useful in some situations).

Quote

In principle, the object types may be unrelated, but since they share a common interface, they are often implemented as subclasses of the same superclass. Though it is not required, it is understood that the different methods will also produce similar results (for example, returning values of the same type).


In Java's case, multiple inheritance is not allowed (explicitly) so interfaces are a way to work it in. I imagine this is where some of the confusion lies. Even when used in that manner there is no IS-A relationship between the class and interface. Consider the following:

public interface Payable {
	public void pay();  
}

public class Employee implements Payable {
	public Employee() {}
	public void pay() {System.out.println("Employee pay");}
}

public class Janitor extends Employee {
	public Janitor() {} 
	public void pay() {System.out.println("Janitor Pay");}
}

public static void main(String[] args){
	   Employee emp = new Employee(); //standard way of doing it
	   emp.pay();
	   
	   Payable emp2 = new Employee(); //polymorphism
	   emp2.pay();
	   	
	   Employee bob = new Janitor();//explicit use of inheritance/polymorphism
	   bob.pay();
}



Employees are able to be paid, so they implement the Payable interface. Janitors are a type of Employee. In the main method, I create an Employee object three times. The first is your run of the mill object instantiation, the type is exactly what the class is. The second uses the interface as a type (perfectly legal in Java) to create an Employee object. The third is using a base class type to point at a derived class. The output:

Quote

Employee pay
Employee pay
Janitor Pay


To explicitly show there is no IS-A relationship, let's get rid of the interface.

//no more interface 

public class Employee {
	public Employee() {}
	public void pay() {System.out.println("Employee pay");}
}

public class Janitor extends Employee {
	public Janitor() {} 
	public void pay() {System.out.println("Janitor Pay");}
}

public static void main(String[] args){
	   Employee emp = new Employee(); //ok
	   emp.pay();
	   	   	
	   Employee bob = new Janitor();//ok
	   bob.pay();
}



Note that Employee and Janitor are still fully functional. what have they lost from the removal of the interface? Nothing. They still have all their methods. They did not inherit, receive, or in any way obtain information from the interface. What did they get? They got a method pay() that they have to override. Now that it's gone, we have lost a way to collectively identify those various objects that implement it. That is all.


Let's look at an example from my multiple inheritance tutorial in java:

//Base class
public class Animal {

	protected int age;
	protected String name;

	public Animal()			 {}
   
	public String getName()		{return name;}
	public int getAge()			{return age;}			
}


public interface Bird {
	//all implementers have to overwrite methods
	void birdNoise();
}

public interface Horse {
	//all implementers have to overwrite methods
	void horseNoise();
}


public class Pegasus extends Animal implements Bird, Horse {
	public Pegasus(String n, int a)
	{
		name = n;
		age = a;
	}
   
	//overriding interface methods
	public void horseNoise()
	{
		System.out.println("Horse Noise!");
	}
   
	public void birdNoise()
	{
		System.out.println("Bird Noise!");
	}
   
   
	public static void main(String[] args)
	{
		Pegasus peggi = new Pegasus("Pegasus", 5);
		System.out.println(peggi.getName() + "'s age is " + peggi.getAge());
		peggi.birdNoise();
		peggi.horseNoise();
	}
}



Pegasus IS-A animal. It has bird and horse qualities. In other languages we could have Bird and Horse inherit Animal and then have Pegasus inherit both of them, but that often results in the infamous "diamond" inheritance problem. Since that is illegal in Java anyway, I create two interfaces, one that represents things Birds and do and another that represents what Horses can do.

If this object only implemented a single interface, I could call it a Bird or Horse, but Pegasus is a hybrid of both. Thus, using the interface as a reference type in this context violates common sense.


In conclusion:

Inheritance is used to model real world relationships as well as attempt to maximize code reuse (if they all are similar, why type it three times, etc...). Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. Interfaces are used to encode similarities which classes of various types share, but do not necessarily constitute a class relationship. (reference)


In cases where you would use a interface type as a handler for objects, you would most likely [well, I would] utilize Generics to define what type of class implementations the function(s) should be expecting. But that is another post for another day. Happy Coding!

0 Comments On This Entry

 

January 2022

S M T W T F S
      1
2345678
9101112131415
161718192021 22
23242526272829
3031     

Tags

    Recent Entries

    Recent Comments

    Search My Blog

    18 user(s) viewing

    18 Guests
    0 member(s)
    0 anonymous member(s)