Featured

Polymorphism

Lets discuss something about Polymorphism.  In short it means many forms/shapes. It simply means using a common name/reference to work with different objects which can be identified with that common name/ reference.

Lets take a evergreen example of Shape. We have different shapes like Square, Circle, Rectangle etc. Now suppose we want to develop application which work with different shape.

So to start with we will develop classes..

class Rectangle {
  public void drawRectangle() {
   System.out.println("I am Rectangle..");
  }
}

class Square {
  public void drawRectangle() {
   System.out.println("I am Square.All have equal length. So fair :-)");
  }
}

Now in you application, you will have write the code as

public class ShapeApplication {
    public static void main(String[] args) {
        String type = args[0];
        if("Rectangle".equals(type)) {
            Rectangle rectangle = new Rectangle();
            rectangle.drawRectangle();
        }
        else if("Square".equals(type)) {
            Square square = new Square();
            square.drawSquare();
        }
    }
}

Now if you run the above application such as: Java ShapeApplication Square, you will get output as: “I am Square.All have equal length. So fair :-)”

So far so good. Now you are asked to handle Circle shape also. You will have to write new class for Circle. But only problem is you will have to modify the existing ShapeApplication class to handle Circle shape. What it means is  every time new type of Shape is introduced, you will have to modify existing working working application. Wouldn’t it be nice if you can handle any shape without modifying your Shape application. Sounds good..

So let’s start the journey to wonderful town called Polymorpshism. I believe this town gets visited by every developer every now and then..

Basically Square, Rectangle, Circle all are different kind of Shapes. Yes, each shape has its own specific behaviour, but still we can say basically these are all shapes &  their behaviour definition can be defined (in Java world we say method) in common super class or interface.  Okay we define interface called Shape which conceptually can represent all shapes.  What we want is that each object should draw its particular Shape. We can generalise method name as draw(). So lets code for polymorphism.

interface Shape {
    public void draw();
}

class Rectangle implements Shape{
    public void draw() {
        System.out.println("I am Rectangle..");
    }
}
class Square implements Shape {
    public void draw() {
        System.out.println("I am Square. I am so fair...all have equal length");
    }
}
class Circle implements Shape {
    public void draw() {
        System.out.println("I am Circle. No rough edges :-)");
    }

Now because we have come up with common class/interface for all types of shape, we can write a factory method which can return appropriate Shape for a specified input String

/**
 * Being a good developer, we will write Javadoc
 * Factory class which returns appropriate Shape object based on user specified string input
 */
public class ShapeFactory {

    public static Shape getShape(String shapeType){

        Shape shape = null;
        if("Rectangle".equals(shapeType)) {
            shape = new Rectangle();
        }
        else if("Square".equals(shapeType)) {
            shape = new Square();
        }
        else if("Circle".equals(shapeType)) {
            shape = new Circle();
        }
        return shape;
    }
}

Now we can rewrite the ShapeApplication as 

public class ShapeApplication {
    public static void main(String[] args) {
        String type = args[0];
        Shape shape = ShapeFactory.getShape(type);
        shape.draw();
    }
}

Now if you run the above application such as: Java ShapeApplication Circle, you will get output as: “I am Circle. No rough edges :-)”.

Now suppose a new Shape needs be handled say Triangle, we will have to just modify the factory method.

/**
 * Factory class which returns appropriate Shape object based on user specified string input
 */
public class ShapeFactory {

    public static Shape getShape(String shapeType){
        Shape shape = null;
        if("Rectangle".equals(shapeType)) {
            shape = new Rectangle();
        }
        else if("Square".equals(shapeType)) {
            shape = new Square();
        }
        else if("Circle".equals(shapeType)) {
            shape = new Circle();
        }
        else if("Triangle".equals(shapeType)) {
            shape = new Triangle();
        }
        return shape;
    }
}

But your existing ShapeApplication class will work with this new Shape type without any changes. In other words, the application (let’s say client application) which works with shape will be able to work with any new additional Shape objects as long as it conforms to Shape interface.

Excellent. Now the main point for which I really wanted to write about. Its here where I find many developers getting confused.

Now suppose a new functionality needs to be added to Circle class for rotating. Being super developer, we are more than happy to write new functionality. No problem. We will add rotate() method the Circle class (& not to other class) as it makes sense to Circle only.

class Circle implements Shape {

    public void draw() {
        System.out.println("I am Circle. No rough edges :-)");
    }
    public void rotate() {
        System.out.println("Its so wonderful to rotate ");
    }

}

Now lets say we write client application as:

Shape shape = new Circle()
shape.draw();
shape.rotate();

What will be the output? Most of the time, I get answers as:
I am Circle. No rough edges 🙂
Its so wonderful to rotate ..

shape.draw() –> yes this works fine. Circle’s draw() method gets called.
shape.rotate(); –> This won’t get compiled.

Even though object is of Circle type & certainly that method is available in that object, but you are using reference of Shape. Shape reference doesn’t have any knowledge about rotate method. It just knows whatever is defined in Shape interface.

Just to reiterate the point, analyse this line:
Shape shape = ShapeFactory.getShape(type);
Here we can get any Shape object. How Java can assume at at compile time that it is going to be Circle object? Even if that line was allowed to compile, question remains what should happen for call to rotate method if you get say Square object?

Each concrete shape class can have its own specific method which doesn’t not make sense for other shapes, we so we won’t be adding that method in Shape interface.  Think from users/client of the Shape functionality. They just the know the contract i.e. behaviour as defined in Shape interface. So you can say they are supposed to work with only those methods as defined in Shape interface. In case client application wants to use specific concrete class, they can cast the reference after checking the type:

if(shape instanceof  Circle) {
    Circle circle = (Circle1)shape;
    circle.rotate();
} 

Or if you say that method make sense for other shapes also, you can add that method to interface & have each concrete class implement it. 

Yes, as per polymorphism, object’s  specific method gets called. i.e  At runtime, which methods gets called depends on actual object.
But which method can be called in the first place depends on reference type. This is a very important concept. 

a new journey

I have been working in Java technology since 1999  and what an wonderful journey it has been. Java technology is so vast & ever growing that we need to keep on learning new thing almost every month (if not day 🙂 ).  I had learned BASIC, FORTRAN, COBOL, C, C++ during graduation, but my real & exciting journey started with learning Java. I still remember waiting to get hard copy of the book Complete Reference by by Patrick Naughton & Herbert Schildt. I really enjoyed learning from that book. But the book that got excited me the most & prepared me for wonderful journey into software development was ‘The Java Handbook’ by Patrick Naughton. It was mainly the appendix section where the author tells the story of how java language development got started. The author gives suggestions to the management after sending resignation, how management at Sun Microsystems took those suggestions in positive way, how small team starts working on a some goal, there joy of working with each other & frustrations during two years, how they wanted it to really come out,fear that it might not work & suddenly (like a bright sunny ray after long dark hours) some real practical usage of their hard work & then the joy that their work becoming one of the most successful language..Oh yes final success comes just after author leaves the company.. sounded like a emotional & gripping movie to me :-)..And after working in software development for so many years, I think I have also gone through all those phases…starting on new project, excitement, learning new things, working with colleagues of different temperament/nature, mistakes, frustrations, so called dead line pressure, success and many many more things…

Over these years Java technology has grown so big & it is getting bigger & more exciting. When I started learning core Java,  Servlets, JSP were the new things & EJB was the next big thing…Till I could learn all those things, some more new frameworks came & then …:-)  I could never  complete that race of learning everything in Java :-). But nevertheless I have learned many things & worked on many exciting projects.  Some times I really think when I would stop learning & take it easy at least for few days..but the joy of learning something new again brings me to this wonderful world called software development. As they say, grass is always greener on other side. Many times, I had to work on legacy applications & using the new framework was always out of question in those projects. So I had to always spend my free time in learning the next exciting thing :-).  But as they say, you can always take many positive things, working with legacy applications allows you to learn many things…smart workarounds, mistakes, refactoring, impact analysis…

I have always been a voracious book reader & still prefer the purchasing the books, that smell of new book, making plans for completing all things from book and humm…  many times as in life, not reaching to final goal :-).

But to be serious (oh no..I really think we should take life easy ), I have read, enjoyed and learned from many good books over the years. But during pressure times, deadlines (BTW …when these deadlines will really go out of this world & life will be simple?..let us all hope :-)) apart from books, as everyone do I have used internet, read blogs, gone through open source framework code base. And then there was strong sense that I should also share whatever I have learned…But being workaholic  (that is not a good habit though) & always busy with work, unfortunately that always took backseat. I have always enjoyed sharing whatever I learned with my colleagues (who almost always became my good friends).  So I had to really start my  first steps in blogging world to share with more friends…..At last I am happy that I have finally started my blog journey.

But already so much is available, what new I can bring…I really thought over that. I believe everyone has unique perspective on a given problem, task ..forget software. Even in everyday life, everyone reacts differently, lives in different way in in similar conditions..So I think, I can bring my perspective on the things that I have learned, the things that I have worked on, mistakes that I did,  the things that did in correct way….So as life is unpredictable and that’s why so interesting, I hope my journey in blog world will also be wonderful…So excited to share whatever little I know..