The permits keyword in Java is used in conjunction with the sealed keyword to specify the classes that are allowed to extend or implement a sealed class or interface. This feature, introduced in Java 17, enables a more controlled and restricted inheritance hierarchy, ensuring that only specified classes or interfaces can be subclasses or implementors of a sealed class or interface.
Table of Contents
- Introduction
permitsKeyword Syntax- Understanding
permits - Examples
- Sealed Class with Permits
- Sealed Interface with Permits
- Real-World Use Case
- Conclusion
Introduction
Sealed classes and interfaces in Java provide a way to control which classes or interfaces can extend or implement them. The permits keyword explicitly lists the subclasses or implementors allowed, ensuring a controlled and predictable class hierarchy.
permits Keyword Syntax
The syntax for using the permits keyword with a sealed class or interface is as follows:
public sealed class ClassName permits Subclass1, Subclass2 {
// class body
}
public sealed interface InterfaceName permits Implementor1, Implementor2 {
// interface body
}
Example:
public sealed class Shape permits Circle, Rectangle, Square {
// class body
}
Understanding permits
Key Points:
- Controlled Inheritance: Specifies which classes or interfaces are allowed to extend or implement a sealed class or interface.
- Explicit Listing: The
permitsclause lists all permitted subclasses or implementors. - Sealed Hierarchy: Ensures a controlled and restricted class hierarchy.
Examples
Sealed Class with Permits
A sealed class with explicitly permitted subclasses.
Example
public sealed class Shape permits Circle, Rectangle, Square {
// common properties and methods
}
public final class Circle extends Shape {
// properties and methods specific to Circle
}
public sealed class Rectangle extends Shape permits ColoredRectangle {
// properties and methods specific to Rectangle
}
public final class Square extends Shape {
// properties and methods specific to Square
}
public final class ColoredRectangle extends Rectangle {
// properties and methods specific to ColoredRectangle
}
public class Main {
public static void main(String[] args) {
Shape shape1 = new Circle();
Shape shape2 = new Rectangle();
Shape shape3 = new Square();
Shape shape4 = new ColoredRectangle();
System.out.println(shape1);
System.out.println(shape2);
System.out.println(shape3);
System.out.println(shape4);
}
}
Sealed Interface with Permits
A sealed interface with explicitly permitted implementors.
Example
public sealed interface Operation permits Addition, Subtraction {
int apply(int a, int b);
}
public final class Addition implements Operation {
@Override
public int apply(int a, int b) {
return a + b;
}
}
public final class Subtraction implements Operation {
@Override
public int apply(int a, int b) {
return a - b;
}
}
public class Main {
public static void main(String[] args) {
Operation addition = new Addition();
Operation subtraction = new Subtraction();
System.out.println("Addition: " + addition.apply(10, 5));
System.out.println("Subtraction: " + subtraction.apply(10, 5));
}
}
Output:
Addition: 15
Subtraction: 5
Real-World Use Case
Financial Transactions
In a financial application, you might want to control the types of transactions that can occur, such as deposits and withdrawals, ensuring no other transaction types are inadvertently created.
Example
public sealed class Transaction permits Deposit, Withdrawal {
// common properties and methods
}
public final class Deposit extends Transaction {
// properties and methods specific to Deposit
}
public final class Withdrawal extends Transaction {
// properties and methods specific to Withdrawal
}
public class Main {
public static void main(String[] args) {
Transaction deposit = new Deposit();
Transaction withdrawal = new Withdrawal();
System.out.println(deposit);
System.out.println(withdrawal);
}
}
Output:
Deposit@<hashcode>
Withdrawal@<hashcode>
Conclusion
The permits keyword in Java, used alongside sealed, allows for defining a controlled and restricted class or interface hierarchy. By specifying the permitted subclasses or implementors, it ensures that the inheritance hierarchy is well-defined and predictable. Understanding and using the permits keyword effectively is crucial for developing robust and maintainable Java applications with controlled inheritance structures.