2010-07-17 5 views
7

Jedes Mal, wenn ich triviale Getter schreibe (Funktionen holen, die nur den Wert des Members zurückgeben), frage ich mich, warum Sprachen nicht einfach einen 'Nur lesen'-Zugriffsmodifikator haben, der es erlaubt, den Wert der Member des Objekts zu lesen erlaubt es nicht, sie genau wie const in C++ zu setzen.Warum haben OOP-Sprachen keinen Zugriffsmodifizierer, der nur gelesen werden kann?

Die privaten, geschützten, öffentlichen Zugriffsmodifikatoren bieten entweder vollen (Lese-/Schreib-) Zugriff oder keinen Zugriff.

Einen Getter zu schreiben und jedes Mal aufzurufen, ist langsam, weil das Funktionsaufrufen langsamer ist als nur auf ein Mitglied zuzugreifen. Ein guter Optimierer kann diese Getter-Aufrufe optimieren, aber das ist "Magie". Und ich denke nicht, dass es eine gute Idee ist zu lernen, wie ein Optimierer eines bestimmten Compilers funktioniert, und Code zu schreiben, um ihn zu nutzen.

Warum also müssen wir in der Praxis Accessoren schreiben, nur Schnittstellen lesen, wenn nur ein neuer Zugriffsmodifikator das tun würde?

PS1: Bitte sagen Sie nicht Dinge wie "Es würde die Kapselung brechen". Eine öffentliche foo.getX() und eine öffentliche, aber nur lesen foo.x würde das gleiche tun.

EDIT: Ich habe meinen Beitrag nicht klar geschrieben. Es tut uns leid. Ich meine, Sie können den Wert des Mitglieds außerhalb lesen, aber Sie können es nicht einstellen. Sie können den Wert nur innerhalb des Klassenbereichs festlegen.

+4

Ihre ps1 macht die Annahme, dass ein Property Getter immer eine einfache Kapselung einer Feldvariablen ist, was nicht immer der Fall ist. Zum Beispiel könnte der Eigenschaften-Getter eine Berechnung sein, die mehrere Felder, eine Verkettung von Feldern usw. enthält. Der Eigenschaften-Getter kapselt die Logik und daher kann die interne Implementierung leicht geändert werden. –

+0

Als Antwort auf Ihre Bearbeitung passt die Antwort von Marcelo Cantos perfekt zu Ihrem Bedarf. – BoltClock

Antwort

11

Sie verallgemeinern falsch von einer oder mehreren OOP-Sprache (n), die Sie kennen, in OOP-Sprachen im Allgemeinen. Einige Beispiele für Sprachen, die implementieren Nur-Lese-Attribute:

  • C# (Danke, Darin und Tonio)
  • Delphi (= Object Pascal)
  • Rubin
  • Scala
  • Objective-C (Dank , Rano)
  • ... mehr?

Persönlich bin ich genervt, dass Java das nicht hat (noch?). Wenn man das Feature in anderen Sprachen gesehen hat, scheint das Schreiben von Texten in Java ermüdend zu sein.

+1

Zählt Javas "final"? – BoltClock

+1

@BoltClock: Guter Punkt, aber ein letztes Feld hat nicht dieselbe Semantik wie eine schreibgeschützte Eigenschaft. Letzteres erlaubt der Klasse normalerweise eine private Hintertür, um den zugrunde liegenden Wert zu ändern, während die Kapselung gegen die Außenseite gesichert bleibt, was ein netter Vorteil sein kann. 'final' ist ... final. –

+0

Wenn Javas "final" nicht zählt, sollte Scalas "val" ebenfalls nicht zählen. – missingfaktor

0

C# -Eigenschaften ermöglichen das einfache Definieren von schreibgeschützten Eigenschaften. Siehe hierzu article.

2

C# hat readonly, Java und einige andere haben final. Sie können diese verwenden, um Ihre Membervariablen schreibgeschützt zu machen.

In C# können Sie einfach einen Getter für Ihre Eigenschaft angeben, sodass er nur gelesen, nicht geändert werden kann.

private int _foo; 

public int Foo 
{ 
    get { return _foo; } 
} 
+2

public int Foo {bekommen; private set;} ist eine andere Möglichkeit, dies zu erreichen. Ohne die zusätzliche Deklaration – btlog

2

Eigentlich sind sie nicht gleich. Public foo.getX() würde weiterhin zulassen, dass der interne Klassencode in die Variable schreibt. Eine schreibgeschützte foo.x wäre auch für den internen Klassencode schreibgeschützt.

Und es gibt einige Sprachen, die solche Modifikator haben.

+0

Es scheint in C# readonly bedeutet, dass Sie die Variable in der Klasse noch ändern können, aber von außen ist es readonly (http://msdn.microsoft.com/en-us/library/acdd6hb7%28VS.71 % 29.aspx). – Frank

+1

C# schreibgeschützte Felder können nur einmal in der Deklaration oder im Konstruktor zugewiesen werden. –

5

In C# können Sie eine automatische Eigenschaft mit unterschiedlichen Zugriffs-Qualifikation auf dem Set definieren und erhalten:

public int Foo { get; private set; } 

Auf diese Weise kann die Klasse Umsetzung seiner Herzenslust mit der Eigenschaft herumzubasteln, während Client-Code kann lies es nur.

0

In Delphi:

strict private 
    FAnswer: integer; 
public 
    property Answer: integer read FAnswer; 

Deklariert eine schreibgeschützte Eigenschaft Antwort, die private Bereich FAnswer zugreift.

0

Die Frage läuft im Wesentlichen darauf hinaus: warum hat nicht jede Sprache eine konstante Eigenschaft wie C++? Dies ist

, warum es nicht in C#:

Anders Hejlsberg: Ja. In Bezug auf const, es ist interessant, weil wir diese Beschwerde die ganze Zeit zu hören: "Warum hast du const?" Implizit in der Frage ist, "Warum haben Sie const, die durch die Laufzeit erzwungen wird?" Das ist wirklich was Leute fragen, obwohl sie nicht kommen und es so sagen.

Der Grund, dass Konst in C++ funktioniert, ist , weil Sie es wegwerfen können. Wenn du es nicht wegwerfen könntest, dann würde deine Welt lutschen. Wenn Sie eine Methode deklarieren, die eine Const Bla nimmt, könnten Sie es eine nicht-const Bla übergeben. Aber wenn es die anders herum ist, können Sie nicht. Wenn Sie deklarieren eine Methode, die eine nicht-const Bla nimmt, können Sie es nicht const Bla übergeben. Jetzt bist du festgefahren. So brauchen Sie allmählich eine const-Version von alles, was nicht const ist, und Sie am Ende mit einer Schattenwelt. In C++ gehen Sie mit davon weg, denn wie bei ist alles in C++ rein optional , ob Sie diese Prüfung wollen oder nicht. Sie können einfach die Konstanz weg whack, wenn Sie es nicht mögen.

See: http://www.artima.com/intv/choicesP.html

Also, der Grund wy const in C++ gewohnt ist, weil man es umgehen kann. Das ist sinnvoll für C++, das seine Wurzeln in C.

hat. Für verwaltete Sprachen wie Java und C# würden Benutzer erwarten, dass const genauso sicher wäre wie etwa der Garbage Collector. Das bedeutet auch, dass Sie nicht umgehen können, und es wird nicht nützlich sein, wenn Sie nicht umgehen können.

+0

Dieser Typ kennt C++ eindeutig nicht. Es ist wahr, dass man const wegwerfen kann, aber es ist unglaublich selten, das jemals tatsächlich zu tun. – Puppy

+0

@DeadMG: Wenn ich in der Google-Codesuche suche, erhalte ich 32000 Treffer für const_cast. Als Benchmark: dynamic_cast bekommt fast 60000. Also nicht nur ich und Anders, die denken, dass sie const_cast brauchen. –

+0

Notwendigkeit ist nicht gleich, Informationen darüber zu wollen, oder denke, dass du es brauchst, wenn du es nicht tust. Die Anzahl der Ergebnisse in einer Suchmaschine ist eine wirklich, wirklich irrelevante Metrik. Wenn Sie 5 Millionen Zeilen Code grepped und festgestellt, dass es häufig vorkam, würde das anders sein. – Puppy

Verwandte Themen