{"id":4881,"date":"2024-10-30T12:20:05","date_gmt":"2024-10-30T12:20:05","guid":{"rendered":"https:\/\/msgprogramator.sk\/?p=4881"},"modified":"2025-07-07T11:36:24","modified_gmt":"2025-07-07T11:36:24","slug":"encapsulation-java","status":"publish","type":"post","link":"https:\/\/msgprogramator.sk\/de\/encapsulation-java\/","title":{"rendered":"Kapselung (Encapsulation) in Java \u2013 unverzichtbar oder \u00fcberfl\u00fcssig?"},"content":{"rendered":"<p>Viele Programmierer, vor allem diejenigen, die mit objektorientierter Programmierung, z.B. in Java, begonnen haben, k\u00f6nnen nur schwer verstehen, warum es notwendig ist, Encapsulation zu verwenden, wenn es doch \u00fcberhaupt nicht notwendig ist und es irgendwie auch ohne funktioniert. Sie glauben f\u00e4lschlicherweise, dass es im Grunde nur darum geht, Daten vor der Au\u00dfenwelt zu verstecken. Ich muss gestehen, dass ich zu einer \u00e4hnlichen Kategorie von Menschen geh\u00f6rte, als ich vor vielen Jahren Java programmieren lernte. Der Zweck dieses Artikels ist es, zu erkl\u00e4ren, was Kapselung ist, warum man damit anfangen sollte, welche Vorteile sie bringt und welche Beziehung zwischen Kapselung und Abstraktion besteht.   <\/p>\n<h2>Was ist encapsulation (Verkapselung)?<\/h2>\n<p>Kapselung ist eine M\u00f6glichkeit, Mitgliedsvariablen (d.h. Daten) und Verhaltensweisen (Methoden) in einer einzigen Einheit zu kombinieren, die eine Klasse, eine Schnittstelle, eine Enum usw. sein kann. Diese Kapselung stellt sicher, dass die Daten nicht direkt zug\u00e4nglich sind, und die gleichen Einschr\u00e4nkungen k\u00f6nnen f\u00fcr die Verhaltensmethoden gelten, die mit den Daten arbeiten. Dies l\u00e4sst sich am besten anhand eines Beispiels veranschaulichen, bei dem es sich um eine Art Kapsel (\u00e4hnlich einer Pille) handelt, die die Datenmethoden und -elemente enth\u00e4lt, und die Kapselung ist eine H\u00fclle oder Schicht, die sie vor der Au\u00dfenwelt sch\u00fctzt. Sie bietet jedoch eine klar definierte \u00f6ffentliche Schnittstelle f\u00fcr den Zugriff und die Bearbeitung dieses Objekts. Die Kapselung stellt auch sicher, dass wir nicht in die Kapsel hineinsehen k\u00f6nnen und daher aus der Perspektive eines au\u00dfenstehenden Beobachters oder Benutzers nicht wissen, wie was implementiert wurde. <strong>Verkapselung<\/strong> kann man sich als Verkapselung von Methoden und Mitgliedern in einer Kapsel vorstellen. <\/p>\n<figure id=\"attachment_4691\" aria-describedby=\"caption-attachment-4691\" style=\"width: 1200px\" class=\"wp-caption alignnone\"><img loading=\"lazy\" decoding=\"async\" class=\"wp-image-4689 size-full\" src=\"https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/10\/Encapsulation_1200x800.webp\" alt=\"Kapselung kann man sich als die Verkapselung von Methoden und Membern in einer Kapsel vorstellen. QUELLE: tutoringlounge.com.au\/objektorientierte-programmierung\/ \" width=\"1200\" height=\"800\" srcset=\"https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/10\/Encapsulation_1200x800.webp 1200w, https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/10\/Encapsulation_1200x800-300x200.webp 300w, https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/10\/Encapsulation_1200x800-1024x683.webp 1024w, https:\/\/msgprogramator.sk\/wp-content\/uploads\/2024\/10\/Encapsulation_1200x800-768x512.webp 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><figcaption id=\"caption-attachment-4691\" class=\"wp-caption-text\">Kapselung kann man sich als die Verkapselung von Methoden und Membern in einer Kapsel vorstellen. QUELLE: tutoringlounge.com.au\/objektorientierte-programmierung\/<\/figcaption><\/figure>\n<h2>Wie erreicht man Kapselung in Java<\/h2>\n<h3>Mechanismus zum Verbergen von Daten<\/h3>\n<p>In Java wird die Kapselung durch Zugriffsmodifikatoren wie <strong>private<\/strong>, <strong>public<\/strong> und <strong>protected<\/strong> realisiert, die die Sichtbarkeit von Klassenmitgliedern wie Feldern und Methoden steuern. Auf private Mitglieder kann nur innerhalb der gleichen Klasse zugegriffen werden, w\u00e4hrend auf \u00f6ffentliche Mitglieder \u00fcberall im Programm zugegriffen werden kann. Auf gesch\u00fctzte Mitglieder kann innerhalb der gleichen Klasse, von Unterklassen und von Klassen im gleichen Paket zugegriffen werden. Mit den get-Methoden des \u00f6ffentlichen Zugriffs k\u00f6nnen wir die in den Klassenmitgliedern gespeicherten Werte abrufen und mit den set-Methoden k\u00f6nnen wir sie \u00e4ndern und somit den alten Wert durch einen neuen Wert \u00fcberschreiben. Viele Programmierer sehen dies jedoch nur als<strong>Datenverstecken<\/strong> und sind verwirrt, warum wir nicht einfach jede Variable in einer Klasse als \u00f6ffentlich definieren und uns das Schreiben von Code f\u00fcr get- und set-Methoden ersparen.  <\/p>\n<p><u>Beispiel:<\/u><\/p>\n<p>Wenn wir eine Klasse Person und einen Variablennamen vom Typ <strong>String<\/strong> und ein Alter vom Typ <strong>int<\/strong> haben, k\u00f6nnten wir sie ohne Kapselung so schreiben und verwenden (Werte schreiben und lesen):<\/p>\n<pre><code class=\"language-java\" data-line=\"\">public class Osoba {\n    public String meno;\n    public int vek;\n}\nOsoba osoba = new Osoba();\nosoba.meno = &quot;Dominika&quot;;\nosoba.vek = 25;\nSystem.out.println(&quot;Meno: &quot; + osoba.meno);\nSystem.out.println(&quot;Vek: &quot; + osoba.vek);<\/code><\/pre>\n<p>Wenn wir eine \u00e4hnliche Klasse kapseln wollten, m\u00fcssten wir die Datenelemente verstecken, d.h. die Zugriffsmodifikatoren z.B. in private oder protected \u00e4ndern. In diesem Fall br\u00e4uchten wir jedoch zumindest get-Methoden zum Lesen und m\u00f6glicherweise set-Methoden zum Schreiben. Die gesamte Deklaration der Klasse wird gestreckt:   <\/p>\n<pre><code class=\"language-java\" data-line=\"\">public class Osoba {\n    private String meno;\n    private int vek;\n\n    public String getMeno() {\n        return meno;\n    }\n\n    public void setMeno(String meno) {\n        this.meno = meno;\n    }\n\n    public int getVek() {\n        return vek;\n    }\n\n    public void setVek(int vek) {\n        this.vek = vek;\n    }\n}\nOsoba osoba = new Osoba();\nosoba.setMeno(&quot;Dominika&quot;);\nosoba.setVek(25);\nSystem.out.println(&quot;Meno: &quot; + osoba.getMeno());\nSystem.out.println(&quot;Vek: &quot; + osoba.getVek());<\/code><\/pre>\n<p>Wenn man sich den Codeumfang beider Ans\u00e4tze ansieht, stellt sich die Frage, warum wir nicht einfach alles \u00f6ffentlich definieren und auf die Definition von get- und set-Methoden verzichten.<br \/>\nAber nehmen wir an, ein unaufmerksamer oder b\u00f6swilliger Benutzer gibt folgendes als Alter ein: person.age = -25; Logischerweise kann das Alter nicht negativ sein, aber das Programm wei\u00df das nicht. Es beachtet alle zul\u00e4ssigen Wertebereiche f\u00fcr den Datentyp int, also auch negative Werte. Das Einstellen der Daten ohne jegliche Pr\u00fcfung f\u00fchrt dann in der Regel zu Fehlern im Programm. Mit dem zweiten Ansatz k\u00f6nnen wir jedoch die set-Methode so \u00e4ndern, dass das Alter eine positive Zahl sein muss.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">public void setVek(int vek) {\n    if (vek &gt;= 0) {\n        this.vek = vek;\n    }\n}<\/code><\/pre>\n<p>Auf \u00e4hnliche Weise k\u00f6nnten wir den String-Wert f\u00fcr den vom Benutzer angegebenen Namen \u00fcberpr\u00fcfen.<\/p>\n<pre><code class=\"language-java\" data-line=\"\">public void setMeno(String meno) {\n    if(meno == null || meno.equals(&quot;&quot;)) {\n        throw new IllegalArgumentException(&quot;Meno musi obsahovat aspon 1 znak!&quot;);\n    }\n    this.meno = meno;\n}<\/code><\/pre>\n<p>Es gibt viele gute Gr\u00fcnde, warum es sinnvoll ist, Zugriffsmethoden (Accessors) anstelle des direkten Zugriffs auf die Felder einer Klasse zu verwenden. Schauen wir uns einige davon an:<\/p>\n<ul>\n<li>Durch die Kapselung in Verbindung mit get\/set-Methoden k\u00f6nnen wir sp\u00e4ter leichter zus\u00e4tzliche Funktionen hinzuf\u00fcgen (z. B. die Validierung, wie wir im Beispiel gesehen haben).<\/li>\n<li>Die set-Methode eignet sich hervorragend als Breakpoint f\u00fcr das Debugging, insbesondere wenn man nachvollziehen m\u00f6chte, wann eine Variable in der Klasse auf einen bestimmten Wert ge\u00e4ndert wird. Ohne sie w\u00e4re es recht schwierig, die \u00c4nderung zu lokalisieren, vor allem in einem gr\u00f6\u00dferen Programm mit vielen Zuweisungen. <\/li>\n<li>Die M\u00f6glichkeit f\u00fcr abgeleitete Klassen, die Semantik des Verhaltens und des Zugriffs auf ein Mitglied durch \u00dcberschreiben der Getter- und Setter-Methoden zu \u00e4ndern.<\/li>\n<li>Getter und Setter k\u00f6nnen unterschiedliche Zugriffslevel haben \u2013 zum Beispiel kann der Getter public sein, w\u00e4hrend der Setter protected ist.<\/li>\n<li>Verbesserte Interoperabilit\u00e4t mit Bibliotheken, die f\u00fcr die Arbeit mit Gettern\/Settern entwickelt wurden &#8211; wie Spring, Mocking, Serialisierung und viele andere.<\/li>\n<li>Erlaubt die \u00dcbergabe von Gettern\/Settern als Lambda-Ausdr\u00fccke anstelle von Werten.<\/li>\n<li>Die interne Darstellung einer Klasse kann sich \u00e4ndern und der Benutzer wird es nat\u00fcrlich nicht bemerken, wenn die \u00f6ffentliche Schnittstelle dieselbe bleibt.<\/li>\n<li>Die Kapselung erm\u00f6glicht es uns, eine Klasse und ihre Instanzen als unver\u00e4nderlich zu definieren (unver\u00e4nderlich nach der Erstellung der Instanz), ein Beispiel ist die Klasse String.<\/li>\n<li>Gew\u00e4hrleistung der Thread-Sicherheit durch Synchronisierung der Methode.<\/li>\n<\/ul>\n<p>Um unsere Klasse richtig zu kapseln, muss nicht jedes Datenelement automatisch eine get- und set-Methode enthalten. Wir f\u00fcgen diese nach Bedarf hinzu. Wenn die Klasse haupts\u00e4chlich funktionalen Code ausf\u00fchrt oder mit unver\u00e4nderlichen Objekten arbeitet, werden andere Accessor-Methoden definiert, als wenn sie mit zustandsabh\u00e4ngigen, ver\u00e4nderlichen Objekten arbeitet. Obwohl Programmieranf\u00e4nger durch das Schreiben von mehreren Zeilen Code entmutigt werden k\u00f6nnten, ist es sicherlich notwendig, sich an die Kapselung und die Verwendung von Accessor-Methoden zu gew\u00f6hnen. Viele Programmierumgebungen und Editoren bieten inzwischen Unterst\u00fctzung f\u00fcr die Generierung von get\/set-Methoden (entweder in der IDE oder als kostenlose Plug-ins), was die Auswirkungen dieses Problems bis zu einem gewissen Grad verringert. Wenn wir rein dateninvariante Klassen schreiben wollen, ist die Verwendung von <strong>Java Records<\/strong>, die wir <a href=\"https:\/\/msgprogramator.sk\/java-records\/\" target=\"_blank\" rel=\"noopener\">im letzten Artikel<\/a> behandelt haben, sehr einfach.  <\/p>\n<h2>Encapsulation vs data hiding<\/h2>\n<p>In der Objektwelt ist das Verstecken von Daten vor der Au\u00dfenwelt keine Kapselung, sondern nur ein notwendiger Teil davon. Das bedeutet, dass es bei der Kapselung nicht nur um die Definition von Zugriffs- und Mutationsmethoden f\u00fcr eine Klasse geht, sondern dass es sich um ein breiteres Konzept in der objektorientierten Programmierung handelt, das die Minimierung von Abh\u00e4ngigkeiten zwischen Klassen beinhaltet und in der Regel durch das Verbergen von Informationen umgesetzt wird. Ein richtig gekapseltes Objekt kapselt den Zustand und die Algorithmen zur Manipulation dieses Zustands. Es ist jedoch wichtig zu betonen, dass der Zustand nur gekapselt und durch Algorithmen manipuliert werden sollte, die vom Objekt selbst bereitgestellt werden. Das Sch\u00f6ne an der Kapselung ist die M\u00f6glichkeit, Dinge zu \u00e4ndern, ohne dass sich dies auf die Benutzer auswirkt. Das Ziel ist also nicht, die Daten selbst zu verbergen, sondern die Implementierungsdetails, wie diese Daten manipuliert werden. Die Hauptidee hinter der Kapselung besteht darin, eine \u00f6ffentliche Schnittstelle bereitzustellen, \u00fcber die der Benutzer auf diese Daten zugreifen kann. Sp\u00e4ter m\u00fcssen wir m\u00f6glicherweise die interne Darstellung der Daten \u00e4ndern, ohne dass dies Auswirkungen auf die Benutzer der bestehenden Schnittstelle hat. Wenn wir jedoch die Daten selbst verf\u00fcgbar machen, gef\u00e4hrden wir die Kapselung und damit die M\u00f6glichkeit, die Art und Weise, wie die Daten manipuliert werden, zu \u00e4ndern. Wir schaffen eine Abh\u00e4ngigkeit von den Daten selbst und nicht von der \u00f6ffentlichen Schnittstelle der Klasse, was fr\u00fcher oder sp\u00e4ter zu gro\u00dfen Problemen f\u00fchren wird. In Java k\u00f6nnen wir ganze Klassen ausblenden und so die Implementierungsdetails der gesamten API verbergen. Beispielsweise gibt die Methode Arrays.asList() eine Implementierung der Schnittstelle List zur\u00fcck, aber es ist uns egal, um welche Implementierung es sich handelt, solange sie die Schnittstelle List erf\u00fcllt (implementiert), richtig? Die Implementierung kann in Zukunft ge\u00e4ndert werden, ohne dass dies Auswirkungen auf die Benutzer dieser Methode hat, aber der Benutzer wird es wahrscheinlich nicht bemerken.   <\/p>\n<h2>Verkapselung und Abstraktion<\/h2>\n<p>Um das Konzept der Kapselung besser zu verstehen, ist es hilfreich, zun\u00e4chst die Abstraktion zu verstehen. Nehmen wir ein gew\u00f6hnliches Auto als Beispiel. Ein Auto besteht aus einer Reihe von Komponenten, \u00e4hnlich wie ein Programm. Es hat mehrere Untersysteme wie Getriebe, Bremsen, Kraftstoffsystem usw. Wir wissen, dass alle Autos ein Lenkrad haben, mit dem wir die Richtung steuern, sie haben ein Pedal, das, wenn es gedr\u00fcckt wird, das Auto beschleunigt und ein anderes, das, wenn es gedr\u00fcckt wird, das Auto stoppt. Dann gibt es noch den Schalthebel, mit dem wir steuern k\u00f6nnen, ob wir vorw\u00e4rts oder r\u00fcckw\u00e4rts fahren. Diese Funktionen bilden die \u00f6ffentliche Schnittstelle der Autoabstraktion. \u00dcber diese \u00f6ffentliche Schnittstelle ihrer Abstraktion behandeln wir alle Autos auf der Welt auf dieselbe Weise. Wir k\u00f6nnen morgens ein Auto fahren und dann aussteigen und am Nachmittag ein anderes Auto fahren, als ob es dasselbe Auto w\u00e4re. Aber nur wenige von uns kennen die Details, wie all diese Funktionen unter der Motorhaube implementiert sind. Eines Tages werden wir vielleicht ein Elektroauto kaufen, bei dem ein Gro\u00dfteil der Komponenten unter der Motorhaube weggefallen ist, dessen Steuersystem (d.h. die \u00f6ffentliche Schnittstelle) aber gleich geblieben ist, und deshalb werden wir es fast sofort fahren k\u00f6nnen. Wenn jedoch z.B. das Lenkrad durch die Sprachsteuerung eines selbstfahrenden Autos ersetzt wird (wir haben die etablierte Schnittstelle ge\u00e4ndert), m\u00fcssen wir erst wieder lernen, wie wir das neue Auto benutzen. Wie in diesem Beispiel zu sehen ist, besteht das Ziel der Kapselung darin, Abh\u00e4ngigkeiten zu minimieren und \u00c4nderungen zu erleichtern. Wir maximieren die Verkapselung, indem wir die Details der Implementierung f\u00fcr den Benutzer so wenig wie m\u00f6glich offenlegen. Der Zustand der Klasse sollte nur \u00fcber die \u00f6ffentliche Schnittstelle zug\u00e4nglich sein.    <\/p>\n<h2>Vorteile der Verkapselung<\/h2>\n<p><strong>Sicherheit:<\/strong> Die Kapselung tr\u00e4gt zur Sicherheit des Codes bei, indem sie sicherstellt, dass andere Entit\u00e4ten (Klassen, Schnittstellen usw.) keinen direkten Zugriff auf die Daten haben. <strong>Flexibilit\u00e4t:<\/strong> Durch die Kapselung wird der Code flexibler, was wiederum dem Programmierer erm\u00f6glicht, den Code leicht zu \u00e4ndern oder zu aktualisieren. <strong>Kontrolle:<\/strong> Die Kapselung erm\u00f6glicht die Kontrolle \u00fcber die in Mitgliedsvariablen gespeicherten Daten. <strong>Wiederverwendbarkeit:<\/strong> Gekapselter Code oder Einheiten k\u00f6nnen \u00fcberall in der Anwendung oder in v\u00f6llig anderen Programmen wiederverwendet werden, ohne dass der Code neu geschrieben werden muss. Praktisch alle Bibliotheken funktionieren auf diese Weise. <strong>Wartbarkeit:<\/strong> Gekapselte Komponenten sind einfach zu warten, weil wir Dinge leicht finden oder \u00e4ndern k\u00f6nnen.<\/p>\n<h2>Fazit<\/h2>\n<p>Die Kapselung ist ein fundamentaler Konzept objektorientierter Sprachen, das die Kombination von Daten und Methoden sowie die Steuerung des Zugriffs darauf umfasst. Sie nutzt dabei die Datenverbergung, die darauf abzielt, den direkten Zugriff auf bestimmte Daten oder Methoden einzuschr\u00e4nken. Ebenso wird eine Abstraktionsschicht eingesetzt, die dem Benutzer eine \u00f6ffentliche Schnittstelle bietet, ohne dass er den internen Zustand der Kapsel \u2013 der Encapsulation \u2013 kennen muss.  <\/p>\n<p>Wenn du ein <a href=\"https:\/\/msg-life.sk\/de\/stellenangebote\/java-entwickler-senior\/\" target=\"_blank\" rel=\"noopener\">Java Programmierer<\/a> bist und nach Arbeit suchst, schau dir unsere <a href=\"https:\/\/msg-life.sk\/de\/mitarbeiter-benefits\/\" target=\"_blank\" rel=\"noopener\">Mitareiterbenefits <\/a> an und reagiere auf die <a href=\"https:\/\/msg-life.sk\/de\/stellenangebote\/\" target=\"_blank\" rel=\"noopener\">neuesten Stellenangebote<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Im Artikel erkl\u00e4ren wir dir, was Kapselung (Encapsulation) in Java ist, warum du sie verwenden solltest, welche Vorteile sie bietet und wie die Beziehung zwischen Kapselung und Abstraktion aussieht.<\/p>\n","protected":false},"author":14,"featured_media":4694,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[62],"tags":[],"class_list":["post-4881","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/posts\/4881","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/users\/14"}],"replies":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/comments?post=4881"}],"version-history":[{"count":2,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/posts\/4881\/revisions"}],"predecessor-version":[{"id":5738,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/posts\/4881\/revisions\/5738"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/media\/4694"}],"wp:attachment":[{"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/media?parent=4881"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/categories?post=4881"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msgprogramator.sk\/de\/wp-json\/wp\/v2\/tags?post=4881"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}