Vorwort
Der Titel "Das Problem der Reduzierung der Zugänglichkeit von Unterklassen gegenüber übergeordneten Klassenfunktionen in Java und C ++" scheint akademischer zu sein, aber es ist in der Tat ein Problem, das leicht zu ignorieren ist. Dieser Artikel bemüht sich, den Unterschied zwischen dieser Ausgabe in Java und C ++ zu nähern.
Zunächst werden wir vorstellen, was "Subklassen" -Regleichte zur Abdeckung der übergeordneten Klassenfunktionen ist. Für die Vererbung können Unterklassen die "virtuellen Funktionen" der übergeordneten Klasse überschreiben - obwohl es in Java keine virtuellen Funktionen gibt, können alle Java -Funktionen als virtuelle Funktionen angesehen werden, da alle Java -Funktionen durch Unterklassen überschrieben werden können. Hier leihen wir uns nur die Bedeutung des Begriffs "virtuelle Funktion" aus und streichen nicht auf die Details der Sprache ein. Sowohl Java als auch C ++ ermöglichen die Änderung der Zugänglichkeit von Funktionen bei Überschreiben. Die sogenannte "Barrierefreiheit" besteht darin, Zugriffskontrollzeichen wie öffentlich, geschützt und privat zu verwenden, um zu steuern, ob auf die Funktion zugegriffen werden kann. Normalerweise ist die Reihenfolge der Zugänglichkeit (da in C ++ kein Konzept von Paketen vorhanden ist, wird die Zugriffskontrolle des Pakets vorerst nicht berücksichtigt, was die Diskussion hier nicht beeinflusst):
öffentlich> geschützt> privat
Nehmen Sie Java als Beispiel:
Klasse Base {Protected void SayShello () {System.out.println ("Hallo in Basis"); }} Klasse Child erweitert Basis {public void SayShello () {System.out.println ("Hallo in Kind"); }} Hinweis: Die Funktion sayHello() hier. In der übergeordneten Klassenbasis wird diese Funktion mithilfe des geschützten Zugriffskontrollzeichens geändert. Und Unterklassen verwenden stattdessen öffentlich, es wird kein Problem geben. Wenn Unterklassen übergeordnete Klassenfunktionen überschreiben, ist die Erweiterung der Zugänglichkeit normalerweise kein Problem.
Java und C ++ verfolgen unterschiedliche Strategien, wenn Unterklassen die Zugänglichkeit über die Funktionen der Elternklassen reduzieren.
Nehmen Sie zunächst Java als Beispiel und sehen Sie sich den folgenden Code an:
Klasse Base {public void SayShello () {System.out.println ("Hallo in Basis"); }} Klasse Child erweitert Basis {private void SayShello () {System.out.println ("Hallo in Child"); }}Im obigen Code gibt es in der hervorgehobenen Zeile 8 einen Kompilierungsfehler - dieser Code kann überhaupt nicht kompiliert werden! Java erlaubt nicht zu, Unterklassen zu verringern, wenn die Überschreibung der Elternklassen die Zugänglichkeit verringert. Wie aus den Gründen können wir ein Beispiel zur Veranschaulichung verwenden. Zum Beispiel schreiben wir den folgenden Code außerhalb der Klasse:
Base Base = new Base (); Base.sayhello (); Base = New Child (); Base.sayhello ();
Wenn der vorherige Code kompiliert werden kann, besteht die Möglichkeit, dass, wenn Basis auf New Base () auftritt, Sayhello () zugegriffen werden kann, aber wenn Basis auf New Child () () auftritt, kann Sayhello () nicht zugegriffen werden! Nach Ansicht von Java ist dies ein Widerspruch, und dieses Problem sollte vermieden werden. Daher sieht Java aus der Perspektive des Compilers fest, dass wir den obigen Code nicht schreiben können.
Für C ++ ist die Situation anders. Schauen wir uns C ++ - Beispiel an:
Klasse Base {public: virtual void SayShello () {std :: cout << "Hallo in der Basis"; }} Klasse Child: öffentliche Basis {privat: void SayShello () {std :: cout << "Hallo in Kind"; }}Dieser Code ist in C ++ vollständig korrekt. Beachten Sie, dass die Unterklasse hier die Zugänglichkeit verringert, wenn die Überklassenfunktionen überschreiben. Wenn Sie kein Problem sehen, können wir den folgenden Code außerhalb der Klasse schreiben:
Kinderkind; Kind.Sayhello (); // kann nicht kompiliert werden, weil SayShello () die static_cast <base &> (Kind) ist .Sayhello (); // kann nicht zusammengestellt werden, weil Sayshello () öffentlich ist
Der Anruf von Zeile 2 schlägt fehl, weil sayHello() im Kind privat ist und nicht extern genannt werden kann. Wenn wir jedoch ein Kind mit static_cast an das Basisobjekt werfen, ändert sich die Dinge - für Basis ist sayHello() öffentlich, sodass es normal genannt werden kann.
Zu diesem Zweck finden Sie das folgende Beispiel im Abschnitt "Zugriff auf virtuelle Funktionen" des Kapitels zur Zugriffskontrolle von C ++ Standardmitgliedern:
Klasse B {public: virtual int f ();}; Klasse d: public b {privat: int f ();}; void f () {d d; B* pb = & d; D* pd = & d; pb-> f (); // ok: b :: f () ist öffentlich, d :: f () wird auf pd-> f () aufgerufen; // Fehler: D :: f () ist privat}In dieser Hinsicht gibt der C ++ - Standard eine Erklärung an:
Der Zugriff wird am Rufpunkt unter Verwendung des Typs des Ausdrucks überprüft, mit dem das Objekt bezeichnet wird, für das die Mitgliedsfunktion aufgerufen wird (B* im obigen Beispiel). Der Zugriff der Mitgliedsfunktion in der Klasse, in der sie definiert wurde (D im obigen Beispiel), ist im Allgemeinen nicht bekannt.
Es gibt zwei wichtige Punkte für eine einfache Übersetzung:
Aus diesem Grund scheinen C ++ Callers in der Lage zu sein, "geschickt" aufzurufen, die ursprünglich durch einige geschickte Transformationen nicht zugänglich waren. Ein praktischeres Beispiel ist: In QT ist QObject::event() öffentlich, und seine Funktion subklasse qwidget event() wird in geschützt geändert. Details können Sie den entsprechenden QT -Code lesen.
Zusammenfassend lässt sich sagen, dass Java, wenn Unterklassen übergeordnete Funktionen überschreiben, streng begrenzt, dass Unterklassen die Funktionsgrad -Zugänglichkeit nicht einschränken können, C ++ diese Einschränkung jedoch nicht. Persönlich glaube ich, dass aus der Sicht des Software -Engineering die Java -Vorschriften zweifellos mehr technische Bedeutung haben und die Aufrufe von Funktionen konsistenter sind. Der C ++ - Standard vereinfacht die Compiler -Implementierung erheblich, ist jedoch keine gute Referenz für das Engineering.
PS: Die offizielle Version des C ++ - Standards erfordert den Kauf, der Entwurf kann jedoch kostenlos heruntergeladen werden. Die Download-Adresse des C ++-Standardentwurfs finden Sie auf der folgenden Seite: https://isocpp.org/std/the-standard
Zusammenfassen
Das obige ist der gesamte Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Referenzwert für das Studium oder die Arbeit eines jeden hat. Wenn Sie Fragen haben, können Sie eine Nachricht zur Kommunikation überlassen. Vielen Dank für Ihre Unterstützung bei Wulin.com.