Ich verstehe, was öffentlich, privat und geschützt ist. Ich weiß, dass Sie sie verwenden sollten, um das Konzept der objektorientierten Programmierung zu erfüllen, und ich weiß, wie Sie sie in einem Programm implementieren, das mehrere Klassen verwendet.
Meine Frage ist: Warum machen wir das? Warum sollte ich nicht eine Klasse haben, die die globalen Variablen einer anderen Klasse direkt verändert? Und selbst wenn Sie nicht sollten, warum sind die geschützten, privaten und öffentlichen Modifikatoren sogar notwendig? Es ist, als ob Programmierer sich nicht trauen, es nicht zu tun, obwohl sie das Programm schreiben.
Vielen Dank im Voraus.
Sie haben recht, weil wir uns nicht selbst vertrauen können. Veränderlicher Zustand ist ein Hauptfaktor in der Komplexität von Computerprogrammen, es ist zu einfach, etwas zu bauen, das zunächst in Ordnung scheint und später außer Kontrolle gerät, wenn das System größer wird. Die Einschränkung des Zugriffs hilft dabei, die Möglichkeiten zu verringern, dass sich die Zustände von Objekten auf unvorhersehbare Weise ändern. Die Idee ist, dass Objekte über klar definierte Kanäle miteinander kommunizieren können, anstatt die Daten der anderen direkt zu optimieren. Auf diese Weise haben wir die Hoffnung, die einzelnen Objekte zu testen und ein gewisses Vertrauen darin zu haben, wie sie sich als Teil eines größeren Systems verhalten werden.
Lassen Sie mich ein einfaches Beispiel geben (dies dient nur der Illustration):
%Vor% Alles sieht gut aus und du bist glücklich. Später haben Sie erkannt, dass andere Entwickler oder Ihre andere API, die Sie zum Setzen des Wertes verwenden, auf 0
eingestellt sind und dies zu einer Exception in Ihrer Bar.process()
-Funktion führt.
Nun können Sie laut der obigen Implementierung nicht verhindern, dass Benutzer den Wert auf 0 setzen. Sehen Sie sich nun die folgende Implementierung an.
%Vor%Nicht nur Sie können jetzt überprüfen, sondern auch eine informative Ausnahme geben, die hilft, Fehler schnell und in einem frühen Stadium zu erkennen.
Dies ist nur eines der Beispiele, die Grundlagen von OOP (Encapsulation, Abstraction etc.), die Ihnen helfen, die Oberfläche zu standardisieren und die darunter liegende Implementierung zu verbergen.
Beachten Sie, dass der Entwickler, der eine bestimmte Klasse codiert, möglicherweise nicht der einzige ist, der sie verwendet. Entwicklerteams schreiben Softwarebibliotheken, die in Java üblicherweise als JARs vertrieben werden und von völlig unterschiedlichen Entwicklerteams verwendet werden. Wenn diese Standards nicht vorhanden wären, wäre es für andere sehr schwierig, zumindest zu wissen, was die beabsichtigten Variablen / Methoden sind.
Wenn ich zum Beispiel eine private / protected-Instanzvariable habe, kann ich eine öffentliche "Setter" -Methode haben, die nach Gültigkeit, Vorbedingungen und anderen Aktivitäten sucht - alles was umgangen würde, wenn jemand frei wäre, das zu modifizieren Instanzvariable direkt.
Ein weiterer guter Punkt ist in der Java Dokumentation / Anleitung: Ссылка :
Öffentliche Felder neigen dazu, Sie mit einer bestimmten Implementierung zu verbinden und Beschränken Sie Ihre Flexibilität beim Ändern Ihres Codes.
Meine Frage ist: Warum machen wir das?
Grundsätzlich, weil wir uns dadurch einschränken machen wir es einfacher ... für uns selbst und andere, die den Code in der Zukunft lesen / ändern müssen ... um das zu verstehen Code und die Art, wie die verschiedenen Teile interagieren.
Die meisten Entwickler verstehen Code durch einen mentalen Abstraktionsprozess; d. h. mental Zeichnen von Grenzen um Code-Bits, Verstehen jedes einzelnen Bits und dann Verstehen, wie jedes Bit mit anderen Bits interagiert. Wenn ein Teil des Codes möglicherweise mit den "Innereien" eines anderen Teils des Codes in Konflikt kommt, dann ist es für den typischen Entwickler schwierig zu verstehen, was vor sich geht.
Dies ist möglicherweise kein Problem für Sie, während Sie den Code schreiben, weil Sie möglicherweise alle komplexen Interaktionen in Ihrem Kopf behalten können, während Sie den Code erstellen. Aber in ein oder zwei Jahren werden Sie viele Details vergessen haben. Und andere Leute hatten niemals die Details in ihren Köpfen.
Warum sollte ich nicht eine Klasse haben, die die globalen Variablen einer anderen Klasse direkt verändert?
Weil es Ihren Code schwerer verständlich macht; siehe oben. Je größer Ihre Codebasis ist, desto ausgeprägter ist das Problem.
Ein weiterer Punkt ist, dass wenn Sie überbezahlte Globals verwenden (eigentlich statische), dann Probleme entstehen, wenn Ihr Code multi-threaded / reentrant sein muss, für Komponententests und wenn Sie Ihren Code in anderen Kontexten wiederverwenden müssen.
Und selbst wenn Sie nicht sollten, warum sind die geschützten, privaten und öffentlichen Modifikatoren sogar notwendig? Es ist, als ob Programmierer sich nicht trauen, es nicht zu tun, obwohl sie das Programm schreiben.
Es geht nicht um Vertrauen. Es geht darum, im Quellcode auszudrücken, wo die Grenzen liegen.
Wenn ich eine Klasse schreibe und eine Methode oder ein Feld private
deklariere, weiß ich, dass ich nicht auf das Problem achten muss, was passiert, wenn eine andere Klasse sie aufruft / darauf zugreift / ändert. Wenn ich jemanden Code lese, weiß ich, dass ich die private
Teile beim Zuordnen der Interaktionen und Grenzen (anfänglich) ignorieren kann. Die Modifikatoren private
und protected
und package private nur
bieten unterschiedliche Granularitäten der Grenze.
(Oder vielleicht geht es um Vertrauen; d. h. nicht vertrauend selbst zu erinnern wo die Abstraktionsgrenzen in unserem Design sind / waren.)
Es gibt im Wesentlichen zwei Gründe:
1) In Java gibt es Schnittstellen, wo Sicherheit erforderlich ist. Wenn Sie beispielsweise ein Java-Applet auf Ihrer Box ausführen, möchten Sie sicherstellen, dass das Applet nicht auf Teile des Dateisystems zugreifen kann, für die es nicht autorisiert ist. Ohne eindringliche Sicherheit könnte ein Applet in die Java-Sicherheitsebene gelangen und seine eigenen Berechtigungen ändern.
2) Selbst wenn jeder "vertraut" ist, übertrifft Zweckmäßigkeit manchmal den gesunden Menschenverstand, und Programmierer umgehen APIs, um auf interne Schnittstellen zuzugreifen, anstatt die APIs zu verbessern (was zugegebenermaßen oft länger dauern kann als praktisch). Dies führt zu Problemen sowohl für die Stabilität als auch für die Upgrade-Kompatibilität.
(Es gibt eine Legende, tief in der uralten Geschichte der Computerverarbeitung, eines Betriebssystems, das von den Anwendungsprogrammierern so behandelt wurde, dass die Programmierer, die das Betriebssystem pflegten, gezwungen waren, bestimmte Codeabschnitte zu sichern Punkte, aber die tatsächlichen internen Codefolgen) änderten die physikalischen Adressen nicht, als das Betriebssystem überarbeitet wurde.)
Beachten Sie, dass diese Probleme vor der Einführung des OOP-Paradigmas bestanden und einige der Gründe für OOP sind. OOP ist keine willkürliche religiöse Doktrin, die aus dem Nichts erfunden wurde, sondern ist eine Reihe von Prinzipien, die durch etwa 6 Jahrzehnte Programmiererfahrung gefiltert wurden.