Polymorphism, Inheritance, Overriding, Object type Casting
Code
Lab Objective: In this lab, we will demonstrate how to achieve Polymorphism using Inheritance, Overriding, Object Type Casting, Encapsulation, and instanceOF objects. One of the key features of Inheritance is that a reference variable (Object) of a superclass type can point to an object of its subclass. Polymorphism is the art of taking advantage of this simple but powerful and versatile feature.
Consider the following illustration:
Suppose that our program uses many kinds of Shapes, such as triangles, rectangles, and so on. We should design a superclass called Shape, which defines the public (common) behaviors of all the shapes. For example, we would like all the shapes to have a method called getArea(), which returns the area of that particular shape.
For the demonstration, we will use both constructors and the setter methods for value initialization.
Step 1:
Create a class named Shape. This will be a Super or Parent class. Write the code below:
publicclassShape {privateString color;protecteddouble area =1.0;protecteddouble base =1.0;protecteddouble width =1.0;protecteddouble height =1.0; /** Constructs a Shape instance with only the given color */publicShape (String color) {this.color= color; }publicShape() { } /** Constructs a Shape instance with the given values */publicShape(String color,double area,double base,double width,double height) {this.color= color;this.area= area;this.base= base;this.width= width;this.height= height; }publicvoidsetColor(String color) {this.color= color; }publicvoidsetArea(double area) {this.area= area; }publicvoidsetBase(double base) {this.base= base; }publicvoidsetWidth(double width) {this.width= width; }publicvoidsetHeight(double height) {this.height= height; } /** Returns a self-descriptive string */ @OverridepublicStringtoString() {return"Shape[color="+ color +"]"; } /** All shapes must provide a method called getArea() */publicdoublegetArea() {// We have a problem here!// We need to return some value to compile the program.System.out.println("Shape unknown! Cannot compute area!");return0; }publicvoiddisplayshapName() {System.out.println("I am a Shape."); }}
Step 2:
Create a class named Circle . This will be a Child class. Write the code below:
publicclassCircleextendsShape {protecteddouble radius;privatefinaldouble PI =Math.PI;publicCircle(double radius) {this.radius= radius; }publicCircle(double radius,double height) {this.radius= radius; super.height= height; }publicdoublegetArea() {//double area = PI * this.radius * this.radius; super.area= PI *Math.pow(this.radius,2); // initializing value in parent class variablereturn super.area; //reference to parent class variable } @OverridepublicvoiddisplayshapName() {System.out.println("Drawing a Circle of radius "+this.radius);} /** Returns a self-descriptive string */ @OverridepublicStringtoString() {return"Circle[ radius = "+ radius + super.toString() +"]"; }}
Step 3:
Create a class named Rectangle. This will be a Child class. Write the code below:
publicclassRectangleextendsShape {publicRectangle(String color) { super(color); }publicRectangle() { }publicRectangle(String color,double area,double base,double width,double height) { super(color, area, base, width, height); } @OverridepublicvoidsetBase(double base) { super.base= base; } @OverridepublicvoidsetWidth(double width) { super.width= width; } @OverridepublicdoublegetArea() {return width * height; }publicdoubleperimeter() { super.area= super.width* super.height;return super.area; }//Overriding method of base class with different implementation @OverridepublicvoiddisplayshapName() {System.out.println("I am a Rectangle" ); } /** Returns a self-descriptive string */ @OverridepublicStringtoString() {return"Rectangle[height="+ height +",width="+ width +","+ super.toString() +"]"; }}
Step 4:
Create a class named Triangle. This will be a Child class. Write the code below:
publicclassTriangleextendsShape {publicTriangle(){}publicTriangle(String color,double area,double base,double width,double height) { super(color, area, base, width, height); }publicTriangle(String color) { super(color); } @OverridepublicvoidsetBase(double base) { super.base= base; } @OverridepublicvoidsetWidth(double width) { super.width= width; } @OverridepublicdoublegetArea() {return0.5*base*height; }//Overriding method of base class with different implementation @OverridepublicvoiddisplayshapName() {System.out.println("I am a TriAngle" ); } /** Returns a self-descriptive string */ @OverridepublicStringtoString() {return"Triangle[base="+ base +",height="+ height +","+ super.toString() +"]"; }}
Step 5:
Create a class named Cylinder. This will be a Child class of the Circle class. Write the code below:
publicclassCylinderextendsCircle {privatefinaldouble PI =Math.PI ;publicCylinder(double radius,double height) { super(radius, height);// TODO Auto-generated constructor stub }publicCylinder(double radius) { super(radius); } /** Returns the volume of this cylinder */publicdoublegetVolumne() {return (PI*Math.pow(super.radius,2)) * super.height; }publicdoublegetSurfaceArea() {return2.0*Math.PI*super.radius*super.height; } @OverridepublicvoiddisplayshapName() {System.out.println("Drawing a Cylinder for radius "+ super.radius); }publicStringtoString() {return"radius is: "+ super.radius+"height is : "+ super.height; }}
Step 6:
Create a class named myRunner. This will be the Main Class or entry point for the application. Write the code below:
publicclassmyRunner {publicstaticvoidmain(String[] args) {Circle c =newCircle(100);System.out.println("Area of Circle "+c.getArea());// Example of Object type casting// declaration of object variable obj of the Shape class// Shape sObj ; // object creation of the Shape classShape sObj =newShape();sObj.displayshapName();System.out.println(sObj instanceof Shape); // true// object creation of the Circle classSystem.out.println("+++++++++");// it’s fine because a Circle is a Shape by inheritanceShape shapeCircleObj =newCircle(100); // UpCastingshapeCircleObj.displayshapName();System.out.println("Area of Circle "+shapeCircleObj.getArea());System.out.println(shapeCircleObj); // Run circle's toString()// Use instanceof operator for ValidationSystem.out.println(shapeCircleObj instanceof Circle); // trueSystem.out.println(sObj instanceof Circle); // false because Shape is not a CircleSystem.out.println("--------------------");Shape shapeRectangleObj =newRectangle("Red"); //UpCastingshapeRectangleObj.displayshapName();shapeRectangleObj.setHeight(2);shapeRectangleObj.setWidth(2);System.out.println("Area of Rectangle is "+shapeRectangleObj.getArea());System.out.println(shapeRectangleObj); // Run Rectangle's toString()// Use instanceof operator for ValidationSystem.out.println(shapeRectangleObj instanceof Rectangle); // trueSystem.out.println(sObj instanceof Rectangle); // false because Shape is not a RectangleSystem.out.println("--------------------");Shape shapeTriangleObj =newTriangle("Blue"); //UpCastingshapeTriangleObj.displayshapName();shapeTriangleObj.setHeight(2);shapeTriangleObj.setBase(3);System.out.println("Area of Triangle is "+shapeTriangleObj.getArea());System.out.println(shapeTriangleObj); // Run Triangle's toString()// Use instanceof operator for ValidationSystem.out.println(shapeTriangleObj instanceof Triangle); // trueSystem.out.println(sObj instanceof Triangle); // false because Shape is not a TriangleSystem.out.println("--------------------");Cylinder cylinderShape =newCylinder(3); //UpCastingcylinderShape.displayshapName();cylinderShape.setHeight(3);System.out.println("Area of Cylinder is "+cylinderShape.getVolumne());System.out.println(cylinderShape); // Run cylinderShape's toString() }}
In the above example, we have created objects of the Shape class: sObj, shapeCircleObj, shapeRectangleObj, and shapeTriangleObj. These objects are polymorphic variables.
We can summarize this by stating that Superclass reference variables are polymorphic reference variables. They can refer to objects of their own class or objects of the subclasses inherited from their class.
The instanceof operator is a Boolean operator that tests whether an object belongs to a given class.