Obwohl Records keine Klassen erweitern können, können sie Schnittstellen implementieren. Dies ermöglicht uns, Abstraktionen zu erstellen, was nützlich ist, um gemeinsame Record-Komponenten zu teilen.
Betrachten wir ein Beispiel. Wir wollen den Basistyp Event nicht mehr als abstrakte Oberklasse deklarieren, sondern als Schnittstelle:
interface Event { String about(); int duration(); }
Das erlaubt es uns, zwei Records zu deklarieren, die die Event-Schnittstelle implementieren:
record Nap( String about, int duration ) implements Event {} record Workout( String about, int duration, int caloriesBurned ) implements Event {}
Der clevere Teil dabei ist, dass die Records bereits die Zugriffsmethoden String about() und int duration() besitzen, sodass keine zusätzliche Implementierung erforderlich ist.
Mit dieser Typbeziehung können wir Folgendes tun:
Event event = new Nap( "Snooze Olympics", 69 ); System.out.println( event.about() ); System.out.println( event.duration() );
In diesem Fall ist der Referenztyp Event und der Objekttyp Nap. Mit dieser Abstraktion lässt sich perfekt Pattern-Matching und Record-Pattern einsetzen:
switch ( event ) { case Nap nap -> System.out.printf( "%d minutes of ninja-level rest!%n", nap.duration ); case Workout( var about, var duration, var calories ) -> System.out.printf("You just burned %d calories for a guilt-free gummy bear.%n", calories ); default -> {} }