Showing posts with label Java. Show all posts
Showing posts with label Java. Show all posts

Sunday, 27 March 2011

Multiple Inheritances in java and the controversy


In my early bachelor's degree when I was starting to begin familiar with languages like C and C++, Our teachers use to point us to this unique problem of multiple inheritance and how it causes ambiguity in the inherited class, the solution was to use virtual functions/inheritance, it seem to be a fix that was added to C++ as it was not thought earlier while designing the C++ language.

Later during my master's degree, this new language called "java" starting to pick up waves and I was kind of impressed with it earlier being a new language and always wanted to explore it. I remembered how C++ solved the problem of multiple inheritances, and was curious of how java would play with it.

Most of them believe that multiple inheritances are possible in java through java interface. However I have a difference in opinion here.

According to me inheritance is

  • Inheriting the implementation
  • Inheriting the declarations

Inheritance of implementation is inheriting the actual code that does the work when the method is called which is done in case of C++ multiple inheritance and which is not possible to do in case of java

Inheriting only the method declaration and variables for one or many such classes for which the implementation will be written in its subclass is called inheritance of interfaces which is a bit different from the concept of multiple inheritances and it’s only possible in java. An interface defines all of those methods that an object exposes to either its subclasses or other classes.

When you inherit from a class in Java you get both inheritance of interface and implementation. All methods in the super class become part of the subclass's interface. However, when you implement an interface you only inherit interface and must provide implementations for each method.

When a Java class implements multiple interfaces you do run the risk of naming clashes. A class can implement two interfaces that share the same method name and return type. Say for example you have the following interfaces:

public interface MyFirstInterface{
                public void myFirstMethod();
}
public interface MySecoundInterface{
                public void myFirstMethod();
}

A class called MyFirstInheritance can come and implement these two interfaces at the same time without difficulty. However there may be a problem. Chances are if this happens the resulting class with not be able to provide an implementation that satisfies the expected behavior of both the interfaces at the same time. Even if you go ahead and provide and implementation for myFirstMethod() this may not make sense if you simply view the object as an MyFirstInterface or MySecoundInterface.

So what's the solution? If you have access to the source code the best course of action is to rename the methods in either of the above cases. If you don't have access, you are stuck.

Tuesday, 15 March 2011

Java design Techniques – Using Interfaces Part – 2


This article will talk more about role of interfaces and its usage while choosing between multiple inheritance and composition in your design I personally believe multiple inheritance implementations is basically inflexible. And this inflexibility maps directly to the inflexibility of inheritance as compared to composition.

By composition, I simply mean using instance variables that are references to other objects. For example, in the following code, class Apple is related to class Fruit by composition, because Apple has an instance variable that holds a reference to a Fruit object:

class Fruit {

    //...
}

class Apple {

    private Fruit fruit = new Fruit();
    //...
}

In this example, Apple is the front-end class and Fruit is the back-end class. In a composition relationship as a thumb rule, the front-end class always holds a reference in one of its instance variables to its back-end class.
Composition usually yields more flexible code. I identified the following flexibility advantages for composition:
  • It's easier to change classes involved in a composition relationship than it is to change classes involved in an inheritance relationship.
  • Composition allows you to delay the creation of back-end objects unless they're needed. It also allows you to change the back-end objects dynamically throughout the lifetime of the front-end object. However with inheritance this is not true, you get the image of the super class in your subclass object image as soon as the subclass is created, and it remains part of the subclass object throughout the lifetime of the subclass.
The one flexibility advantage I identified for inheritance was:
  • It's easier to add new subclasses (inheritance) than it is to add new front-end classes (composition), because inheritance comes with polymorphism. If you have a bit of code that relies only on a super class interface, that code can work with a new subclass without change. This isn't true for composition, unless you use composition with interfaces.
In this above flexibility comparison, however, inheritance is not as secure as it might seem given its polymorphism advantage. That last clause above, "unless you use composition with interfaces," is very important. Basically, thanks to interfaces. Here's an example:

interface Peelable {

    int peel();
}

class Fruit {

    // Return int number of pieces of peel that
    // resulted from the peeling activity.
    public int peel() {

        System.out.println("Peeling is appealing.");
        return 1;
    }
}

class Apple implements Peelable {

    private Fruit fruit = new Fruit();

    public int peel() {
        return fruit.peel();
    }
}

class FoodProcessor {

    static void peelAnItem(Peelable item) {
        item.peel();
    }
}

class Example {

    public static void main(String[] args) {

        Apple apple = new Apple();
        FoodProcessor.peelAnItem(apple);
    }
}
Given the above set of classes, you could later define a class Banana like this:

class Banana implements Peelable {

    private Fruit fruit = new Fruit();

    public int peel() {
        return fruit.peel();
    }
}

Like Apple, class Banana has a composition relationship with Fruit. It reuses Fruit's implementation of peel() by explicit delegation: it invokes peel() on its own Fruitobject. But a Banana object can still be passed to the peelAnItem() method of class FoodProcessor, because Banana implements the Peelable interface.

As this example illustrates, interfaces allow you to get the best of both worlds. You get the flexibility of composition and the flexibility of polymorphism in one design.