Feature/bael 4662 sealed classes (#10224)
* BAEL-4662: Initial commit of new module * BAEL-4662: Example with Records * BAEL-4662: Example with Interface * BAEL-4662: Add test classes * BAEL-4662: Update examples and tests * BAEL-4662: Rename test classes
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package com.baeldung.sealed.alternative;
|
||||
|
||||
public class Vehicles {
|
||||
|
||||
abstract static class Vehicle {
|
||||
|
||||
private final String registrationNumber;
|
||||
|
||||
public Vehicle(String registrationNumber) {
|
||||
this.registrationNumber = registrationNumber;
|
||||
}
|
||||
|
||||
public String getRegistrationNumber() {
|
||||
return registrationNumber;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class Car extends Vehicle {
|
||||
|
||||
private final int numberOfSeats;
|
||||
|
||||
public Car(int numberOfSeats, String registrationNumber) {
|
||||
super(registrationNumber);
|
||||
this.numberOfSeats = numberOfSeats;
|
||||
}
|
||||
|
||||
public int getNumberOfSeats() {
|
||||
return numberOfSeats;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class Truck extends Vehicle {
|
||||
|
||||
private final int loadCapacity;
|
||||
|
||||
public Truck(int loadCapacity, String registrationNumber) {
|
||||
super(registrationNumber);
|
||||
this.loadCapacity = loadCapacity;
|
||||
}
|
||||
|
||||
public int getLoadCapacity() {
|
||||
return loadCapacity;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.sealed.classes;
|
||||
|
||||
public non-sealed class Car extends Vehicle implements Service {
|
||||
|
||||
private final int numberOfSeats;
|
||||
|
||||
public Car(int numberOfSeats, String registrationNumber) {
|
||||
super(registrationNumber);
|
||||
this.numberOfSeats = numberOfSeats;
|
||||
}
|
||||
|
||||
public int getNumberOfSeats() {
|
||||
return numberOfSeats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxServiceIntervalInMonths() {
|
||||
return 12;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.sealed.classes;
|
||||
|
||||
public sealed interface Service permits Car, Truck {
|
||||
|
||||
int getMaxServiceIntervalInMonths();
|
||||
|
||||
default int getMaxDistanceBetweenServicesInKilometers() {
|
||||
return 100000;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.sealed.classes;
|
||||
|
||||
public final class Truck extends Vehicle implements Service {
|
||||
|
||||
private final int loadCapacity;
|
||||
|
||||
public Truck(int loadCapacity, String registrationNumber) {
|
||||
super(registrationNumber);
|
||||
this.loadCapacity = loadCapacity;
|
||||
}
|
||||
|
||||
public int getLoadCapacity() {
|
||||
return loadCapacity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxServiceIntervalInMonths() {
|
||||
return 18;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.baeldung.sealed.classes;
|
||||
|
||||
public abstract sealed class Vehicle permits Car, Truck {
|
||||
|
||||
protected final String registrationNumber;
|
||||
|
||||
public Vehicle(String registrationNumber) {
|
||||
this.registrationNumber = registrationNumber;
|
||||
}
|
||||
|
||||
public String getRegistrationNumber() {
|
||||
return registrationNumber;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.sealed.records;
|
||||
|
||||
public record Car(int numberOfSeats, String registrationNumber) implements Vehicle {
|
||||
|
||||
@Override
|
||||
public String getRegistrationNumber() {
|
||||
return registrationNumber;
|
||||
}
|
||||
|
||||
public int getNumberOfSeats() {
|
||||
return numberOfSeats;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.sealed.records;
|
||||
|
||||
public record Truck(int loadCapacity, String registrationNumber) implements Vehicle {
|
||||
|
||||
@Override
|
||||
public String getRegistrationNumber() {
|
||||
return registrationNumber;
|
||||
}
|
||||
|
||||
public int getLoadCapacity() {
|
||||
return loadCapacity;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.baeldung.sealed.records;
|
||||
|
||||
public sealed interface Vehicle permits Car, Truck {
|
||||
|
||||
String getRegistrationNumber();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.baeldung.sealed.classes;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
public class VehicleUnitTest {
|
||||
|
||||
private static Vehicle car;
|
||||
private static Vehicle truck;
|
||||
|
||||
@BeforeAll
|
||||
public static void createInstances() {
|
||||
car = new Car(5, "VZ500DA");
|
||||
truck = new Truck(19000, "VZ600TA");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenUsingReflectionAPI_thenSuperClassIsSealed() {
|
||||
Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false);
|
||||
Assertions.assertThat(car.getClass().getSuperclass().isSealed()).isEqualTo(true);
|
||||
Assertions.assertThat(car.getClass().getSuperclass().permittedSubclasses())
|
||||
.contains(ClassDesc.of(car.getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenUsingReflectionAPI_thenSuperClassIsSealed() {
|
||||
Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false);
|
||||
Assertions.assertThat(truck.getClass().getSuperclass().isSealed()).isEqualTo(true);
|
||||
Assertions.assertThat(truck.getClass().getSuperclass().permittedSubclasses())
|
||||
.contains(ClassDesc.of(truck.getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenGettingPropertyTraditionalWay_thenNumberOfSeatsPropertyIsReturned() {
|
||||
Assertions.assertThat(getPropertyTraditionalWay(car)).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenGettingPropertyViaPatternMatching_thenNumberOfSeatsPropertyIsReturned() {
|
||||
Assertions.assertThat(getPropertyViaPatternMatching(car)).isEqualTo(5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenGettingPropertyTraditionalWay_thenLoadCapacityIsReturned() {
|
||||
Assertions.assertThat(getPropertyTraditionalWay(truck)).isEqualTo(19000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenGettingPropertyViaPatternMatching_thenLoadCapacityIsReturned() {
|
||||
Assertions.assertThat(getPropertyViaPatternMatching(truck)).isEqualTo(19000);
|
||||
}
|
||||
|
||||
private int getPropertyTraditionalWay(Vehicle vehicle) {
|
||||
if (vehicle instanceof Car) {
|
||||
return ((Car) vehicle).getNumberOfSeats();
|
||||
} else if (vehicle instanceof Truck) {
|
||||
return ((Truck) vehicle).getLoadCapacity();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown instance of Vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
private int getPropertyViaPatternMatching(Vehicle vehicle) {
|
||||
if (vehicle instanceof Car car) {
|
||||
return car.getNumberOfSeats();
|
||||
} else if (vehicle instanceof Truck truck) {
|
||||
return truck.getLoadCapacity();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown instance of Vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.baeldung.sealed.records;
|
||||
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.lang.constant.ClassDesc;
|
||||
|
||||
public class VehicleUnitTest {
|
||||
|
||||
private static Vehicle car;
|
||||
private static Vehicle truck;
|
||||
|
||||
@BeforeAll
|
||||
public static void createInstances() {
|
||||
car = new Car(4, "VZ500DA");
|
||||
truck = new Truck(16000, "VZ600TA");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenUsingReflectionAPI_thenInterfaceIsSealed() {
|
||||
Assertions.assertThat(car.getClass().isSealed()).isEqualTo(false);
|
||||
Assertions.assertThat(car.getClass().getInterfaces()[0].isSealed()).isEqualTo(true);
|
||||
Assertions.assertThat(car.getClass().getInterfaces()[0].permittedSubclasses())
|
||||
.contains(ClassDesc.of(car.getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenUsingReflectionAPI_thenInterfaceIsSealed() {
|
||||
Assertions.assertThat(truck.getClass().isSealed()).isEqualTo(false);
|
||||
Assertions.assertThat(truck.getClass().getInterfaces()[0].isSealed()).isEqualTo(true);
|
||||
Assertions.assertThat(truck.getClass().getInterfaces()[0].permittedSubclasses())
|
||||
.contains(ClassDesc.of(truck.getClass().getCanonicalName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenGettingPropertyTraditionalWay_thenNumberOfSeatsPropertyIsReturned() {
|
||||
Assertions.assertThat(getPropertyTraditionalWay(car)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCar_whenGettingPropertyViaPatternMatching_thenNumberOfSeatsPropertyIsReturned() {
|
||||
Assertions.assertThat(getPropertyViaPatternMatching(car)).isEqualTo(4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenGettingPropertyTraditionalWay_thenLoadCapacityIsReturned() {
|
||||
Assertions.assertThat(getPropertyTraditionalWay(truck)).isEqualTo(16000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenTruck_whenGettingPropertyViaPatternMatching_thenLoadCapacityIsReturned() {
|
||||
Assertions.assertThat(getPropertyViaPatternMatching(truck)).isEqualTo(16000);
|
||||
}
|
||||
|
||||
private int getPropertyTraditionalWay(Vehicle vehicle) {
|
||||
if (vehicle instanceof Car) {
|
||||
return ((Car) vehicle).getNumberOfSeats();
|
||||
} else if (vehicle instanceof Truck) {
|
||||
return ((Truck) vehicle).getLoadCapacity();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown instance of Vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
private int getPropertyViaPatternMatching(Vehicle vehicle) {
|
||||
if (vehicle instanceof Car car) {
|
||||
return car.getNumberOfSeats();
|
||||
} else if (vehicle instanceof Truck truck) {
|
||||
return truck.getLoadCapacity();
|
||||
} else {
|
||||
throw new RuntimeException("Unknown instance of Vehicle");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user