Wenn wir über Setter und Getter auf die privaten Mitglieder zugreifen können, wozu dient dann der Begriff "privat"?
Antworten
Zu viele Anzeigen?Sie brauchen die Private, um die Kapselung durchzusetzen. Es ist eines der grundlegenden Paradigmen der objektorientierten Programmierung, die Implementierung von etwas getrennt von der Schnittstelle zu halten. Dies reduziert die Kopplung zwischen den verschiedenen Programmteilen und macht das Programm auf lange Sicht wartungsfreundlicher.
Nehmen Sie das folgende Beispiel:
class toto {
private String someThing;
public String getSomething();
public void setSomething(String Something);
}
Wenn Sie oben ändern, um someThing einfach öffentlich zu machen, haben Sie zwar weniger Code, aber wenn eines Tages dieses someThing zu einem komplexeren Objekt für eine neue Funktionalität geändert werden muss, während der alte Code immer noch gut mit einer Zeichenkette funktionieren könnte, müssen Sie alles ändern. Indem man die interne Repräsentation von someThing isoliert, kann man sein System viel einfacher weiterentwickeln
class toto {
private ComplexSomeThing someThing;
public String getSomething(){ someThing.toString();}
public void setSomething(String something){ something = new ComplexSomeThing(something);}
public ComplexSomeThing (getComplexSomething();
public void setComplexSomething(ComplexSomething someThing);
}
Es gibt noch andere Gründe, warum Kapselung eine gute Sache ist, dies ist nur ein dummes Beispiel, um den Punkt zu illustrieren.
EDIT Es gibt derzeit eine Debatte über die Verwendung von protected vs. private oder die Verwendung von Konzepten, die in einigen Sprachen (Delphi, C#) den Eigenschaften ähneln, anstelle von getters und setters (wie in Java). Geschützt statt privat ermöglicht einfachere Änderungen durch die Kunden des Codes, legt aber das Innenleben des Systems stärker offen, so dass ein Gleichgewicht zwischen der Nutzbarkeit der API und ihrer Wartbarkeit angestrebt werden muss. Das Grundprinzip der Kapselung bleibt jedoch bestehen. Unabhängig von der gewählten Option muss die Funktionalität kohärent und auf der gleichen Abstraktionsebene offengelegt werden und die blutigen Details, wie dies geschieht, verborgen bleiben.
Für mich geht es in der Debatte nicht darum, einen Dschihad gegen die Privatwirtschaft auszurufen, sondern einen Weg zu finden, Erweiterbarkeit und Flexibilität zu bieten, ohne die Kohärenz der API zu zerstören.
Hier einige interessant über Privatpersonen zu lesen, wenn Sie mehr wissen wollen. Ich muss jedoch betonen, dass Sie, bevor Sie sich eine Meinung über Private bilden, die folgenden Konzepte wirklich beherrschen sollten Verkapselung y Polymorphismus hinter ihrer scheinbaren Einfachheit verbergen sich jedoch einige subtile Komplexität .
Denn die Getter und Setter können als Proxy fungieren. Sie sorgen dafür, dass Sie das eigentliche Innere der Klasse verbergen können und die äußeren Klassen nur über Methoden auf die Daten zugreifen können. So können Sie das Innere der Klasse behandeln, wie Sie wollen.
Nur weil Ihr Getter/Setter den Namen getName()
und Ihre Eigenschaft heißt name
Das heißt aber nicht, dass es immer so sein wird.
Was wäre, wenn Sie die Variable so ändern wollten, dass sie fullName
. Wenn Sie direkt auf öffentliche Variablen zugreifen würden, würde die Änderung einen Großteil des Codes zerstören. Stattdessen können Sie einfach neu zuordnen, wo getName()
seine Daten abruft.
Eines meiner besten Beispiele dafür ist meine eigene URL-Klasse, in der ich die Erstellung und Bearbeitung einer URL erlaube. Wenn Sie das Schema festlegen möchten, können Sie $obj->setScheme()
. Sie wissen jedoch nicht, ob ich die Zeichenkette jedes Mal, wenn Sie die URL ändern, manuell anlege oder ob ich sie als separate Teile speichere. Das gibt mir Flexibilität, denn ich kann Ihre Daten speichern, wie ich will.
Außerdem kann ich die Daten vor dem Speichern manipulieren. In meiner URL-Klasse gehe ich davon aus, dass alle Schemata und Hostnamen klein geschrieben werden. Ich kann dies standardisieren, indem ich alle Zeichenketten, die über setHost()
in Kleinbuchstaben umwandeln und sie dann speichern. Würde ich eine öffentliche Variable verwenden, müssten Sie davon ausgehen, dass der Client, der die Daten eingegeben hat, diese auch korrekt speichert.
Sie können auch Informationen validieren, um sicherzustellen, dass es sich um gültige Daten handelt, und im gegenteiligen Fall einen Fehler verursachen.
Niemand zwingt Sie dazu, Getter und Setter für jede Variable einzufügen. In der Tat ist es sinnlos, blind private Mitglieder + Dummy-Getter und -Setter für jede Variable zu verwenden, auch wenn viele Tutorials zur "objektorientierten Kapselung" dies aus irgendeinem Grund ständig tun. Zum einen ist eine solche Verkapselung keine Verkapselung aus Sicht der Gleichzeitigkeit.
Ich denke, was Sie wirklich verstehen wollen, ist, warum wir öffentliche Eigenschaften mit privaten Hintergrundfeldern verwenden, anstatt nur öffentliche Felder zu verwenden. Es gibt mehrere Fragen zu SO wie diese; hier ist eine:
Was ist der Unterschied zwischen einem Feld und einer Eigenschaft in C#?
Ich denke, Sie haben bisher gute Antworten gegeben (Informationen verstecken und so weiter). Ich möchte nur einen Vorschlag zur Verwendung von Setzern hinzufügen.
Wie Sie bereits erwähnt haben, macht die Verwendung von Accessoren private Variablen ein wenig sinnlos und in einigen Umgebungen macht die Verwendung von Gettern und Settern die Leistung einfach wertlos.
Auf der anderen Seite, wenn Sie nicht über solche Bedenken, ich denke, mit Getter ist nicht so schlecht, aber Sie sollten zweimal überlegen, bevor Sie Setter. Sie machen Ihr Objekt änderbar was in konkurrierenden Umgebungen besonders schwer zu bewerkstelligen ist.