Abstract Class in java

Introduction:

Abstract classes in Java provide a way to design blueprints for classes. you can create new classes by using that blueprint. Abstract classes can contain rules (methods) that other classes must follow. They can also have their own properties and behaviors.

Java abstract class is a class that can not be initiated by itself, which means you can’t create object of abstract class it needs to be sub classed by other classes to use its properties.

Abstract is a mechanism to achieve abstraction in java. we can achieve 0 to 100 % abstraction in java by using abstract classes. because it both have complete and incomplete method body.

Abstract class Syntax in Java:

An abstract class in Java is one that is declared with the abstract keyword. It may have both abstract and non-abstract methods(methods with bodies)

abstract class MyAbstractClass {
    // Abstract method (no method body)
    abstract void myAbstractMethod();
    
    // Regular method with a method body
    void myRegularMethod() {
        // Method implementation
    }
}

When to Use an Abstract Class:

Shared Base Implementation: If you have a group of similar classes that do similar data, you can use an abstract class as a starting point or blueprint for creating other classes.. It has common methods and stuff they all use. Then, each class can change or add things as they want.

Partial Implementation: Abstract classes can provide both concrete (implemented) methods and abstract (unimplemented) methods within the same class. This means you can define default behavior in the abstract class and leave some methods to be implemented by its subclasses.

Shared Information: If different kinds of classes use the same data, an abstract class can hold that data and give ways to work with it. But interfaces can’t do this.”

Method Overriding: When you want to provide default behavior in some methods but require subclasses to override others, abstract classes offer a way to achieve this combination of shared and specialized behavior.

Future Expansion: Abstract classes can be extended with new methods or fields without immediately breaking existing subclasses. which is helpful when you expect your classes to grow and change over time.

Code Reusability: By providing a common implementation, abstract classes enable code reusability across subclasses, reducing duplication and promoting better maintenance.

Rules of Using Abstract Class:

  • You cannot directly create an instance of an abstract class, you can use a subclass instance to indirectly access the abstract class’s behavior through inheritance and method overriding
// Abstract class
abstract class MyAbstractClass {
    abstract void myAbstractMethod();
}

// Concrete class extending the abstract class
class MyConcreteClass extends MyAbstractClass {
    void myAbstractMethod() {
        System.out.println("Concrete class: myAbstractMethod() called");
    }
}

// Main class
public class Main {

    public static void main(String args[]) {

        // You can't directly create an instance of an abstract class.
        // The line below will result in an error during compilation.
        // MyAbstractClass abs = new MyAbstractClass();
        // But you can create a reference of the abstract class type
        // and assign it an instance of a concrete subclass.
        MyAbstractClass abs = new MyConcreteClass();
        abs.myAbstractMethod();  // This calls the overridden method in the concrete class.
    }
}

Concrete class: myAbstractMethod() called

  • Abstract class can have its own constructor, and when a concrete subclass is instantiated, the constructor chain involves calling the abstract class constructor first and then the concrete subclass constructor..
// Abstract class
abstract class MyAbstract {

    // Constructor of the abstract class
    MyAbstract() {
        System.out.println("Abstract Constructor Called");
    }

    // Abstract method inside the abstract class
    abstract void myAbstractMethod();
}

// Concrete class extending the abstract class
class MyConcrete extends MyAbstract {

    // Constructor of the concrete class
    MyConcrete() {
        System.out.println("Concrete Constructor Called");
    }

    // Implementation of the abstract method from the base class
    void myAbstractMethod() {
        System.out.println("Concrete myAbstractMethod() called");
    }
}
// Main class
public class Main {

    // Main driver method
    public static void main(String args[]) {
        // Creating an object of the concrete class inside main() method
        MyConcrete concreteObj = new MyConcrete();
        concreteObj.myAbstractMethod();
    }
}

Abstract Constructor Called
Concrete Constructor Called
Concrete myAbstractMethod() called

  • We can have an abstract class without any abstract method. it help us to create classes that cannot be instantiated but can only be inherited.
// An abstract class without any abstract method
abstract class MyBase {
    // Demo method. This is not an abstract method.
    void show() {
        System.out.println("Function of MyBase class is called");
    }
}

// A class inheriting from MyBase
class MyDerived extends MyBase {
    // This class only inherits the methods and properties of MyBase
}

// Main class
public class Main {

    // Main driver method
    public static void main(String args[]) {
        // Creating an object of MyDerived class
        MyDerived derivedObj = new MyDerived();

        // Calling the method from MyBase using an object of MyDerived
        derivedObj.show();
    }
}

Function of MyBase class is called

  • final method declared within an abstract class cannot be overridden by any subclass. Subclasses inherit the final method and can use it as-is but are not allowed to change its behavior
// Abstract class
abstract class MyAbstract {

    // Final method inside the abstract class
    final void myFinalMethod() {
        System.out.println("Abstract final method called");
    }
}

// Concrete class extending the abstract class
class MyDerived extends MyAbstract {
    // No new methods or properties added in this class
}

// Main class
public class Main {

    // Main driver method
    public static void main(String args[]) {
        // Creating an object of the abstract class
        MyAbstract myObj = new MyDerived();

        // Calling the final method on the object inside the main method
        myObj.myFinalMethod();
    }
}

Abstract final method called

  • Abstract java class we are not allowed to create an object for any abstract class instantiation is not possible. it will give compilation error.
// Main class
// An abstract class
abstract class MyBase {

    // Main driver method
    public static void main(String args[]) {

        // Trying to create an object
        MyBase myBase = new MyBase();
    }
}

Compilation Error

  • You can define static methods in an abstract class, and these methods can be called without needing to create an object of the class.
// Abstract class
abstract class MyAbstract {

    // Static method inside the abstract class
    static void myStaticMethod() {
        System.out.println("java tech point");
    }
}

// Main class extending MyAbstract
public class Main extends MyAbstract {

    // Main driver method
    public static void main(String[] args) {

        // Calling the static method from MyAbstract inside the main() method
        MyAbstract.myStaticMethod();
    }
}

java tech point

  • You can declare abstract inner classes within abstract outer classes. When an outer class is extended and an inner class is implemented, the inner class should provide concrete implementations for the abstract methods defined in the abstract inner class.

abstract class MyAbstractBase {
	// Declaring inner class as abstract with abstract method
	abstract class MyInnerAbstract {
		abstract void myInnerAbstractMethod();
	}
}

class MyDerived extends MyAbstractBase {
	class MyInnerDerived extends MyInnerAbstract {
		// Implementing the abstract method
		void myInnerAbstractMethod() {
			System.out.println(
				"Inside inner abstract method implementation");
		}
	}
}

public class MyMainClass {
	public static void main(String args[]) {
		// Instantiating the outer class
		MyDerived outer = new MyDerived();

		// Instantiating the inner class
		MyDerived.MyInnerDerived inner = outer.new MyInnerDerived();
		inner.myInnerAbstractMethod();
	}
}


Inside inner abstract method implementation

  • If a class contains at least one abstract method, it is indeed necessary to declare the class as abstract. otherwise we will get a compile-time error.

// If we remove the abstract keyword here, 
// we will get a compile time error due to the abstract method
abstract class MyAbstract {
    abstract void myMethod();
}

class MyChild extends MyAbstract {
    public void myMethod() {
        System.out.print("Hello");
    }
}

public class MyMain {
    public static void main(String[] args) {
        MyChild c = new MyChild();
        c.myMethod();
    }
}

Hello

  • We should declare that Child class as abstract if If the Child class is unable to provide implementation to all abstract methods of the Parent class so that the next level Child class should provide implementation to the remaining abstract method.

abstract class BaseDemo {
    abstract void baseMethod1();
    abstract void baseMethod2();
    abstract void baseMethod3();
}

abstract class FirstDerived extends BaseDemo {
    public void baseMethod1() {
        System.out.println("Inside baseMethod1");
    }
}

class SecondDerived extends FirstDerived {
    public void baseMethod2() {
        System.out.println("Inside baseMethod2");
    }
    public void baseMethod3() {
        System.out.println("Inside baseMethod3");
    }
}

public class MainApp {
    public static void main(String[] args) {
        // If we remove the abstract keyword from FirstDerived
        // class and uncomment the below object creation for
        // FirstDerived, it will throw a compile time error
        // because it didn't override all the abstract methods.
        
        // FirstDerived f = new FirstDerived();
        // f.baseMethod1();

        SecondDerived s = new SecondDerived();
        s.baseMethod1();
        s.baseMethod2();
        s.baseMethod3();
    }
}

Inside baseMethod1
Inside baseMethod2
Inside baseMethod3

  • A class cannot directly extend multiple classes, whether they are abstract or not ,this is a limitation of Java’s class hierarchy, and it’s known as the “diamond problem.” To achieve multiple inheritances of behavior in Java, you should use interfaces. This approach helps avoid the ambiguity issues of multiple inheritance
interface A {
    void methodA();
}

interface B {
    void methodB();
}

class MyClass implements A, B {
    @Override
    public void methodA() {
        System.out.println("Method A implementation");
    }
    
    @Override
    public void methodB() {
        System.out.println("Method B implementation");
    }
}

public class Main {
    public static void main(String[] args) {
        MyClass obj = new MyClass();
        obj.methodA(); // Output: Method A implementation
        obj.methodB(); // Output: Method B implementation
    }
}

Method A implementation
Method B implementation

Important Points about Abstract Class in Java:

Remember these rules when working with abstract classes:

  1. To create an abstract class, use the “abstract” keyword with class name
  2. An abstract class can contain both abstract and regular (non-abstract) methods.
  3. Abstract class can also include static methods.
  4. Constructors are also allowed in an abstract class.
  5. abstract class can also have Final method . If a method is marked as final in an abstract class, it can’t be changed by subclasses.
  6. You can’t make an object directly from an abstract class.
  7. When a class extends an abstract parent class, it must implement every abstract method from the parent. Otherwise, there will be an error during compilation.
  8. If the extending class doesn’t implement all the abstract methods, it must also be declared as abstract itself.

Conclusion:

In this article we learn about Java’s abstract classes as guides for other classes, explaining how they work, their advantages, and when to use them. This article will surely help you in understanding the concept of Abstract Classes in Java.

Leave a Reply

Your email address will not be published. Required fields are marked *