What are Abstract Classes & Interfaces?
An abstract class is a class which cannot be instantiated. This means that we cannot create Objects of abstract classes. An abstract method is a method without a body. Any class that has any abstract methods must be declared as abstract. There can be abstract classes without abstract methods.
Consider the following class:-
public class AbstractExample
{
public void f1();
}
On compiling, we get the following error:-
Let us declare the method as abstract.
public class AbstractExample
{
public abstract void f1();
}
The error message now changes, and it demands that the class be declared as abstract.
public abstract class AbstractExample
{
public abstract void f1();
}
Now the class Compiles successfully.
The class file has been generated:-
We shall develop a class AbstractExtend to extend the abstract class.
public class AbstractExtend extends AbstractExample
{
}
Try compiling:-
Either the current class should be declared abstract, or the abstract method has to be implemented.
We mark the new class as abstract:-
public abstract class AbstractExtend extends AbstractExample
{
}
The other alternative is to provide an implementation:-
public class AbstractExtend extends AbstractExample
{
public void f1()
{
System.out.println(“This is a method f1 in class AbstractExtend implementing an abstract method in abstract class AbstractExample”);
}
}
It compiles successfully:-
We add a main method:-
public class AbstractExtend extends AbstractExample
{
public void f1()
{
System.out.println(“This is a method f1 in class AbstractExtend implementing an abstract method in abstract class AbstractExample”);
}
public static void main(String[] args)
{
AbstractExample x1=new AbstractExample();
AbstractExample x2=new AbstractExtend();
AbstractExtend x3=new AbstractExample();
AbstractExtend x4=new AbstractExtend();
}
}
Try compiling:-
The abstract class cannot be instantiated.
comment the two above lines.
public class AbstractExtend extends AbstractExample
{
public void f1()
{
System.out.println(“This is a method f1 in class AbstractExtend implementing an abstract method in abstract class AbstractExample”);
}
public static void main(String[] args)
{
//AbstractExample x1=new AbstractExample();
AbstractExample x2=new AbstractExtend();
//AbstractExtend x3=new AbstractExample();
AbstractExtend x4=new AbstractExtend();
}
}
Try compiling:-
It now compiles.
Next we experiment by adding some new methods:-
public abstract class AbstractExample
{
public abstract void f1();
public void f2()
{
System.out.println(“This is a concrete method in class Abstract Example”);
}
public static void f3()
{
System.out.println(“This is a static concrete method in class Abstract Example”);
}
public static abstract void f4()
{
System.out.println(“This is a static abstract concrete method in class Abstract Example”);
}
}
The combination of static and abstract as used in method f4 is not allowed. We will remove it.
The class now compiles.
Next we will try to create a variable, a constant, a constructor, and an abstract constructor.
public abstract class AbstractExample
{
public int x1=10;
public final int x2=20;
public static int x3=30;
public static final int x4=40;
public abstract void f1();
public void f2()
{
System.out.println(“This is a concrete method in class Abstract Example”);
}
public static void f3()
{
System.out.println(“This is a static concrete method in class Abstract Example”);
}
}
This compiles successfully.
Thus instance variables, static variables, instance constants and static constants are all allowed in abstract classes.
Next we try to define a concrete constructor, next an abstract constructor.
public abstract class AbstractExample
{
public AbstractExample()
{
}
public void f2()
{
System.out.println(“This is a concrete method in class Abstract Example”);
}
public static void f3()
{
System.out.println(“This is a static concrete method in class Abstract Example”);
}
}
public abstract class AbstractExample
{
public abstract AbstractExample()
{
}
public void f2()
{
System.out.println(“This is a concrete method in class Abstract Example”);
}
public static void f3()
{
System.out.println(“This is a static concrete method in class Abstract Example”);
}
}
Abstract constructors are not allowed. Let us try the same things for finalize and toString.
public abstract class AbstractExample
{
public void f2()
{
System.out.println(“This is a concrete method in class Abstract Example”);
}
public static void f3()
{
System.out.println(“This is a static concrete method in class Abstract Example”);
}
public abstract void finalize();
public abstract String toString();
}
Try compiling:-
Success!!!. This means that barring the constructor and static methods , all other methods can be abstract. The toString is implemented in java.lang.Object and marked as abstract in a sub class. This means that methods which are concrete in a super class can be declared abstract in a sub class.
The following rules can be stated:-
- Abstract classes cannot be instantiated.
- Any class having at least one abstract method must be declared as abstract.
- Classes can be abstract without any abstract method.
- Abstract methods do not have a body.
- All classes that extend an abstract class must be either abstract or implement the abstract methods in the abstract class.
- Constructors and static methods cannot be abstract.
- Variables and constants, both static and instance are allowed.
- toString and finalize can be implemented both as abstract or concrete.
- Super class concrete methods can be made abstract in the sub class.
Now, we will develop a meaningful example:-
We will develop an abstract class called Figure and extend it into two classes Rectangle and Circle.
public abstract class Figure
{
public abstract double area();
public abstract double perimeter();
public double radiansToDegree(double radianvalue)
{
return (radianvalue*180)/Math.PI;
}
public double degreeToRadians(double degreevalue)
{
return (degreevalue*Math.PI)/180;
}
}
Next we develop the Circle and Rectangle classes.
public class Rectangle extends Figure
{
private double length,breadth;
public Rectangle(double length,double breadth)
{
this.length=length;
this.breadth=breadth;
}
public double area()
{
return length*breadth;
}
public double perimeter()
{
return 2*length + 2*breadth;
}
public double diagonal()
{
return Math.sqrt(length*length + breadth*breadth);
}
}
public class Circle extends Figure
{
private double radius;
public Circle(double radius)
{
this.radius=radius;
}
public double area()
{
return Math.PI*radius*radius;
}
public double perimeter()
{
return 2*Math.PI*radius;
}
public double diameter()
{
return 2*radius;
}
}
Compile everything:-
Success.
Now develop a class called AbstractUse.java and try to create Objects of the different classes:-
public class AbstractUse
{
public static void main(String[] args)
{
Figure f1=new Rectangle(3,4);
Figure f2=new Circle(7);
Rectangle r1=new Rectangle(3,4);
Circle c1=new Circle(7);
}
}
The compilation succeeds.
Now try calling the methods:-
public class AbstractUse
{
public static void main(String[] args)
{
Figure f1=new Rectangle(3,4);
Figure f2=new Circle(7);
Rectangle r1=new Rectangle(3,4);
Circle c1=new Circle(7);
System.out.println(f1.area());
System.out.println(f1.perimeter());
System.out.println(f1.degreeToRadians(180));
System.out.println(f1.diagonal());
System.out.println(r1.area());
System.out.println(r1.perimeter());
System.out.println(r1.degreeToRadians(180));
System.out.println(r1.diagonal());
}
}
The abstract class has no knowledge of the diagonal method. Comment it and run the class.
public class AbstractUse
{
public static void main(String[] args)
{
Figure f1=new Rectangle(3,4);
Figure f2=new Circle(7);
Rectangle r1=new Rectangle(3,4);
Circle c1=new Circle(7);
System.out.println(f1.area());
System.out.println(f1.perimeter());
System.out.println(f1.degreeToRadians(180));
//System.out.println(f1.diagonal());
System.out.println(r1.area());
System.out.println(r1.perimeter());
System.out.println(r1.degreeToRadians(180));
System.out.println(r1.diagonal());
}
}
Now run the class:-
Now try the same things for the Circle class.