Keywords

These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

Sometimes we start doing some work with an expectation that our incomplete work will be carried out by someone else. A real life example can be seen in case of properties purchases and modeling those. It is very common that many of our grandparents may bought some properties earlier, then our parents made a small house in that property and ultimately we give the house a larger shape or we redecorate the house. So basic idea is same: we want someone to continue and complete the incomplete work first. We give them freedom that upon completion, they can remodel as per their needs. The concepts of abstract class suits best in such type of scenarios in the programming world.

These are incomplete classes and we cannot instantiate objects from this type of classes. The child of those classes must complete them first and then they can redefine some of the methods (by overriding).

In general, if a class contains at least one incomplete/abstract method, the class itself is an abstract class. By the term “abstract method”- we mean that the method has the declaration (or signature) but no implementation.

The technique is useful when the super class can define a generalized form (that will be shared by its subclasses) and passes the responsibilities to fill the details to its subclasses.

Here is the implementation:

Demonstration-1

A simple abstract class demo

package abstractclasses.examples; abstract class MyAbstractClass {         public  abstract void showMe(); } class MyConcreteClass extends MyAbstractClass {         @Override         public void showMe()         {                 System.out.println("I am from concrete class:");                 System.out.println("I am supplying the method body for showMe()");         }         } class AbstractClassEx1 {         public static void main(String Args[])         {                 System.out.println("***Abstract class Demo***");                 //Illegal:Cannot instantiate                 //MyAbstractClass abstractOb=new MyAbstractClass();                 MyConcreteClass concreteOb=new MyConcreteClass();                 concreteOb.showMe();         } }

Output

figure a

An abstract class can contain concrete methods also. The child class may or may not override those methods.

Here is another implementation.

Demonstration-2

package abstractclasses.examples; abstract class AbstractClass {         public  abstract void showMe();         public void completeMethod1()         {                 System.out.println(" Originally,I am from completeMethod1 in MyAbstractClass.But,I am complete.");                 }         public void completeMethod2()         {                 System.out.println(" Originally,I am from  completeMethod2 in MyAbstractClass.But,I am also complete.");                 } } class ConcreteClass extends AbstractClass {         @Override         public void showMe()         {                 System.out.println("I am from concrete class:");                 System.out.println("I am supplying the method body for showMe()");         }         //It wants to override completeMethod1() in MyAbstractClass         public void completeMethod1()         {                 System.out.println("I am overriding completeMethod1 of MyAbstractClass.");                 } } class AbstractClassEx2 {         public static void main(String Args[])         {                 System.out.println("***Abstract class Demo2***");                 ConcreteClass concreteOb=new ConcreteClass();                 concreteOb.showMe();                 //It will show that completeMethod1 is redefined in MyConcreteClass.                 concreteOb.completeMethod1();                 //It will show the details of completeMethod2 defined in MyAbstractClass.                 concreteOb.completeMethod2();                 //Following declaration will be fine                 AbstractClass abstractRef=new ConcreteClass();                 abstractRef.completeMethod1();         } }

Output

figure b

Students ask:

Can we implement the concept of dynamic method dispatch here?

Yes. Following declaration will be perfectly fine and it can call CompleteMethod1 of the ConcreteClass.

through the below codes:

AbstractClass abstractRef=new ConcreteClass(); abstractRef.completeMethod1();

Students ask:

Can an abstract class contain fields?

Yes.

Following example will demonstrate how we can use the concept of dynamic method dispatch here. Also, the program will show that an abstract class contain fields.

Demonstration-3

package abstractclasses.examples; abstract class AbstractClass3 {         public int myInt=5;         public  abstract void showMe();         public void completeMethod1()         {                 System.out.println("I am originally from completeMethod1 in MyAbstractClass.But,I am complete.");                 }         } class ConcreteClass3 extends AbstractClass3 {         @Override         public void showMe()         {                 System.out.println("I am from concrete class:");                 System.out.println("I am supplying the method body for showMe()");         }         } class AbstractClassEx3 {         public static void main(String Args[])         {                 System.out.println("***Abstract class Demo3***");                 AbstractClass3 abstractRef=new ConcreteClass3();                 abstractRef.completeMethod1();                 System.out.println("myInt in AbstractClass3="+abstractRef.myInt);                         } }

Output

figure c

Students ask:

In the above example, the access modifier is public. Is it mandatory?

Teacher says: Not at all. We can use non-public access modifiers also. Later you’ll learn that it is one of the key differences with interfaces.

Students ask:

Suppose in a class we have 10+ methods and out of that only one is an abstract method. Still we need to mark the class as abstract?

Teacher says: Yes. If a class contains at least one abstract method, the class itself is abstract. You can think from a general point of view-an abstract keyword is used in a sense to represent the incompleteness. So, if your class contains one incomplete method, your class itself is incomplete and hence need to mark by the keyword abstract.

Note

So, the simple formula is: whenever your class has at least an abstract method, your class itself is an abstract class.

Teacher asks:

Now consider a reverse scenario. Suppose, you have marked your class abstract but there is no abstract method in it like this:

abstract class AbstractClass {         public void completeMethod1()         {                 System.out.println("A complete method");                 }         public void completeMethod2()         {                 System.out.println("Another complete method.");                 }         }

Can we compile the program?

Teacher says: Yes. Still it will compile but till this point, you cannot create object for this class.

Students ask:

So sir, how can we create objects from an abstract class?

Teacher says: We mentioned already that we cannot create objects from an abstract class.

Students ask:

Sir, it appears to me that an abstract class has virtually no use if it is not extended. Is the understanding correct?

Yes.

Students ask:

If a class extends an abstract class, it has to implement all the abstract methods.Is the understanding correct?

Teacher says: It may or may not implement all the abstract methods in the parent class. The simple formula is that if you want to create objects of a class, the class needs to be completed i.e. it should not contain any abstract methods. So, if the child class cannot provide implementation (i.e. body) of all the abstract methods, it should be marked again with the keyword abstract like the below example.

abstract class AbstractClass {         public abstract void inCompleteMethod1();         public abstract void inCompleteMethod2();         } abstract class child1 extends AbstractClass {         //Here our child class is implementing only one of the abstract methods.         //So, the class is abstract again.         @Override         public void inCompleteMethod1()         {                 System.out.println("Implementing the inCompleteMethod1()");                 }         }

Students ask:

A concrete class is a class which is not abstract-is the understanding correct?

Teacher says: Yes.

Students ask:

Can we tag a method with both abstract and final?

Teacher says: No. Just think, by declaring abstract, you want overriding and by declaring final, you want to prevent overriding. i.e. you cannot do both at the same time.

Quiz

Teacher asks:

Can you predict the output?

package abstractclasses.examples; class MyClassEx4 {         //Constructors cannot be final/abstract/static         abstract MyClassEx4()         {                 System.out.println("I am a no argument constructor");                         } } class ExperimentWithConstructorEx4 {         public static void main(String args[])         {                 System.out.println("*** Experiment with constructors  ***");                 System.out.println("***Question:Can construcors be abstract?  ***");                         MyClassEx4 myOb=new  MyClassEx4();         } }

Output

Compilation error .

figure d

Students ask:

Sir, why constructors cannot be abstract?

Teacher says: Think from a general point of view. The keyword abstract with a method is used to mean that the method will be overriding somewhere in a child class. But constructors cannot be overridden as per the language specification.

Quiz

Teacher asks:

Can you predict the output?

package abstractclasses.examples; abstract class MyAbstractClass {         public abstract void showMe();         } class MyConcreteClass extends MyAbstractClass {         @Override         protected void showMe()         {                 System.out.println("I am from concrete class:");                 System.out.println("I am supplying the method body for showMe()");         } } public class AbstractClassAccessModifierEx {         public static void main(String args[])         {                 MyAbstractClass myref=new MyConcreteClass();                 myref.showMe();         } }

Output

figure e

Note

We have 2 solutions to remove the problem. Either in the parent class, we use the modifier protected or in the child class, we can use the modifier public. Just think, if you are implementing dynamic method dispatch and suddenly at runtime you discover that you do not have enough visibility-Then what will happen? This will be a definite source of problem then.

Students ask:

Sir, what will happen if we do the reverse (i.e. using protected in parent class and public in child class in the above scenario)?

Teacher says: In this case, you are basically increasing the visibility, so there can be no issue in runtime like above. So, compiler will allow you to do this change and you will receive the following output:

figure f