Class Types in Java
-
Last Updated: March 3, 2025
-
By: javahandson
-
Series
Discover the different class types in Java, including Concrete Classes, Abstract Classes, Interfaces, Nested Classes, and Anonymous Classes. Understand their roles, use cases, and how they contribute to object-oriented programming in Java.
In Java, classes can be categorized into different types based on their behavior, usage, and the way they are defined. The key types of classes are:
A concrete class in Java is a class that has a complete implementation and can be instantiated. It provides full functionality with method definitions and can have instance variables, constructors, and methods. Unlike abstract classes and interfaces, which serve as blueprints, a concrete class is ready for direct use in object creation.
1. Instantiable – Objects can be created directly from a concrete class using the new
keyword.
2. Fully Implemented Methods – All methods in a concrete class have complete implementations.
3. Can Extend Other Classes – A concrete class can inherit from another class (including an abstract class) and must provide implementations for any abstract methods.
4. Can Implement Interfaces – A concrete class can implement one or more interfaces and must provide implementations for all their abstract methods.
class Car { String model; int speed; // Constructor Car(String model, int speed) { this.model = model; this.speed = speed; } // Method void displayCarInfo() { System.out.println("Car Model: " + model); System.out.println("Car Speed: " + speed); } } public class Main { public static void main(String[] args) { Car car1 = new Car("Tesla", 120); car1.displayCarInfo(); } }
Car is a concrete class in the above example because it is fully implemented and can be instantiated to create objects.
An abstract class in Java is a class that serves as a blueprint for other classes. It cannot be instantiated on its own and is meant to be extended by subclasses that provide implementations for its abstract methods. Abstract classes are used to define common behavior that multiple related classes can share.
1. Cannot be Instantiated – You cannot create objects of an abstract class directly.
2. Can Have Abstract Methods – Abstract methods are methods without a body that must be implemented by subclasses.
3. Can Have Concrete Methods – Unlike interfaces, an abstract class can have methods with full implementations.
4. Can Have Instance Variables – Abstract classes can declare instance variables like regular classes.
5. Can Have Constructors – Though an abstract class cannot be instantiated, it can have constructors that are called when a subclass is instantiated to initialize common fields to all subclasses.
abstract class Animal { abstract void sound(); // Abstract method (no body) void breathe() { // Non-abstract method (with body) System.out.println("Animal is breathing."); } } class Dog extends Animal { @Override void sound() { System.out.println("Woof! Woof!"); } } public class Main { public static void main(String[] args) { Dog dog = new Dog(); dog.sound(); // Calling overridden method dog.breathe(); // Calling inherited method } }
In the above example, Animal is an abstract class, and Dog is a concrete subclass that implements the sound() method.
1. When you want to enforce a common structure for multiple related classes.
2. When you have some shared code among subclasses but still want to enforce specific methods to be implemented by each subclass.
3. When you need to define methods with implementations that all subclasses can inherit.
An abstract class is ideal for situations where multiple classes share common functionality but also require their own specific behavior. It provides the flexibility of partially implemented classes while enforcing a contract for subclasses.
An interface in Java is a collection of abstract methods and constants that define a contract for classes to follow. Interfaces provide a way to achieve multiple inheritance and abstraction in Java. Any class that implements an interface must provide implementations for all its abstract methods unless declared as abstract itself.
1. Cannot Have Constructors – Unlike abstract classes, interfaces cannot have constructors because they cannot be instantiated.
2. Only Abstract Methods (Before Java 8) – Before Java 8, interfaces could only have abstract methods (without implementation).
3. Default and Static Methods (Since Java 8) – Java 8 introduced default and static methods in interfaces, allowing them to have method implementations.
4. Private Methods (Since Java 9) – Java 9 introduced private methods inside interfaces to allow code reuse.
5. All Methods Are Public and Abstract by Default – Explicitly using public abstract is optional.
6. All Variables Are Public, Static, and Final – Interface fields act as constants.
interface Vehicle { void start(); // Abstract method (no body) } class Car implements Vehicle { @Override public void start() { System.out.println("Car is starting."); } } public class Main { public static void main(String[] args) { Car car = new Car(); car.start(); // Calling method implemented from interface } }
In the above example, Vehicle is an interface, and Car implements the start() method defined in the interface.
Write an Interface with Default and Static Methods (Java 8 and Later)
// Interface with default and static methods interface Student { void study(); // Abstract method // Default method (Introduced in Java 8) default void submitAssignment() { System.out.println("Assignment submitted."); } // Static method (Introduced in Java 8) static void schoolInfo() { System.out.println("Welcome to Mount carmel convent School."); } } // Implementing class class CollegeStudent implements Student { private String name; CollegeStudent(String name) { this.name = name; } @Override public void study() { System.out.println(name + " is studying."); } } public class Main { public static void main(String[] args) { CollegeStudent student = new CollegeStudent("Suraj"); student.study(); // Output: Suraj is studying. student.submitAssignment(); // Output: Assignment submitted. // Calling static method of interface Student.schoolInfo(); // Output: Welcome to Mount carmel convent School. } }
1. When you want to define a contract that multiple classes must follow.
2. When you need multiple inheritance, Java allows a class to implement multiple interfaces but not extend multiple classes.
3. When you want to separate implementation from definition and allow flexibility in extending functionality.
Interfaces are a fundamental part of Java’s polymorphism and abstraction, making code more modular, reusable, and scalable.
A nested class is a class defined inside another class. Nested classes are used to logically group related classes, improve encapsulation, and make the code more readable and maintainable.
Nested classes in Java are categorized into two types:
1. Static Nested Class – A static class inside another class.
2. Non-Static Nested Class (Inner Class) – A class that belongs to an instance of the outer class. It has three types:
A static nested class is associated with the outer class, but it does not require an instance of the outer class to be instantiated.
class OuterClass { static int staticVar = 100; static class NestedClass { void display() { System.out.println("Static Variable: " + staticVar); } } } public class Main { public static void main(String[] args) { OuterClass.NestedClass nestedObj = new OuterClass.NestedClass(); nestedObj.display(); } }
In the above example, NestedClass is a static nested class because it is defined with the static keyword and can be instantiated without an outer class instance.
An inner class is associated with an instance of the outer class. It requires an instance of the outer class to be instantiated.
class OuterClass { int outerVar = 50; class InnerClass { void display() { System.out.println("Outer Class Variable: " + outerVar); } } } public class Main { public static void main(String[] args) { OuterClass outerObj = new OuterClass(); OuterClass.InnerClass innerObj = outerObj.new InnerClass(); innerObj.display(); } }
In the above example, InnerClass is a non-static inner class, and it can access the instance variable of the outer class.
An anonymous class is a type of inner class that is declared and instantiated in a single statement. It does not have a name and is primarily used when a one-time implementation of a class or interface is needed.
Anonymous classes are commonly used in event handling, thread creation, and inline implementations of interfaces or abstract classes.
1. No Explicit Class Name – The class is defined without a name.
2. Single Instance Usage – It is used for a one-time instantiation.
3. Can Extend a Class or Implement an Interface – But not both simultaneously.
4. Can Access Outer Class Members – even private members of the enclosing class.
5. Can Access Local Variables – But they must be final or effectively final (unchanged after assignment).
interface Greeting { void greet(); } public class Main { public static void main(String[] args) { Greeting greeting = new Greeting() { // Anonymous class @Override public void greet() { System.out.println("Java HandsOn"); } }; greeting.greet(); // Calling the method } }
In the above example, we created an anonymous class that implements the Greeting interface and overrides the greet() method.
Write a program to access Outer Class Members (Including Private Members)
class Outer { private String message = "Hello from Outer Class"; void display() { System.out.println("Outer class method."); } void createAnonymous() { // Anonymous class inside a method new Object() { void show() { System.out.println(message); // Accessing private member display(); // Accessing private method } }.show(); // Calling method of anonymous class } } public class Main { public static void main(String[] args) { Outer outer = new Outer(); outer.createAnonymous(); } } Output: Hello from Outer Class Outer class method.
Write a program to access local variables (Must Be Final or Effectively Final)
interface Printer { void print(); } public class Main { public static void main(String[] args) { String localVar = "Local Variable"; // Effectively final Printer printer = new Printer() { @Override public void print() { System.out.println(localVar); // Accessing local variable } }; printer.print(); } } Output: Local Variable
1. Cannot Have Constructors – Since the class has no name, constructors cannot be explicitly defined.
2. Cannot Implement Multiple Interfaces – Unlike regular classes, an anonymous class can implement only one interface or extend only one class.
3. Code Readability Issue – If overused, anonymous classes can make code harder to read and debug.
1. When you need a one-time implementation of a class or interface.
2. Defining a separate class would be unnecessary and would increase code complexity.
3. In event listeners, callbacks, and small helper classes.
Java provides a variety of class types to support different programming needs, from fully implemented concrete classes to abstract classes and interfaces that define blueprints for other classes. Nested and anonymous classes further enhance modularity and flexibility. Understanding these class types allows developers to write more maintainable, reusable, and efficient code. By leveraging the right class type in the right scenario, you can create robust Java applications that follow best coding practices.
So this is all about class types in Java. If you have any questions on this topic, please raise them in the comments section. If you liked this article, then please share this post with your friends and colleagues.