Inheritance allows us to create general classes which can be
plugged to other classes by using an extends
keyword. Let us take a simple example to create classes for variety of
shapes.
public class Shape {
double dim1, dim2;
Shape(){}
Shape(double d1,
double d2){
dim1=d1;
dim2=d2;
}
void
setDim1(double d1){
dim1=d1;
}
void
setDim2(double d2){
dim2=d2;
}
double getDim1() {
return dim1;
}
double getDim2() {
return dim2;
}
void show() {
System.out.println(getDim1()+","+getDim2());
}
public void
calcArea(){
System.out.println("Cannot calculate Area : Shape Unknown");
}
}
Shape is a general class which can provide common
functionality to all types of Shape classes. Let us create a Rectangle Shape
public class Rectangle extends Shape{
Rectangle(double
d1, double d2) {
super(d1,d2);
}
Rectangle(){
}
public void
calcArea() {
System.out.println("area of rectangle is : "+dim1*dim2);
}
public void
showPerimeter(){
System.out.println("Perimeter = "+(2*(dim1+dim2)));
}
}
Let us create another shape, Triangle.
public class Triangle extends Shape{
Triangle(double
d1, double d2) {
super(d1,d2);
}
Triangle() {
}
public void
calcArea(){
System.out.println("area of traingle = "+(0.5*dim1*dim2));
}
public void
draw(){
System.out.println("draw Triangle will be implemented later");
}
}
Rectangle and Triangle classes override calcArea() method.
It makes sense to redefine calcArea(). Both, Rectangle and Triangle Shapes are
well defined and so are their functionalities. Let us create a ShapeTester class to test the functionality.
public class ShapeTester {
public static void
main(String[] args) {
Shape shape=
new Shape(20,50);
Rectangle
rectangle = new Rectangle(30,40);
Triangle
triangle = new Triangle(25,12);
shape.calcArea();
rectangle.calcArea();
triangle.calcArea();
}
}
run:
Cannot calculate Area : Shape Unknown
area of rect is : 1200.0
area of traingle = 150.0
calcArea() method is insignificant in Shape class. The
question is, when there is no well defined functionality for calcArea() method
in Shape class we can do two things :
First, we can remove the error message and leave the method
with null body.
public void
calcArea(){ }
If calcArea() is
null body method, it is misleading. When the method will be called nothing happens.
Second, we can remove the calcArea() method from the Shape
class. It seems to be a good alternative. But if we want to design a family of
classes with common behavior, where
every type of Shape is capable of calculating the area, depending on the Shape
type, we need to find another alternative to deal with the calcArea() method.
This is what we can do. We will create calcArea() method in Shape class without
any definition. Such a method is called an abstract method. When a class
contains one or more abstract methods, class must be declared abstract.
public abstract class Shape {
double dim1, dim2;
Shape(){}
Shape(double d1,
double d2){
dim1=d1;
dim2=d2;
}
void
setDim1(double d1){
dim1=d1;
}
void
setDim2(double d2){
dim2=d2;
}
double getDim1() {
return dim1;
}
double getDim2() {
return dim2;
}
void show() {
System.out.println(getDim1()+","+getDim2());
}
public abstract void
calcArea(){
System.out.println("Cannot calculate Area : Shape Unknown");
}
}
Shape class is abstract as it does not define all its
methods. An abstract class is incomplete and hence cannot be instantiated. It
can only be used as a super class. Any subclass of an abstract class needs to
override all the abstract methods in the super class to become a concrete
class. If subclass does not override all the abstract methods of its super
class(es), subclass remains as an abstract class and hence cannot be
instantiated. Abstract methods help to enforce certain functionality in the
subclasses. Sometime, even if we have a concrete class and we wish it to
be used only as a super class. We can create an abstract class, which does not
contain any abstract method. For example :
public class abstract Shape {
double dim1, dim2;
Shape(){}
Shape(double d1,
double d2){
dim1=d1;
dim2=d2;
}
void
setDim1(double d1){
dim1=d1;
}
void
setDim2(double d2){
dim2=d2;
}
double getDim1() {
return dim1;
}
double getDim2() {
return dim2;
}
void show() {
System.out.println(getDim1()+","+getDim2());
}
public void
calcArea(){
}
}
Now, although we have all the well defined or implemented
methods in Shape class, Shape class cannot be instantiated, as it is declared as
an abstract class. A class can be declared abstract if we wish to avoid
instantiating the class. Such a class can only be used for subclassing.
By Nancy
@ 1:55 am 12/30/2013
And what benefit you want to achieve by defining empty method in abstract class?
ReplyDeleteWhy not keep the method as abstract to ensure it is not produce misleading results when used later through child class or it should through an exception to indicate the calcArea from Shape is not supposed to be used at all.
We don't want to keep an empty method in the class, as it is misleading. It is not a good design. The alternative with a good design is to make method and eventually class as an abstract. It is better design and gives flexibility to implement instance related business logic
ReplyDelete