{"id":4600,"date":"2021-05-20T11:03:17","date_gmt":"2021-05-20T09:03:17","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=4600"},"modified":"2021-05-20T11:03:17","modified_gmt":"2021-05-20T09:03:17","slug":"inselraus-vererbung-und-ueberschattung-von-statischen-variablen-in-schnittstellen","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2021\/05\/inselraus-vererbung-und-ueberschattung-von-statischen-variablen-in-schnittstellen\/","title":{"rendered":"Inselraus: Vererbung und \u00dcberschattung von statischen Variablen in Schnittstellen"},"content":{"rendered":"<p>Die Konstanten einer Schnittstelle k\u00f6nnen einer anderen Schnittstelle vererbt werden. Dabei gibt es einige kleine Einschr\u00e4nkungen. Wir wollen an einem Beispiel sehen, wie sich die Vererbung auswirkt, wenn gleiche Bezeichner in den Unterschnittstellen erneut verwendet werden. Die Basis unseres Beispiels ist die Schnittstelle BaseColors mit ein paar Deklarationen von Farben. Zwei Unterschnittstellen erweitern BaseColors, und zwar CarColors und PlaneColors, die f\u00fcr Farbdeklarationen f\u00fcr Autos und Flugzeuge stehen. Eine besondere Schnittstelle FlyingCarColors erweitert die beiden Schnittstellen CarColors und PlaneColors, denn es gibt auch fliegende Autos, die eine Farbe haben k\u00f6nnen.<\/p>\n<pre>interface BaseColors {\r\n\u00a0 int WHITE\u00a0\u00a0 = 0;\r\n\u00a0 int BLACK\u00a0\u00a0 = 1;\r\n\u00a0 int GREY\u00a0\u00a0\u00a0 = 2;\r\n}\r\ninterface CarColors extends BaseColors {\r\n\u00a0 int WHITE\u00a0\u00a0 = 1;\r\n\u00a0 int BLACK\u00a0\u00a0 = 0;\r\n}\r\ninterface PlaneColors extends BaseColors {\r\n\u00a0 int WHITE\u00a0\u00a0 = 0;\r\n\u00a0 int GREY\u00a0\u00a0\u00a0 = 2;\r\n}\r\ninterface FlyingCarColors extends CarColors, PlaneColors { }\r\npublic class Colors {\r\n\u00a0 public static void main( String[] args ) {\r\n\u00a0\u00a0\u00a0 System.out.println( BaseColors.GREY );\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 2\r\n\u00a0\u00a0\u00a0 System.out.println( CarColors.GREY );\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 2\r\n\u00a0\u00a0\u00a0 System.out.println( BaseColors.BLACK );\u00a0\u00a0\u00a0\u00a0 \/\/ 1\r\n\u00a0\u00a0\u00a0 System.out.println( CarColors.BLACK );\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ 0\r\n\u00a0\u00a0\u00a0 System.out.println( PlaneColors.BLACK );\u00a0\u00a0\u00a0 \/\/ 1\r\n\u00a0\u00a0\u00a0 System.out.println( FlyingCarColors.WHITE );\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ \u00a0field FlyingCarColors.WHITE is ambiguous\r\n\u00a0\u00a0\u00a0 System.out.println( FlyingCarColors.GREY );\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ \u00a0field FlyingCarColors.GREY is ambiguous\r\n\u00a0 }\r\n}<\/pre>\n<p>Die erste wichtige Tatsache ist, dass unsere drei Schnittstellen ohne Fehler \u00fcbersetzt werden k\u00f6nnen, aber nicht die Klasse Colors. Das Programm und der Compiler zeigen folgendes Verhalten:<\/p>\n<ul>\n<li>Schnittstellen vererben ihre Eigenschaften an die Unterschnittstellen. CarColors und auch PlaneColors erben die Farben WHITE, BLACK und GREY aus BaseColors.<\/li>\n<li>Konstanten d\u00fcrfen \u00fcberdeckt werden. CarColors vertauscht die Farbdeklarationen von WHITE und BLACK und gibt ihnen neue Werte. Wird jetzt der Wert BLACK verlangt, liefert die Umgebung den Wert 0, w\u00e4hrend BaseColors.BLACK 1 ergibt. Auch PlaneColors \u00fcberdeckt die Konstanten WHITE und GREY, obwohl die Farben mit dem gleichen Wert belegt sind.<\/li>\n<li>Erbt eine Schnittstelle von mehreren Oberschnittstellen, so ist es zul\u00e4ssig, dass die Oberschnittstellen jeweils eine gleichlautende Objektvariable haben. So erbt etwa FlyingCarColors von CarColors und PlaneColors die Eintr\u00e4ge WHITE, BLACK und GREY.<\/li>\n<li>Unterschnittstellen k\u00f6nnen aus zwei Oberschnittstellen die Objektvariablen gleichen Namens \u00fcbernehmen, auch wenn die Konstanten einen unterschiedlichen Wert haben. Das testet der Compiler nicht. FlyingCarColors bekommt aus CarColors ein WHITE mit 1, aber aus PlaneColors das WHITE mit 0. Daher ist in dem Beispiel Colors auch der Zugriff WHITE nicht m\u00f6glich und f\u00fchrt zu einem Compilerfehler. Bei der Benutzung muss ein unmissverst\u00e4ndlich qualifizierter Name verwendet werden, der deutlich macht, welche Objektvariable gemeint ist, also zum Beispiel CarColors.WHITE oder PlaneColors.WHITE. \u00c4hnliches gilt f\u00fcr die Farbe GREY. Obwohl Grau durch die urspr\u00fcngliche Deklaration bei BaseColors und auch bei der \u00dcberschattung in PlaneColors immer 2 ist, ist die Nutzung durch FlyingCarColors.GREY nicht zul\u00e4ssig. Das ist ein guter Schutz gegen Fehler, denn wenn der Compiler dies durchlie\u00dfe, k\u00f6nnte sich im Nachhinein die Belegung von GREY in BaseColors oder PlaneColors ohne Neu\u00fcbersetzung aller Klassen \u00e4ndern und zu Schwierigkeiten f\u00fchren. Diesen Fehler \u2013 die Oberschnittstellen haben f\u00fcr eine Konstante unterschiedliche Werte \u2013 m\u00fcsste die Laufzeitumgebung erkennen. Doch das ist nicht m\u00f6glich, und in der Regel setzt der Compiler die Werte auch direkt in die Aufrufstelle ein, und ein Zugriff auf die Konstantenwerte der Schnittstelle findet nicht mehr statt.<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Die Konstanten einer Schnittstelle k\u00f6nnen einer anderen Schnittstelle vererbt werden. Dabei gibt es einige kleine Einschr\u00e4nkungen. Wir wollen an einem Beispiel sehen, wie sich die Vererbung auswirkt, wenn gleiche Bezeichner in den Unterschnittstellen erneut verwendet werden. Die Basis unseres Beispiels ist die Schnittstelle BaseColors mit ein paar Deklarationen von Farben. Zwei Unterschnittstellen erweitern BaseColors, und [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[1],"tags":[],"class_list":["post-4600","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4600","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=4600"}],"version-history":[{"count":1,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4600\/revisions"}],"predecessor-version":[{"id":4601,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/4600\/revisions\/4601"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=4600"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=4600"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=4600"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}