Warum die Verwendung von Getter und setter/Accessoren?
Was ist der Vorteil der Verwendung von Getter und setter - dass nur get-und set - anstatt einfach mit öffentlichen Felder für die Variablen?
Wenn Getter und setter sind, jemals mehr als nur die einfache get - /set, kann ich diese Figur ein, sehr schnell, aber ich bin mir nicht 100% klar wie:
public String foo;
ist schlimmer als:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
In der Erwägung, dass der ehemalige nimmt viel weniger boilerplate code.
J: Duplizieren mit vielen anderen Fragen: stackoverflow.com/search?q=getters+setters
Natürlich sind beide gleich schlecht, wenn sich das Objekt nicht eine Eigenschaft, geändert werden. Ich würde lieber alles privat, und fügen Sie get, wenn Sie nützlich sind und setter, wenn nötig.
Google "- Accessoren sind böse"
"Accessoren sind böse", wenn Sie geschehen, zu schreiben funktionaler code oder unveränderliche Objekte. Wenn Sie geschehen, zu schreiben stateful mutable-Objekte sind, dann sind Sie ziemlich unerlässlich.
Sagen, nicht Fragen. pragprog.com/articles/tell-dont-ask
Natürlich sind beide gleich schlecht, wenn sich das Objekt nicht eine Eigenschaft, geändert werden. Ich würde lieber alles privat, und fügen Sie get, wenn Sie nützlich sind und setter, wenn nötig.
Google "- Accessoren sind böse"
"Accessoren sind böse", wenn Sie geschehen, zu schreiben funktionaler code oder unveränderliche Objekte. Wenn Sie geschehen, zu schreiben stateful mutable-Objekte sind, dann sind Sie ziemlich unerlässlich.
Sagen, nicht Fragen. pragprog.com/articles/tell-dont-ask
InformationsquelleAutor Dean J | 2009-10-14
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es gibt tatsächlich viele gute Gründe zu prüfen, mit Accessoren anstatt direkt auszusetzen Felder einer Klasse - außer eben das argument der Kapselung und um zukünftige änderungen zu erleichtern.
Hier sind einige der Gründe, die mir bekannt sind:
Ich glaube
public
accessor-Methoden bewirken, dass code-Duplizierung, und Informationen verfügbar gemacht werden. Öffentliche Zugriffsmethoden sind nicht notwendig für das marshalling (Serialisierung). In einigen Sprachen (Java)public
get-Accessor kann nicht über den Rückgabetyp geändert, ohne zu brechen abhängigen Klassen. Darüber hinaus glaube ich, dass Sie gegen die OO-Prinzipien. Siehe auch: stackoverflow.com/a/1462424/59087Eine Sache, die gekauft wird, indem eine Eigenschaft setter, auch in einem gut gestalteten Rahmen, ist die Fähigkeit zu haben, ein Objekt zu Benachrichtigen, eine andere, wenn eine Eigenschaft ändert.
Allerdings bin ich mir nicht, im Allgemeinen, die Förderung der öffentlichen Daten. Benachrichtigung anderer Objekte können auch aus realen Methoden und somit eine erhebliche Abstraktion auf eine Reine Daten-container mit (mehr oder weniger) öffentlichen Datenfelder. Statt
plane.turnTo(dir); plane.setSpeed(spd); plane.setTargetAltitude(alt); plane.getBreaks().release();
möchte ich sagenplane.takeOff(alt)
. Was die innere Daten-Felder geändert werden müssen, um das Flugzeug in dietakingOff
- Modus ist nicht mein Anliegen. Und welche anderen Objekte (breaks
) die Methode weist ich will nicht wissen, entweder.Ich weiß wirklich nicht, wie sonst, es zu sagen. "Zugriffsmethoden" ist nur ein synonym für "Getter/setter", und in meinen ersten beiden Kommentare, die ich erklärt, warum jene, die ein Missbrauch der Begriff "OOP". Wenn Sie brauchen, um zu erreichen in und Sie manipulieren den Staat direkt, es ist nicht ein Objekt in der OOP-Sinne des Begriffs.
InformationsquelleAutor LBushkin
Weil 2 Wochen (Monate, Jahre) von nun an, wenn Sie merken, dass Ihre setter muss mehr als nur der Wert gesetzt wird, werden Sie auch feststellen, dass das Eigentum verwendet wurde, direkt in 238 andere Klassen 🙂
Ich kann nur neidisch auf Sie und Ihre app 🙂 Das heißt, es hängt wirklich davon ab, Ihre software-stack als auch. Delphi, zum Beispiel (und C# - denke ich?!) können Sie Eigenschaften definieren, die als 1. Klasse-Bürger, wo Sie nur können Lesen / schreiben, ein Feld direkt zunächst aber - sollten Sie es brauchen - dies über getter - / setter-Methoden als gut. Mucho bequem. Java, leider, nicht, nicht zu erwähnen die javabeans-standard, welche Kräfte Sie Getter / setter sowie.
Dies ist zwar in der Tat einen guten Grund für die Verwendung von Zugriffsmethoden, viele Entwicklungsumgebungen und Editoren bieten nun Unterstützung für refactoring (entweder in der IDE oder als kostenloses add-ins), die etwas reduziert die Auswirkungen des Problems.
klingt wie pre-Reife-Optimierung
Die Frage, die Sie stellen müssen, wenn Sie sich Fragen, ob die Implementierung von get-und Set-Methoden besteht: Warum sollten Sie die Benutzer einer Klasse zugreifen zu können, müssen Sie die Klasse' Innereien überhaupt? Es ist eigentlich egal, ob Sie es tun, direkt oder abgeschirmt durch eine dünne pseudo-Ebene — wenn die Benutzer benötigen Zugriff auf die Implementierungsdetails, dann ist das ein Zeichen, dass die Klasse nicht bieten genug Abstraktion. Siehe auch diesem Kommentar.
InformationsquelleAutor ChssPly76
Einem öffentlichen Feld ist nicht schlimmer als eine getter - /setter-pair-Mädchen, die nichts tut, außer die Rücksendung der Feld-und zugewiesen. Erstens, es ist klar, dass (in den meisten Sprachen) gibt es keinen funktionalen Unterschied. Irgendeinen Unterschied muss in anderen Faktoren, wie beispielsweise die Wartbarkeit oder Lesbarkeit.
Einen oft genannten Vorteil der getter - /setter-Paare, nicht. Es gibt diese Behauptung, dass Sie können ändern Sie die Implementierung und Ihre Kunden müssen nicht neu kompiliert werden. Angeblich, Set-Methoden ermöglichen das hinzufügen von Funktionen wie Validierung später auf und Ihre Kunden nicht einmal kennen müssen. Jedoch, hinzufügen von Validierung zu einem setter ist eine änderung der Voraussetzungen, eine Verletzung des vorhergehenden Vertrages, das war ganz einfach, "Sie können alles, was in hier, und Sie bekommen können, dass die gleiche Sache später aus dem getter".
So, jetzt, dass Sie brach den Vertrag, ändern Sie jede Datei in der codebase ist etwas, das sollten Sie tun wollen, nicht zu vermeiden. Wenn Sie es vermeiden, Sie machen die Annahme, dass der gesamte code davon ausgegangen, der Vertrag für diese Methoden war anders.
Sollte das nicht der Vertrag, dann die Schnittstelle ermöglichen den Kunden, um das Objekt in ungültige Zustände. , Dass das genaue Gegenteil der Kapselung Wenn das Feld konnte nicht richtig eingestellt werden, um alles von Anfang an, warum nicht die Validierung von Anfang an dabei?
Diese gleiche argument gilt auch für andere angebliche Vorteile dieser pass-through-getter/setter-Paare: wenn Sie später entscheiden, um den Wert zu ändern gesetzt ist, du brichst den Vertrag. Wenn Sie überschreiben die Standard-Funktionalität in einer abgeleiteten Klasse, in einer Art und Weise über ein paar Harmlose änderungen (wie die Protokollierung oder anderen nicht-beobachtbaren Verhalten), du brichst den Vertrag von der Basis-Klasse. Das ist ein Verstoß gegen das Liskov Substituierbarkeit-Prinzip, das als eines der Grundprinzipien der OO.
Wenn eine Klasse diese dumme Getter und setter für jedes Feld, dann ist es eine Klasse, die keine Invarianten auch immer, kein Vertrag. Ist das wirklich Objekt-orientierten design? Wenn alle die Klasse hat, ist diese Getter und setter, es ist nur eine dumme Daten Halter und stumm Daten-Inhaber sollten schauen, wie dumm die Daten-Inhaber:
Hinzufügen von pass-through-getter/setter-Paare diese Klasse fügt keinen Wert. Andere Klassen sollten aussagekräftige Operationen, nicht nur Vorgänge, die die Felder bereitstellen. Das ist, wie Sie definieren und pflegen Sie nützlich Invarianten.
Gibt es Gründe für die Verwendung von Getter und setter, aber wenn diese Gründe nicht vorhanden, die getter/setter-Paare, die im Namen des falschen Kapselung Götter ist nicht eine gute Sache. Gültige Gründe, um Getter oder setter die Dinge oft erwähnt, als mögliche änderungen können Sie später, wie die Validierung oder die verschiedenen internen Darstellungen. Oder vielleicht der Wert sollte gelesen werden von Kunden, aber nicht schreibbar ist (zum Beispiel, Lesen Sie die Größe eines Wörterbuchs), so dass eine einfache get-Methode ist eine gute Wahl. Aber diese Gründe sollten da sein, wenn Sie die Wahl treffen, und nicht nur als ein Potenzial, was Sie wollen vielleicht später. Dies ist ein Fall von YAGNI (Sie ist nicht Gonna Es Brauchen).
Dies ist eine große Antwort, aber leider die aktuelle Zeit vergessen hat, was "information hiding" ist oder was es ist. Sie nie gelesen Unveränderbarkeit und in Ihrem Streben für die meisten agile, nie zog, state-transition-Diagramm, definiert, was die rechtlichen Zustände eines Objekts wurden und somit, was nicht der Fall war.
Eine wichtige Beobachtung ist, dass Getter sind viel nützlicher als setter. Ein getter zurückkehren können einen berechneten Wert oder um eine zwischengespeicherte berechneten Wert. Alle Set-tun können, ist, einige Validierung und als das
private
Feld. Wenn eine Klasse keine setter ist es einfach, um es unveränderlich.Äh, ich denke, Sie weiß nicht, was für ein Klasse invariant ist. Wenn es eine nicht-triviale Struktur, es ziemlich viel bedeutet, es hat die Invarianten aufrecht zu erhalten und man kann einfach nicht design es ohne diesen im Auge. "Es war ein Fehler, ein Mitglied wurde aktualisiert falsch." auch ziemlich viel, liest sich wie "Ein Mitglied-update gegen die Klasse der Invarianten". Eine gut gestaltete Klasse nicht erlaubt, client-code zu verletzen, seine Invarianten.
+1 für 'dumb Daten-Inhaber sollten Aussehen wie dumm datenhaltern' Leider, jeder scheint zu design-alles rund um stumm Daten-Inhaber in diesen Tagen, und viele frameworks erfordern sogar...
InformationsquelleAutor R. Martinho Fernandes
Viele Menschen sprechen über die Vorteile von Getter und setter, aber ich will den Advocatus Diaboli spielen. Jetzt bin ich debugging ein sehr großes Programm, wo die Programmierer beschlossen, alles zu machen, dass Getter und setter. Das mag schön, aber es ist ein reverse-engineering Alptraum.
Sagen, Sie bist suchen durch Hunderte von Zeilen code, und Sie kommen über diese:
Ist es ein schön einfach Stück code, bis man sich klar macht, einen setter. Nun, Sie Folgen, dass Set-und feststellen, dass es auch sets person.firstName, person.lastName, person.isHuman, person.hasReallyCommonFirstName, und fordert die person.update(), die zum senden einer Abfrage aus der Datenbank, etc. Oh, wo ist das memory leak auftrat.
Verständnis ein lokales Stück code, das auf den ersten Blick ist eine wichtige Eigenschaft, eine gute Lesbarkeit, Getter und setter neigen dazu, zu brechen. Das ist, warum ich versuchen, Sie zu vermeiden, wenn ich kann, und minimieren Sie, was Sie tun, wenn ich Sie verwende.
Dies ist argument gegen die syntaktische Zucker, nicht gegen-setter im Allgemeinen.
True und wahr ist, aber darüber hinaus Punkte wie, warum einzelne Eigenschaft setter öffnen Sie die Tür für ungültige Zustände mit absolut kein Mittel zur Gewährleistung der Integrität von jedem beliebigen Objekt, das es ermöglicht die Abstraktion zu lecken.
"Es ist schön einfach Stück code, bis man sich klar macht, einen setter" - hey, das war die original-Beitrag über Java oder über C#? 🙂
Ich bin völlig einer Meinung bezüglich der Lesbarkeit. Es ist völlig klar, was passiert, wenn
person.name = "Joe";
genannt wird. Es gibt keine Reste in der Art der Informationen, syntax-highlighting zeigt, dass es ein Feld und refactoring einfacher ist (keine Notwendigkeit zur Umgestaltung von zwei Methoden und ein Feld). Zweitens, alle diese vergeudeten Gehirn-Zyklen denken "getIsValid()" oder sollte es sein, "isValid()" etc. vergessen werden kann. Ich kann nicht denken, der einzige eine Zeit, die ich habe gespeichert wurden, von einem Fehler durch eine getter - /setter.InformationsquelleAutor Kai
Gibt es viele Gründe. Mein Favorit ist, wenn Sie Sie brauchen, um das Verhalten oder die Regeln, was Sie können auf eine variable. Zum Beispiel können sagen, Sie hatte eine setSpeed(int speed) - Methode. Aber Sie wollen, dass Sie nur eine maximale Geschwindigkeit von 100. Sie würde so etwas machen:
Was nun, wenn ÜBERALL in Ihrem code, den Sie mit dem öffentlichen Feld-und dann erkannte man, müssen die genannten Anforderungen? Haben Sie Spaß, die Jagd nach jeder Benutzung des öffentlichen Feld anstatt nur zu ändern von Ihren setter.
My 2 cents 🙂
das stimmt natürlich, aber warum machen es schwieriger, als es entworfen wurde, zu sein. Die get - /set-Ansatz ist immer noch die bessere Antwort.
andere Verwendungen ist nicht das problem. Wechsel Ihnen allen ist.
ändern Sie alle ist ein Vorteil, nicht ein problem 🙁 Was ist, wenn Sie code, der angenommenen Geschwindigkeit könnte höher sein als 100 (weil, wissen Sie, bevor Sie brach den Vertrag, könnte es!) (
while(speed < 200) { do_something(); accelerate(); }
)Es ist ein SEHR schlechtes Beispiel! Jemand sollte rufen:
myCar.setSpeed(157);
und nach paar Zeilenspeed = myCar.getSpeed();
... Und jetzt möchte ich Sie gerne Debuggen, während Sie versuchen zu verstehen, warumspeed==100
sein, wenn es157
InformationsquelleAutor Peter D
In eine Reine Objekt-orientierte Welt Getter und setter ist ein schrecklichen anti-pattern. Lesen Sie diesen Artikel: Getter/Setter. Böse. Zeit. Kurz gesagt, Sie fördern die Programmierer zu denken, über Objekte als Daten-Strukturen, und diese Art des Denkens ist rein prozedurale (wie in COBOL oder C). In einer Objekt-orientierten Sprache gibt es keine Datenstrukturen, sondern nur Objekte, die aussetzen Verhalten (nicht die Attribute/Eigenschaften!)
Können Sie mehr darüber finden Sie in Abschnitt 3.5 Elegante Objekte (mein Buch über Objekt-orientierte Programmierung).
Interessante Sicht. Aber in den meisten Programmier-Kontexten, was wir brauchen, ist die Daten-Strukturen. Unter dem verlinkten Artikel - "Hund" - Beispiel. Ja, Sie können nicht ändern, in der realen Welt Hund das Gewicht durch die Vorgabe eines Attribut ... aber ein
new Dog()
ist nicht ein Hund. Es ist Objekt enthält Informationen über einen Hund. Und für die Verwendung, es ist natürlich in der Lage sein zu korrigieren einer falsch erfassten Gewichts.Gut, ich habe es Ihnen, dass die meisten nützliche Programme, die nicht brauchen, zu modellieren / simulieren realer Objekte. IMO, ist das nicht wirklich zu Programmiersprachen überhaupt. Es ist über was wir schreiben Programme für.
Realen Welt oder nicht, Jegor hat völlig Recht. Wenn das, was Sie haben, ist wirklich ein "Struct" und Sie nicht brauchen, um code schreiben, Verweise es durch den Namen, steckte es in eine Hash-Tabelle oder eine andere Datenstruktur. Wenn Sie brauchen, um code zu schreiben für Sie dann legen Sie es als Mitglied einer Klasse und setzen Sie den code, ändert, die variable in der selben Klasse und weglassen der setter - & get. PS. obwohl ich meistens teilen sich Jegor ' s Sicht, ich bin gekommen, zu glauben, dass annotierten beans ohne code sind etwas nützliche Daten-Strukturen-auch Getter sind manchmal notwendig, setter sollte nicht immer vorhanden.
Ich habe mich mitreißen lassen-diese gesamte Antwort, obwohl korrekt und relevant, nicht die Frage direkt. Vielleicht soll es auch sagen "Sowohl-als-setters/getters UND public-Variablen falsch"... Zu absolut bestimmten, Setter-und Schreibrechte für öffentliche Variablen sollten nie verwendet werden, in der Erwägung, dass Getter sind so ziemlich das gleiche wie public final Variablen und gelegentlich ein notwendiges übel, aber das ist auch nicht viel besser als die anderen.
InformationsquelleAutor yegor256
Einer der Vorteile von Accessoren und Mutatoren ist, können Sie die Validierung.
Zum Beispiel, wenn
foo
öffentlichkeit gab, konnte ich leicht einstellen, dass esnull
und dann jemand anderes könnte versuchen, rufen Sie eine Methode auf dem Objekt. Aber es ist nicht mehr da! Mit einemsetFoo
Methode, ich könnte dafür sorgen, dassfoo
war nie zunull
.Accessoren und Mutatoren auch ermöglichen Kapselung - wenn Sie nicht sehen sollte der Wert einmal seinen Satz (vielleicht ist es im Konstruktor und dann durch Methoden, aber nie soll geändert werden), es wird nie gesehen, von niemandem. Aber wenn Sie zulassen, dass andere Klassen zu sehen, oder ändern Sie es, Sie bieten die richtige accessor und/oder mutator.
InformationsquelleAutor Thomas Owens
Hängt von Ihrer Sprache. Sie gekennzeichnet haben diese "Objekt-orientiert" anstatt "Java", so möchte ich darauf hinweisen, dass ChssPly76 Antwort ist Sprachabhängig. In Python, zum Beispiel, gibt es keinen Grund für die Verwendung von Getter und setter. Wenn Sie brauchen, um das Verhalten, die Sie verwenden können, eine Eigenschaft, die wraps eine getter-und setter-rund-basic-Attribut zugreifen. So etwas wie dieses:
überhaupt nicht. Sie definieren Ihre "Schnittstelle" (öffentliche API wäre ein besserer Begriff hier), indem Sie Ihre öffentliche Felder. Sobald das erledigt ist, gibt es kein zurück mehr. Eigenschaften sind NICHT die Felder, denn Sie liefern einen Mechanismus zum abfangen versuche, auf Felder zuzugreifen (indem Sie zu Methoden, wenn diese definiert sind); das ist aber nichts weiter als syntax-Zucker über getter - / setter-Methoden. Es ist extrem bequem, aber es ändert nichts an der zugrunde liegenden Paradigma und setzen Felder mit keine Kontrolle über den Zugang zu Ihnen verstößt gegen das Prinzip der Kapselung.
nicht einverstanden. Ich habe nur so viel Kontrolle, als wären Sie Eigenschaften, denn ich kann diese Eigenschaften, wenn ich muss. Es gibt keinen Unterschied zwischen einer Eigenschaft, die verwendet boilerplate Getter und setter, und eine raw-Attribut, außer, dass die raw-Attribut ist schneller, weil es nutzt die zugrunde liegende Sprache, sondern als Aufruf von Methoden. Funktional sind Sie identisch. Der einzige Weg, Kapselung verletzt werden könnten ist, wenn Sie denken, dass Klammern (
obj.set_attr('foo')
) sind von Natur aus überlegen-gleich-Zeichen (obj.attr = 'foo'
). Öffentlichen Zugriff öffentlichen Zugriff.wie viel Kontrolle ja, aber nicht so viel Lesbarkeit, andere oft fälschlicherweise davon ausgehen, dass
obj.attr = 'foo'
stellt nur die variable, ohne das etwas anderes passiertWie ist das anders als ein Benutzer in Java vorausgesetzt, dass
obj.setAttr('foo')
"stellt nur die variable, ohne das etwas anderes passiert"? Wenn es eine öffentliche Methoden, dann ist es eine öffentliche Methode. Wenn Sie es verwenden, um zu erreichen, dass einige Nebenwirkungen, und es ist öffentlich, dann sollten Sie besser darauf verlassen können, dass alles funktioniert als wenn nur der beabsichtigte Nebeneffekt ist passiert (mit alle andere Implementierungsdetails und andere Nebenwirkungen, Einsatz von Ressourcen, was auch immer, versteckt den Nutzer betrifft). Das ist absolut nicht anders als mit Python. Python ist die syntax um die Wirkung zu erreichen, ist nur einfacher.InformationsquelleAutor jcdyer
Naja ich möchte nur hinzufügen, dass auch wenn Sie manchmal notwendig sind für die Verkapselung und den Schutz von Variablen/Objekte, wenn wir wollen, dass code eine echte Objekt-Orientiertes Programm, dann müssen wir STOPPEN ÜBERNUTZUNG DER ACCESSOREN, verursachen manchmal hängen wir eine Menge auf Sie wenn ist nicht wirklich notwendig und macht fast das gleiche, als wenn wir die Variablen public.
InformationsquelleAutor Jorge Aguilar
Dank, das ist wirklich geklärt, was ich denke. Hier ist nun (fast) 10 (fast) gute Gründe, NICHT zu verwenden, Getter und setter:
Den letzten drei bin ich gerade verlassen, (N/A oder D/C)...
InformationsquelleAutor
Ich weiß, es ist ein bisschen spät, aber ich denke, es gibt einige Leute, die interessiert sind, in der Leistung.
Ich habe mich ein wenig performance-test. Ich schrieb eine Klasse "NumberHolder", die gut, hält eine ganze Zahl. Sie können entweder Lesen, dass die ganze Zahl durch Verwendung der get-Methode
anInstance.getNumber()
oder durch direkten Zugriff auf die Nummer durchanInstance.number
. Mein programm liest die Anzahl 1,000,000,000 mal über beide Möglichkeiten. Dieser Prozess wiederholt sich fünf mal, und die Zeit gedruckt wird. Ich habe das folgende Ergebnis:(Zeitpunkt 1 ist der direkte Weg, Zeit 2 ist der getter)
Sehen Sie die get-Methode ist (fast) immer einen Tick schneller. Dann habe ich versucht mit einer unterschiedlichen Anzahl von Zyklen. Statt 1 Mio, habe ich 10 Millionen und 0,1 Millionen.
Die Ergebnisse:
10 Millionen Zyklen:
Mit 10 Millionen Zyklen, die Zeiten sind fast die gleichen.
Hier sind 100 tausend (0,1 Millionen) Zyklen:
Auch mit unterschiedlichen Mengen von Zyklen, die get-Methode ist ein wenig schneller als der normale Weg. Ich hoffe das hat dir geholfen.
InformationsquelleAutor kangalioo
Nicht verwenden, Getter-setter, soweit erforderlich, für Ihre aktuellen Lieferbedingungen I. e. Denke nicht zu viel über das, was in Zukunft passieren würde, wenn irgend etwas geändert werden, eine änderung seiner Anfrage in den meisten der Produktion, Anwendungen, Systeme.
Denke einfach, die Komplexität, wenn nötig.
Würde ich nicht nehmen, Vorteil der Unwissenheit von Besitzern der tiefen technischen wissen, nur weil ich denke, dass es richtig oder ich mag den Ansatz.
Habe ich massive system geschrieben, ohne Getter-setter nur mit zugriffsmodifizierer und einige Methoden zu validieren, n durchführen biz-Logik. Wenn Sie absolut nötig. Verwenden Sie alles.
InformationsquelleAutor Mohamed
Verbrachte ich eine Weile und dachte über diese für die Java-Falle, und ich glaube, die wirklichen Gründe sind:
In anderen Worten, der einzige Weg, können Sie ein Feld angeben, in ein interface ist durch die Bereitstellung einer Methode für das schreiben eines neuen Wertes und eine Methode zum Lesen des aktuellen Wertes.
Diese Methoden sind die berüchtigten getter und setter....
In jeden nicht-triviale Java-Projekt, das Sie brauchen, um code-Schnittstellen um, um die Dinge überschaubar und überprüfbar (denke Prototypen-und proxy-Objekte). Wenn Sie die Schnittstellen, die Sie benötigen, Getter und setter.
InformationsquelleAutor Thorbjørn Ravn Andersen
Kann es sinnvoll sein, für lazy-loading. Sagen Sie das Objekt in Frage ist in einer Datenbank gespeichert, und Sie wollen nicht zu gehen, es zu erhalten, es sei denn, Sie es brauchen. Wenn das Objekt abgerufen wird, indem ein getter ist, dann ist die interne Objekt kann null sein, bis jemand fragt, für Sie, dann können Sie gehen, es zu erhalten, die auf den ersten Aufruf der getter.
Hatte ich eine Basis-Seite-Klasse in einem Projekt, das wurde an mich übergeben, war laden einige der Daten aus ein paar verschiedene web-service-Aufrufe, die Daten aber in diese web-service-Aufrufe nicht immer auf alle Kind-Seiten. Web-services für alle Vorteile, pioneer, neue Definitionen von "slow", so dass Sie nicht wollen, um eine web-service-Aufruf, wenn Sie nicht haben, um.
Zog ich von öffentlichen Felder, Getter, und jetzt die Getter prüfen Sie den cache, und wenn es nicht da ist rufen Sie die web-service. Also mit ein wenig Geschenkpapier, eine Menge von web-service-Aufrufe verhindert wurden.
Also die getter-spart mir aus versuchen herauszufinden, auf jeder untergeordneten Seite, was ich brauche. Wenn ich es brauche, rufe ich die get-Methode, und es geht für mich zu finden, wenn ich nicht bereits haben.
Ich habe ein code-Beispiel, wie ich es getan habe in der Vergangenheit - im wesentlichen, Sie speichern die in der aktuellen Klasse in eine geschützte member, dann Rückkehr, geschützt Mitglied in der get-accessor, der Initialisierung, wenn es nicht initialisiert wurde.
was ist das? Definitiv nicht ausführbarer java-code ^^
Es ist C# docs.microsoft.com/en-us/dotnet/csharp/programming-guide/...
InformationsquelleAutor quillbreaker
Verwenden wir Getter und setter:
Getter-und setter-Methoden public sind Schnittstellen zum Zugriff auf Klassenelemente.
Kapselung mantra
Kapselung mantra ist, um Felder private und Methoden public.
Obwohl die getter-und setter-Methoden nicht neue Funktionalität hinzufügen, ändern wir unseren Geist kommen später wieder, um zu machen, die Methode
Überall einen Wert verwendet werden kann, eine Methode, die zurückgibt, die Wert Hinzugefügt werden kann. Statt:
verwenden
In juristischer Hinsicht
Nehmen wir an, wir müssen zum speichern der details dieses
Person
. DiesePerson
hat die Feldername
,age
undsex
. Dies zu tun beinhaltet das erstellen Methoden für diename
,age
undsex
. Wenn wir nun benötigen, erstellen Sie eine andere person, wird es notwendig, zu erstellen, die die Methoden für diename
,age
,sex
alle immer wieder.Statt dies zu tun, erstellen wir eine Bohne
class(Person)
mit getter-und setter-Methoden. Also morgen können wir nur die Objekte erstellen, die von dieser Beanclass(Person class)
Wann immer wir müssen zum hinzufügen einer neuen person (siehe die Abbildung). Also wir verwenden erneut die Felder und Methoden der bean-Klasse, die ist viel besser.InformationsquelleAutor Devrath
Einen Aspekt, den ich vermisst in den Antworten so weit, der Zugriff Spezifikation:
InformationsquelleAutor jdehaan
In den Sprachen, die nicht unterstützen "Eigenschaften" (C++, Java) oder recompilierung von Kunden, beim ändern der Felder-Eigenschaften (C#), mit get/set-Methoden einfacher zu ändern. Zum Beispiel durch hinzufügen von Validierungslogik, um eine Methode setFoo nicht verlangen, dass sich die öffentliche Schnittstelle einer Klasse.
In den Sprachen, die Unterstützung der "realen" Eigenschaften (Python, Ruby, vielleicht Smalltalk?) es gibt keine Punkt-zu-get - /set-Methoden.
sorry, falsch getippt. Ich meinte, dass die Klienten der Klasse neu übersetzt werden müssen.
Hinzufügen Validierungslogik, um eine Methode setFoo erfordern keine änderung der Schnittstelle einer Klasse auf Sprachniveau, aber es ändert die aktuelle Schnittstelle, auch bekannt als Vertrag, weil es ändert die Voraussetzungen. Warum würde man wollen, dass der compiler nicht behandeln, als breaking change wenn es?
wie macht man das "broken" - problem? Der compiler kann nicht sagen, ob es bricht oder nicht. Dies ist nur ein Problem, wenn Sie schreiben, die Bibliotheken für andere, aber du machst es als universal-zOMG hier werden Drachen!
Erfordert Neukompilierung, wie bereits in der Antwort ist ein Weg, der compiler kann machen Sie Kenntnis von einem möglichen brechen ändern. Und fast alles, was ich Schreibe, ist effektiv "eine Bibliothek für andere", weil ich nicht allein arbeiten. Ich code schreiben, der hat Schnittstellen, die andere Menschen in das Projekt verwenden wird. Was ist der Unterschied? Hölle, auch wenn ich die Benutzer von diesen Schnittstellen, warum sollte ich dann meinen code zu niedrigeren Qualitätsstandards? Ich weiß nicht, wie die Arbeit mit schwierigen Schnittstellen, auch wenn ich bin derjenige der Sie schreibt.
InformationsquelleAutor John Millikin
EDIT: ich beantwortete diese Frage, denn es gibt eine Reihe von Menschen, erlernen der Programmierung gefragt, und die meisten Antworten sind sehr fachlich kompetent, aber Sie sind nicht so leicht zu verstehen, wenn du bist ein Neuling. Wir waren alle Neulinge, so dass ich dachte, ich würde versuchen, meine hand auf eine mehr Anfänger freundlich.
Die zwei wichtigsten sind Polymorphismus und Validierung. Auch wenn es nur eine dumme Datenstruktur.
Sagen wir, wir haben diese einfach Klasse:
Einer sehr einfachen Klasse, der hält, wie viel Flüssigkeit in ihm ist, und was seine Kapazität (in Millilitern).
Was passiert, wenn ich tun:
Gut, Sie würden nicht erwarten, zu arbeiten, Recht?
Sie wollen dort eine Art Plausibilitätsprüfung. Und noch schlimmer, was wenn ich nie angegeben ist die maximale Kapazität? Oh je, wir haben ein problem.
Aber es gibt ein anderes problem zu. Was ist, wenn die Flaschen waren nur eine Art container? Was ist, wenn man mehrere Container, die alle mit Kapazitäten und Mengen von Flüssigkeit gefüllt? Falls wir könnte gerade eine Schnittstelle, wir konnten den rest unseres Programms akzeptieren, dass die Schnittstelle, und Flaschen, jerrycans und alle Arten von Sachen, die nur funktionieren würde, interchangably. Wäre das nicht besser? Da Schnittstellen demand " Verfahren, dies ist auch eine gute Sache.
Würden wir am Ende mit etwas wie:
Toll! Und jetzt ändern wir eben die Flasche:
Lasse ich die definition der BottleOverflowException als übung für den Leser.
Nun bemerken, wie viel mehr robust ist. Wir umgehen können mit jeder Art von container, in der unser code wird nun durch die Annahme LiquidContainer statt der Flasche. Und wie diese Flaschen befassen sich mit diese Art von Sachen können, die sich alle unterscheiden. Sie können die Flaschen, die schreiben Ihre Zustand auf die Festplatte, wenn es sich verändert, oder die Flaschen, sparen, SQL-Datenbanken oder GNU weiß was sonst noch.
Und alle diese können unterschiedliche Möglichkeiten zum Umgang mit verschiedenen whoopsies. Die Flasche gerade überprüft, und wenn es ist überfüllt, es wirft eine RuntimeException. Aber das wäre die falsche Sache zu tun.
(Es ist eine nützliche Diskussion über Fehlerbehandlung, aber ich halte es sehr einfach ist hier am Ziel. Die Leute in den Kommentaren wird wahrscheinlich darauf hinweisen, die Mängel dieses einfachen Ansatz. 😉 )
Und ja, es scheint, wir gehen von einer sehr einfachen Idee zu bekommen, viel besser schnell Antworten.
Gibt es auch noch die Dritte Sache, die nicht jeder hat angesprochen: Getter und setter Methode aufruft. Das bedeutet, dass Sie Aussehen wie normale Methoden überall sonst funktioniert. Anstatt seltsame spezifische syntax für die DTOs und die Sachen, Sie haben die gleiche Sache überall.
"Sie können die Flaschen, die Schriftsteller Ihren Zustand auf der Festplatte, wenn es sich verändert, oder die Flaschen, die speichern auf SQL-Datenbanken" ich räkelte so schwer xD. Aber egal, nette Idee, es zu präsentieren!
InformationsquelleAutor Haakon Løtveit
Eines der Grundprinzipien der OO-design: Kapselung!
Gibt es Ihnen viele Vorteile, einer davon ist, dass Sie können ändern Sie die Implementierung der get - /Set-hinter den kulissen, aber alle Verbraucher, die Wert sind, weiter zu arbeiten, solange der Datentyp bleibt die gleiche.
Wenn Sie Ihre öffentliche Schnittstelle, die besagt, dass 'foo' ist vom Typ 'T' und kann alles, was man nie ändern kann. Sie können nicht letzteres entscheiden, um es von Typ "Y", noch können Sie zu verhängen Regeln, wie die Größe Einschränkungen. Also, wenn Sie öffentliche get/set -, die nichts zu tun viel set/get, Sie gewinnen nichts, dass ein öffentliches Feld nicht bieten und machen es eher umständlich zu bedienen. Wenn Sie eine Einschränkung, wie kann das Objekt auf null gesetzt werden, oder der Wert innerhalb eines Bereichs ist, dann ja, einer öffentlichen set-Methode erforderlich wäre, aber Sie stellen immer noch ein Vertrag, die von der Einstellung dieser Wert nicht ändern können
Warum kann nicht einen Vertrag ändern?
Warum sollten Dinge, die halten Sie auf kompilieren, wenn Verträge ändern?
InformationsquelleAutor Justin Niessner
Vom Objekt Orientierung, design-Sicht die beiden alternativen, die schädlich sein können, um die Wartung des Codes durch die Schwächung der Kapselung der Klassen. Für eine Diskussion blickt man in diesem ausgezeichneten Artikel: http://typicalprogrammer.com/?p=23
InformationsquelleAutor andrers52
Sollten Sie verwenden, Getter und setter, wenn:
So ist dies sehr selten eine Allgemeine Frage OO; es ist eine Sprache-spezifische Frage, verschiedene Antworten für verschiedene Sprachen und verschiedene use-cases).
Vom OO-Theorie Sicht, Getter und setter sind nutzlos. Die Schnittstelle der Klasse ist, was er tut, nicht, was sein Zustand ist. (Wenn nicht, die du geschrieben hast die falsche Klasse.) In sehr einfachen Fällen, wo das, was eine Klasse tut, ist nur, z.B., stellen Sie einen Punkt in rechtwinkligen Koordinaten,* die Attribute sind Teil der Schnittstelle; Getter und setter nur cloud. Aber in alles, aber sehr einfachen Fällen, weder die Attribute noch die Getter und setter sind Teil der Schnittstelle.
Anders ausgedrückt: Wenn Sie glauben, dass die Verbraucher von Ihrer Klasse gar nicht wissen, dass Sie eine
spam
Attribut, viel weniger in der Lage, es zu ändern, wohl oder übel, dann gibt Ihnen einset_spam
Methode ist das Letzte, was Sie tun möchten.* Auch für, einfach Klasse, die Sie nicht unbedingt wollen, es zulassen, dass die
x
undy
Werte. Wenn das ist wirklich Klasse, sollte es nicht haben Methoden wietranslate
,rotate
usw.? Wenn es nur eine Klasse, weil Sie Ihre Sprache nicht haben, records/structs/named Tupel, dann ist dies nicht wirklich eine Frage OO...Aber niemand ist jemals Allgemeine OO-design. Sie sind dabei design und Implementierung, die in einer bestimmten Sprache. Und in einigen Sprachen, Getter und setter sind weit Weg von nutzlos.
Wenn Ihre Sprache nicht die Eigenschaften haben, die dann der einzige Weg, etwas zu repräsentieren, das ist konzeptionell ein Attribut, aber tatsächlich berechnet oder validiert, etc., ist durch Getter und setter.
Selbst wenn Ihre Sprache nicht Eigenschaften haben, kann es Fälle geben, wo Sie sind unzureichend oder unangemessen. Zum Beispiel, wenn Sie möchten, dass Sie in Unterklassen zu kontrollieren, die Semantik eines Attributs, in Sprachen ohne dynamische Zugang, eine Unterklasse kann nicht ersetzen, eine berechnete Eigenschaft für ein Attribut.
Als für die "was will ich ändern meine Implementierung später?" - Frage (wiederholt sich mehrmals in verschiedenen Formulierungen in beiden OP ' s Frage und die akzeptierte Antwort): Wenn es sich wirklich um eine Reine Implementierung zu ändern, und Sie begann mit einem Attribut, können Sie es ändern, um eine Eigenschaft, ohne die Schnittstelle. Es sei denn, natürlich, Ihre Sprache nicht unterstützt. Also das ist wirklich genau der gleiche Fall wieder.
Es ist auch wichtig, um die Ausdrücke der Sprache (oder der Rahmen), die Sie verwenden. Wenn Sie schreiben, schönes Rubin-Stil-code in C#, jeder erfahrene C# - Entwickler, außer Sie wird Schwierigkeiten haben, es zu Lesen, und das ist schlecht. Einige Sprachen haben ein stärkeres Kulturen rund um Ihre Konventionen als andere.—und es kann kein Zufall sein, dass Java und Python, die sind an entgegengesetzten enden des Spektrums, wie idiomatische Getter sind, geschehen zu haben, zwei der stärksten Kulturen.
Jenseits der menschlichen Leserinnen und Leser, gibt es Bibliotheken und tools erwarten, dass Sie Folgen den Konventionen, und machen Ihr das Leben schwer, wenn Sie nicht. Anschließen der Interface Builder widgets, alles andere als ObjC Eigenschaften, oder der Nutzung bestimmter Java mocking-libraries ohne Getter, nur macht Ihr das Leben schwer. Wenn die Werkzeuge sind wichtig für Sie, nicht gegen Sie kämpfen.
InformationsquelleAutor abarnert
Getter-und setter-Methoden accessor-Methoden, was bedeutet, dass Sie sind in der Regel eine öffentliche Schnittstelle zu ändern Klassenelemente. Verwenden Sie getter-und setter-Methoden zu definieren, eine Eigenschaft. Sie Zugriff auf getter-und setter-Methoden für Eigenschaften außerhalb der Klasse, obwohl Sie definieren Sie innerhalb der Klasse als Methoden. Diese Eigenschaften außerhalb der Klasse einen anderen Namen haben kann aus der Eigenschaft name in der Klasse.
Es gibt einige Vorteile der Verwendung von getter-und setter-Methoden, wie die Fähigkeit zu lassen, erstellen Sie die Mitglieder mit ausgefeilten Funktionen, die Sie zugreifen können, wie die Eigenschaften. Sie können auch erstellen, nur-Lesen und nur-schreiben-Eigenschaften.
Obwohl getter-und setter-Methoden sind hilfreich, Sie sollten vorsichtig sein, nicht zu Häufig zu Ihnen, weil, unter anderem, können Sie den code Wartung schwieriger, in bestimmten Situationen. Auch Sie ermöglichen den Zugang zu Ihrer Klasse Umsetzung, wie öffentliche Mitglieder. OOP-Praxis rät direkten Zugriff auf die Eigenschaften innerhalb einer Klasse.
Beim schreiben von Klassen, werden Sie immer ermutigt, so viele wie möglich von Ihrer Instanzvariablen private und fügen Sie getter-und setter-Methoden entsprechend. Dies ist weil es gibt mehrere Zeiten, wenn Sie nicht wollen, um Benutzern die änderung bestimmter Variablen innerhalb Ihrer Klassen. Zum Beispiel, wenn Sie eine private statische Methode, die verfolgt die Anzahl der erzeugten Instanzen für eine bestimmte Klasse, die Sie nicht möchten, dass ein Benutzer zu ändern, den Zähler mit code. Nur die Konstruktor-Anweisung sollte Inkrementieren Sie die variable, wenn es aufgerufen wird. In dieser situation, könnten Sie eine private Instanz-variable und erlauben eine get-Methode nur für die counter-variable, was bedeutet, Anwender sind in der Lage, zum abrufen des aktuellen Werts nur durch Verwendung der get-Methode, und Sie werden nicht in der Lage, neue Werte durch setter-Methode. Erstellen einer getter-ohne eine Set ist eine einfache Möglichkeit, bestimmte Variablen in Ihrer Klasse "nur Lesen".
InformationsquelleAutor Sumit Singh
Code entwickelt sich.
private
ist groß, wenn Sie benötigen Daten, die Mitglied Schutz. Schließlich werden alle Klassen sollten eine Art "miniprograms", die haben eine gut definierte Schnittstelle , dass man nicht einfach die Schraube mit dem Innenleben von.Sagte, software-Entwicklung ist nicht etwa festgelegt, dass die endgültige version der Klasse, als wenn Sie drücken einige Gusseisen-statue auf dem ersten Versuch. Während Sie mit ihm arbeiten, code ist mehr wie Lehm. Es entwickelt sich, wie Sie es zu entwickeln, und erfahren Sie mehr über die problem domain, die Sie für die Lösung sind. Während der Entwicklung können Klassen miteinander interagieren, als Sie sollten (Abhängigkeit, die Sie planen, um den Faktor aus), miteinander verschmelzen oder sich aufspalten. Also ich denke, die Debatte läuft darauf hinaus, die Menschen nicht wollen, um religiös zu schreiben
So haben Sie:
Statt
Ist nicht nur
getVar()
visuell laut, es gibt diese illusion, dassgettingVar()
ist irgendwie ein komplexerer Vorgang, als es wirklich ist. Wie Sie (wie die Klasse writer) hinsichtlich der Heiligkeit desvar
ist besonders verwirrend, wenn ein Benutzer Ihrer Klasse, wenn es einen passthru-setter -- dann sieht es aus wie Sie setzen diese Tore zu "schützen", etwas, das Sie darauf bestehen, ist wertvoll, (die Heiligkeitvar
), aber dennoch sogar Sie zugeben, dass dievar
's Schutz nicht viel Wert durch die Möglichkeit für jedermann, einfach kommen undset
var
zu was auch immer Wert, den Sie möchten, ohne dass Sie selbst einsehen, was Sie tun.Damit ich das Programm wie folgt (davon ausgehend, dass eine "agile" Ansatz, -- dh wenn ich code schreiben, nicht zu wissen genau, was Sie tun werden/haben keine Zeit oder Erfahrung, um zu planen eine aufwendige Wasserfall-Stil-Schnittstelle einstellen):
1) Beginnen Sie mit allen öffentlichen Mitglieder für basic-Objekte mit Daten und Verhalten. Dies ist der Grund, warum in allen mein C++ - "Beispiel" - code, den Sie bemerken mich mit
struct
stattclass
überall.2) Wenn ein Objekt das interne Verhalten für ein Datenelement wird Komplex genug ist, (zum Beispiel, es mag eine interne
std::list
in irgendeine Art von Bestellung), accessor-Typ Funktionen geschrieben werden. Denn ich bin der Programmierung von mir selbst, dass ich nicht immer die Mitgliedprivate
richtigen Weg, aber irgendwo im Laufe der evolution der Klasse werden dem Mitglied "befördert" werden, um entwederprotected
oderprivate
.3) Klassen, die sind komplett ausgearbeitet und haben strenge Regeln über Ihre Struktur (ie Sie genau wissen, was Sie tun, und Sie sind nicht zu "ficken" (technischer Begriff) mit seinen Einbauten) werden die
class
Bezeichnung, default, private Mitglieder, und nur ein paar ausgewählte Mitglieder werden dürfenpublic
.Ich finde dieses Vorgehen ermöglicht es mir, zu vermeiden, dort zu sitzen und religiös zu schreiben getter/setter, wenn eine Menge von Daten, die Mitglieder kommen aus migriert, verschoben, usw werden. während der frühen Stadien einer Klasse ist evolution.
InformationsquelleAutor bobobobo
Gibt es einen guten Grund zu prüfen, mit Accessoren ist keine Eigenschaft der Vererbung. Siehe Nächstes Beispiel:
Ausgabe:
InformationsquelleAutor GeZo
Einer anderen Verwendung (in Sprachen, die Unterstützung properties), die setter und Getter kann bedeuten, dass eine operation ist nicht-trivial. In der Regel möchten Sie vermeiden, etwas zu tun, das ist rechnerisch teuer, in einer Eigenschaft.
execute
oderbuild
Methode.InformationsquelleAutor Jason Baker
Getter und setter werden verwendet, um die Implementierung von zwei der grundlegenden Aspekte der objektorientierten Programmierung sind:
Nehmen wir an, wir haben eine Employee-Klasse:
Hier die details der Implementierung der Vollständige Name, ist vor dem Benutzer verborgen und ist nicht direkt zugänglich für den Benutzer, im Gegensatz zu einem public-Attribut.
Der Vorteil dabei ist, dass Sie können ändern, die Interna der Klasse, ohne änderung der Schnittstelle. Sagen, anstelle der drei Eigenschaften, Sie hatte eins - ein array von strings. Wenn Sie schon die Verwendung von Getter und setter, Sie können das ändern, und aktualisieren Sie dann die getter/setter zu wissen, dass die Namen[0] ist der erste name, Namen[1] ist die Mitte, usw. Aber wenn Sie nur die öffentlichen Eigenschaften, Sie würde auch jede Klasse zugegriffen Mitarbeiter, weil die firstName-Eigenschaft, die Sie verwendet haben, existiert nicht mehr.
InformationsquelleAutor Pritam Banerjee
Einem relativ modernen Vorteil der get - /Set-Methoden ist, dass macht es einfacher zu navigieren code in tagged (indexiert) code-Editoren. E. g. Wenn Sie möchten, um zu sehen, wer Mitglied ist, können Sie öffnen Sie die Aufrufhierarchie der setter.
Auf der anderen Seite, wenn das Mitglied der öffentlichkeit, die tools machen es nicht möglich zu filtern, Lesen/schreiben Zugriff auf das Element. So haben Sie zu stapfen, obwohl alle Verwendungen des Mitglieds.
InformationsquelleAutor Rakesh Singh
In einer Objekt-orientierten Sprache die Methoden und Ihre zugriffsmodifizierer, die erklären, die Schnittstelle für das Objekt. Zwischen den Konstruktor und accessor-und mutator-Methoden ist es möglich, für das der Entwickler den Zugriff auf den internen Zustand eines Objekts. Wenn die Variablen einfach als public deklariert, dann gibt es keine Möglichkeit zu regulieren, dass der Zugang.
Und wenn wir mit setter, wir können einschränken, die Benutzer für die Eingabe, die wir brauchen. Meine den feed für dieses sehr variable wird durch einen ordnungsgemäßen Kanal und der Kanal ist von uns vordefiniert. Also ist es sicherer, zu verwenden setter.
InformationsquelleAutor Antz
Darüber hinaus ist dies zu "future-proof" Ihrer Klasse. Insbesondere der Wechsel von einem Feld, einer Eigenschaft ist eine ABI-Pause, so dass, wenn Sie später entscheiden, dass Sie brauchen mehr Logik als nur "set/get the field", dann müssen Sie brechen ABI, was natürlich Probleme schafft, für alles andere bereits kompiliert gegen Ihre Klasse.
muss nicht immer sein. TBYS
InformationsquelleAutor Pete
Ich würde nur gerne werfen die Idee der annotation : @getter und @setter. Mit @get, Sie sollten in der Lage sein zu obj = Klasse.Feld, aber nicht Klasse.field = obj. @Setter, Umgekehrt. Mit @getter und @setter-Sie sollten in der Lage sein, beides zu tun. Dies würde zu bewahren Kapselung und die Zeit verringern, die durch den Aufruf nicht trivialen Methoden zur Laufzeit.
Heute ist diese kann getan werden, mit einer Anmerkung zum Präprozessor.
InformationsquelleAutor fastcodejava