Difference between Final and Abstract in Java


When working with Java, understanding the concepts of final and abstract is crucial for writing efficient and maintainable code. Whereas both last and theoretical play important parts in object-oriented programming, they serve diverse purposes. In this article, we'll investigate the sentence structure and utilization of last and abstract keywords in Java, as well as the diverse approaches to executing them.

Syntax

To characterize a final class or strategy, we utilize the catchphrase "final" some time recently the class or strategy affirmation. For case, a final class would be characterized as takes after −

final class MyClass {
   // Class implementation
}

To characterize an abstract class or strategy, we utilize the watchword "abstract" before the class or strategy statement. For illustration, an theoretical course would be characterized as takes after −

abstract class MyAbstractClass {
   // Class implementation
}

Explanation of Syntax

The final" keyword is utilized to demonstrate that a class, method, or variable is not implied to be changed or overridden. A final class cannot be subclassed, and a last strategy cannot be overridden in any subclasses. Moreover, a last variable cannot be reassigned once it has been assigned a value.

On the other hand, the "abstract" keyword is utilized to show that a class or strategy is deficient and must be amplified or actualized by another class. An abstract course cannot be instantiated straightforwardly, and it may contain theoretical strategies that are implied to be executed by its subclasses.

Approach 1: Final

In this approach, we will focus on the usage of the final keyword. The main purpose of using final is to create immutable entities in Java. Immutable objects are those whose state cannot be changed once they are created.

Algorithm

  • Declare the class or method as final.

  • Implement the desired functionality within the class or method.

  • Prevent any further modifications by other classes or subclasses.

Example

final class ImmutableClass {
   private final String name;

   public ImmutableClass(String name) {
      this.name = name;
   }

   public String getName() {
      return name;
   }
}

public class Main {
   public static void main(String[] args) {
      ImmutableClass immutableObject = new ImmutableClass("Hello");
      System.out.println(immutableObject.getName());
   }
}

Output

Hello

Explanation of the code in approach 1

ImmutableClass is designated as being both immutable and unextendable due to the inclusion of the "final" keyword during declaration. It encompasses a solitary private instance variable called "name," which too has been marked as final to prevent modification post-assignment at inception via the constructor.

The constructor of ImmutableClass takes a String parameter called name and assigns its value to the name variable. This ensures that the name variable can only be set once during object creation and cannot be modified afterwards.

Within ImmutableClass exists a public-facing means of finding an object's name through a logically named getName() method. Since said name element is designated as private, exterior access to it must be precluded - thereby necessitating implementation of this findable utility. Our program's entry point begins upon reaching Main class' main() function where we instantiate an instance of ImmutableClass with its accompanying naming parameter set as "Hello".

Once initialized, we store our new instance under the memory saving variable immutableObject. We culminate our main function by specifying System.out.println()'s output stream as equaling return from immutableObject's previously detailed getName() method - so that our program displays successful execution by showing "Hello" (our initially designated name) on-screen.

Approach 2: Abstract

In this approach, we'll focus on the utilization of the abstract keyword. Abstract classes are utilized to supply a common interface and characterize common behavior for a gathering of related classes.

Algorithm

  • Declare the class as abstract.

  • Define abstract methods that should be implemented by subclasses.

  • Implement common functionality within the abstract class.

Example

abstract class Shape {
   protected String color;

   public Shape(String color) {
      this.color = color;
   }

   abstract double getArea();
}

class Circle extends Shape {
   private double radius;

   public Circle(String color, double radius) {
      super(color);
      this.radius = radius;
   }

   @Override
   double getArea() {
      return Math.PI * radius * radius;
   }
}

public class Main {
   public static void main(String[] args) {
      Circle circle = new Circle("Red", 2.5);
      System.out.println("Color: " + circle.color);
      System.out.println("Area: " + circle.getArea());
        
   }
}

Output

Color: Red
Area: 19.634954084936208

The Shape class is declared as an abstract class using the abstract keyword. Abstract classes cannot be instantiated, meaning objects of the Shape class cannot be created directly. The Shape class has a protected instance variable called color and a constructor that takes a color parameter and assigns its value to the color variable.

The Shape class also declares an abstract method called getArea(). Procedure-wise in programming, abstract methods play a key role in creating framework and structuring practices for code implementations. Specifically with this toolset, developers can create methodologies and structures without immediately committing them down at runtime-- instead leaving them up for later development from concrete subclasses (i.e., classes outside introduced categories).

Let's examine how getArea() relates here in particular- concisely put: calculating an area varies depending on shape classification and subtype factors used by various developers therein; so having this variation factor placed into non-immediate or independent development allows any concrete subclass to implement customizations without concern over overall structure breakdowns or integrity maintenance issues expressed previous to sublevel creation(s). Additionally relevant regarding our groundwork here, Shape can be seen extended by Circle as such a subclass and further modulated for integration into other structures with similar template methods of development. It adds a private instance variable called radius and has a constructor that takes both a color and radius parameter. The constructor of Circle calls the constructor of its superclass (Shape) using the super keyword to initialize the color variable. It then assigns the radius parameter to the radius variable of the Circle class.

The Circle class overrides the getArea() method inherited from the Shape class. In this case, it calculates the area of the circle using the formula: π * radius * radius. The Math.PI constant represents the value of pi (approximately 3.14159).

Fundamental to this programming sequence is the Main class, in which we can find the main method - establishing the starting point of our program. Within this method, we instigate a Circle object, initially featuring a radius of 2.5 and presenting with "Red" coloring. This new object fetches information from both of its respective constructors: first calling upon the Circle constructor before summoning assistance from the Shape constructor in resetting its color value. Lastly, we designate "circle" as our variable name for this specific instance.

Finally, the color variable of the circle object is accessed using circle.color and printed to the console. The getArea() method is also called on the circle object, and the returned value is printed to the console as well.

Difference between Final and Abstract in Java

Points of Difference

Approach 1: Final

Approach 2: Abstract

Instantiation

Allows instantiation of class

Cannot be instantiated directly

Inheritance

Cannot be subclassed

Subclassing is allowed

Method Override

Methods cannot be overridden

Abstract methods must be implemented by subclasses

Modifiability

Prevents modification of class, method, or variable

Provides a blueprint for modification and extension in subclasses

Usage

Useful for creating immutable entities or enforcing specific behavior

Useful for defining common interface and behavior for related classes

Conclusion

In conclusion, while final and abstract serve different purposes, they are both important tools in Java programming. By utilizing them appropriately, you can write more robust, flexible, and maintainable code that conforms to design principles and meets specific requirements. Whether it's creating immutable entities or establishing a common interface, final and abstract keywords contribute to the development of high-quality Java applications.

Updated on: 28-Jul-2023

650 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements