<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://mletkin.net/index.php?action=history&amp;feed=atom&amp;title=Java_17%3A_Sealed_Classes</id>
	<title>Java 17: Sealed Classes - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://mletkin.net/index.php?action=history&amp;feed=atom&amp;title=Java_17%3A_Sealed_Classes"/>
	<link rel="alternate" type="text/html" href="https://mletkin.net/index.php?title=Java_17:_Sealed_Classes&amp;action=history"/>
	<updated>2026-05-06T16:58:17Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in MimiPedia</subtitle>
	<generator>MediaWiki 1.39.4</generator>
	<entry>
		<id>https://mletkin.net/index.php?title=Java_17:_Sealed_Classes&amp;diff=166&amp;oldid=prev</id>
		<title>Ullrich: Die Seite wurde neu angelegt: „Category:Java __TOC__ Um die Ableitbarkeit von Klassen zu steuern bietet Java bis Versuion 16 nur eine einzige Möglichkeit, den Modifier {{java|final}}. Ist eine Klasse als {{java|final}} markiert, ist es unmöglich eine weitere Klasse von ihr abzuleiten. Ist die nicht {{java|final}}, kann jeder der Zugriff auf die Klasse hat von ihr beliebige Klassen ableiten.  Das folgt dem Gedanken, daß die Klassen-Hierarchie nichts anderes ist als ein Erweiterun…“</title>
		<link rel="alternate" type="text/html" href="https://mletkin.net/index.php?title=Java_17:_Sealed_Classes&amp;diff=166&amp;oldid=prev"/>
		<updated>2023-10-21T14:52:03Z</updated>

		<summary type="html">&lt;p&gt;Die Seite wurde neu angelegt: „&lt;a href=&quot;/index.php?title=Kategorie:Java&amp;amp;action=edit&amp;amp;redlink=1&quot; class=&quot;new&quot; title=&quot;Kategorie:Java (Seite nicht vorhanden)&quot;&gt;Category:Java&lt;/a&gt; __TOC__ Um die Ableitbarkeit von Klassen zu steuern bietet Java bis Versuion 16 nur eine einzige Möglichkeit, den Modifier {{java|final}}. Ist eine Klasse als {{java|final}} markiert, ist es unmöglich eine weitere Klasse von ihr abzuleiten. Ist die nicht {{java|final}}, kann jeder der Zugriff auf die Klasse hat von ihr beliebige Klassen ableiten.  Das folgt dem Gedanken, daß die Klassen-Hierarchie nichts anderes ist als ein Erweiterun…“&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;[[Category:Java]]&lt;br /&gt;
__TOC__&lt;br /&gt;
Um die Ableitbarkeit von Klassen zu steuern bietet Java bis Versuion 16 nur eine einzige Möglichkeit, den Modifier {{java|final}}.&lt;br /&gt;
Ist eine Klasse als {{java|final}} markiert, ist es unmöglich eine weitere Klasse von ihr abzuleiten.&lt;br /&gt;
Ist die nicht {{java|final}}, kann jeder der Zugriff auf die Klasse hat von ihr beliebige Klassen ableiten.&lt;br /&gt;
&lt;br /&gt;
Das folgt dem Gedanken, daß die Klassen-Hierarchie nichts anderes ist als ein Erweiterungs-Konzept.&lt;br /&gt;
Möchte man Klassen so modellieren, daß dabei eine abgegrenzten DSL entsteht, eine Abstraktion über die die&lt;br /&gt;
Elemente einer bestimmten Domäne der Verarbeitung zugänglich gemacht wird, benötigt man eine feinere Steuerung.&lt;br /&gt;
Denn dann möchte man die Ableitung innerhalb der Anwendung einschränken und ggf. nach außen hin ganz unterbinden.&lt;br /&gt;
&lt;br /&gt;
Das Konzept der {{Java|sealed classes}} läßt uns Teile der Klassen-Hierarchie unserer Anwendung vollständig gegen Vererbung abschotten,&lt;br /&gt;
wärend Teile der Hierarchie der Vererbung offen bleiben.&lt;br /&gt;
&lt;br /&gt;
== sealed classes ==&lt;br /&gt;
&lt;br /&gt;
Betrachten wir die Klasse {{Java|Shape}} von der nur zwei Klassen abgeleitet werden können sollen:&lt;br /&gt;
{{Java|code=&lt;br /&gt;
public sealed class Shape permits Quadrangle, Ellipse { ... }&lt;br /&gt;
}}&lt;br /&gt;
Das [[Keywords|context keyword]] {{Java|sealed}} verschließt die Klasse gegen direkte, nicht vorgesehene Vererbung,&lt;br /&gt;
wärend hinter dem [[Keywords|context keyword]] {{Java|permits}} alle Klassen aufgezählt werden die von der Klasse ableiten dürfen.&lt;br /&gt;
&lt;br /&gt;
Was verhält es sich nun mit den beiden abgeleiteten Klassen? Java verlangt, daß für jede Klasse die von&lt;br /&gt;
einer {{Java|sealed}} Klasse abgeleitet wird festgelegt wird, wie von ihr abgeleitet werden kann:&lt;br /&gt;
&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;final&amp;#039;&amp;#039;&amp;#039; von der Klasse ist überhaupt keine Ableitung mehr möglich&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;non-sealed&amp;#039;&amp;#039;&amp;#039; von der Klasse können wieder beliebige weitere Klassen abgeleitet werden&lt;br /&gt;
:&amp;#039;&amp;#039;&amp;#039;sealed&amp;#039;&amp;#039;&amp;#039; wie bei der Super-Klasse werden alle ableitenden Klassen angegeben.&lt;br /&gt;
&lt;br /&gt;
== sealed interfaces ==&lt;br /&gt;
Analog zu Klassen können auch Interfaces abgeschottet werden. Hier bieten sich nun zwei Möglichkeiten der&lt;br /&gt;
Erweiterung: Zum Einen können von einem Interface neue Interfaces abgeleitet werden,&lt;br /&gt;
zum Anderen können Klassen das Interface implementieren. Es entstehen also zwei Varianten der Versiegelung.&lt;br /&gt;
&lt;br /&gt;
Bei der Ableitung verhalten sich die Dinge genauso wie oben für Klassen beschrieben:&lt;br /&gt;
Ist das Interface {{java|sealed}}, müssen bei der Definition &amp;#039;&amp;#039;alle&amp;#039;&amp;#039; abgeleiteten Interfaces angegeben werden:&lt;br /&gt;
{{Java|code=&lt;br /&gt;
public sealed interface Length permits Convex, NonConvex { ... }&lt;br /&gt;
}}&lt;br /&gt;
Alle abgeleiteten Interfaces verhalten sich wieder wie Klassen, sie müssen entweder {{Java|sealed}} oder {{Java|non-sealed}} sein.&lt;br /&gt;
Interfaces können -- weil das absurd wäre -- niemals {{Java|final}} sein.&lt;br /&gt;
&lt;br /&gt;
Implementiert eine Klasse ein {{Java|sealed}} Interface, kommt es in den gleichen Zustand als wäre es von einer {{Java|sealed}} Klasse abgeleitet.&lt;br /&gt;
Es muß entweder als {{Java|sealed}}, {{Java|non-sealed}} oder {{Java|final}} markiert sein.&lt;br /&gt;
&lt;br /&gt;
== enums ==&lt;br /&gt;
Da das klassische {{java|enum}} implizit -- zumindest fast immer -- {{java|final}} ist, kann es nicht {{java|sealed}} sein.&lt;br /&gt;
Da es aber interfaces implementieren kann, kann es auch {{java|sealed}} interfaces implementieren. Da das enum implizit {{java|final}} ist,&lt;br /&gt;
braucht es aber nicht weiter markiert zu werden.&lt;br /&gt;
&lt;br /&gt;
In a nutshell: Ein {{java|enum}} kann ein {{java|sealed}} interface implementieren, als wäre es ein normales Interface.&lt;br /&gt;
&lt;br /&gt;
Was sollte im vorangehenden Absatz aber der Einschub &amp;quot;fast immer&amp;quot;?&lt;br /&gt;
&lt;br /&gt;
Betrachten wir dieses kleine -- zugegebenermaßen etwas unsinnige -- enum:&lt;br /&gt;
{{Java|code=&lt;br /&gt;
 public enum Foo {&lt;br /&gt;
     BLA,&lt;br /&gt;
     FASEL {&lt;br /&gt;
            public int wert = 5;&lt;br /&gt;
            }&lt;br /&gt;
 }&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
Es soll nur eines verdeutlichen:&lt;br /&gt;
&lt;br /&gt;
Das enum {{java|Foo}} ist implizit {{java|sealed}} und die einzige Klasse die davon ableitet&lt;br /&gt;
ist die namenlose Klasse die den Typ des Objekts {{java|FASEL}} darstellt; diese namenlose Klasse ist imlizit {{java|final}}.&lt;br /&gt;
&lt;br /&gt;
Vereinfacht ausgedrückt:&lt;br /&gt;
&lt;br /&gt;
enums die sealed Interfaces implementieren sind implizit final, Objekte des enums können aber finale Sub-Klassen des enums bilden.&lt;br /&gt;
&lt;br /&gt;
== Mocking ==&lt;br /&gt;
Da sealed classes keine Ableitung erlauben, stellt sich die Frage ob man sie mocken kann.&lt;br /&gt;
Mit Mockito ist das möglich ab Version 5.0.0, Version 4 kompiliert zwar, wirft bei der Ausführung aber eine Exception.&lt;br /&gt;
Gleiches gilt für den Spy, der ebenfalls ab Version 5.0.0 erzeugt werden kann.&lt;br /&gt;
&lt;br /&gt;
An dieser Stelle sei der Vollständigkeit halber darauf hingewiesen,&lt;br /&gt;
daß Mockito auch final Klassen mocken und spyen kann -- aber auch erst mit Version 5.0.0&lt;br /&gt;
&lt;br /&gt;
== Fazit ==&lt;br /&gt;
Sealed Klasses und Interfaces sind für Java ein Konzept, das das Paradigma nicht gerade ändert, aber doch in eine ungewohnte Richtung biegt.&lt;br /&gt;
Formal werden dadurch -- eigentlich unerwünschte -- zyklische Abhängigkeit zwischen Super- und Sub-Klasse geschaffen, weil plötzlich die&lt;br /&gt;
Superklasse ihre Subklasses kennt. Inhaltlich aber macht die Superklasse ja davon gar keine Verwendung, es ist in Wirklichkeit eine Compiler-Anweisung.&lt;br /&gt;
&lt;br /&gt;
Man muß die (teil)ge-sealte Hierarchie als ein Ganzes sehen, das einen Teil einer fachlichen Domäne abbildet.&lt;br /&gt;
Weil die Domäne als geschlossen betrachtet wird, läßt sie auch keine unkontrollierte Erweiterung zu.&lt;br /&gt;
Verwendet man diese Hierarchie nur, hat man keine Wahl und muß sie nehmen wie sie ist.&lt;br /&gt;
Arbeitet man an der Hierarchie, weist einen die Versiegelung darauf hin, daß eine Erweiterung vom Konzept an dieser Stelle nicht vorgesehen ist.&lt;br /&gt;
Eine Veränderung bedarf zunächst der fachlichen Klärung und die Versiegelung schützt uns davor, voreilige Änderungen durchzuführen.&lt;br /&gt;
&lt;br /&gt;
Wenn eine Programmiersprache Möglichkeiten der Einschränkung schafft, ist das keine Behinderung des Coders.&lt;br /&gt;
Es ist die Möglichkeit, Consraints der Domäne explizit zu machen -- und das ist ein wertvolles Hilfsmittel.&lt;/div&gt;</summary>
		<author><name>Ullrich</name></author>
	</entry>
</feed>