Menu
Coddy logo textTech

Zugriffsstufen bei Vererbung

Teil des Abschnitts Objektorientierte Programmierung der C++-Journey von Coddy — Lektion 49 von 104.

Die von Ihnen gewählte Vererbungsart beeinflusst, wie auf Member der Basisklasse in der abgeleiteten Klasse zugegriffen wird. C++ bietet drei Optionen: public, protected und private Vererbung.

Hier erfahren Sie, wie jeder Typ den Zugriff auf Member transformiert:

Basis-Memberpublic-Vererbungprotected-Vererbungprivate-Vererbung
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privatenicht zugreifbarnicht zugreifbarnicht zugreifbar
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class PublicDerived : public Base {
    // pub ist public, prot ist protected, priv ist nicht zugänglich
};

class ProtectedDerived : protected Base {
    // pub ist protected, prot ist protected, priv ist nicht zugänglich
};

class PrivateDerived : private Base {
    // pub ist private, prot ist private, priv ist nicht zugänglich
};

Öffentliche Vererbung modelliert „is-a“-Beziehungen und ist bei weitem die häufigste. Ein Dog ist ein Animal, sodass externer Code es als solches behandeln kann.

Geschützte und private Vererbung modellieren „implementiert-mittels“-Beziehungen (implemented-in-terms-of). Sie verbergen die Schnittstelle der Basisklasse vor externem Code, was nützlich ist, wenn Sie die Implementierung wiederverwenden möchten, ohne die Vererbungsbeziehung offenzulegen. Bei privater Vererbung verlieren selbst weiter abgeleitete Klassen den Zugriff auf die ursprünglichen Basiselemente.

challenge icon

Aufgabe

Einfach

Lassen Sie uns untersuchen, wie sich verschiedene Vererbungstypen auf die Zugänglichkeit von Mitgliedern auswirken, indem wir eine einfache Gerätehierarchie aufbauen. Sie werden eine Basisklasse Device und drei abgeleitete Klassen erstellen, die jeweils einen anderen Vererbungstyp verwenden, um aus erster Hand zu sehen, wie öffentliche (public), geschützte (protected) und private Vererbung den Zugriff auf Mitglieder transformieren.

Sie werden Ihren Code in zwei Dateien organisieren:

  • Device.h: Definieren Sie eine Basisklasse Device mit drei Mitgliedern auf verschiedenen Zugriffsebenen:
    • Ein öffentliches std::string model
    • Ein geschütztes int serialNumber
    • Ein privates int internalCode (standardmäßig auf 999 gesetzt)
    • Eine öffentliche Methode showModel(), die Folgendes ausgibt: Model: <model>

    Erstellen Sie dann drei abgeleitete Klassen, die jeweils mit unterschiedlichen Vererbungstypen von Device erben:

    • PublicDevice unter Verwendung von öffentlicher Vererbung (public inheritance) — fügen Sie eine Methode displaySerial() hinzu, die Folgendes ausgibt: Serial: <serialNumber>
    • ProtectedDevice unter Verwendung von geschützter Vererbung (protected inheritance) — fügen Sie eine Methode displaySerial() hinzu, die Folgendes ausgibt: Serial: <serialNumber>
    • PrivateDevice unter Verwendung von privater Vererbung (private inheritance) — fügen Sie eine Methode displaySerial() hinzu, die Folgendes ausgibt: Serial: <serialNumber>

    Jede abgeleitete Klasse sollte einen Konstruktor haben, der einen Modellnamen und eine Seriennummer entgegennimmt, das Modell an die Basisklasse übergibt und die Seriennummer setzt.

  • main.cpp: Lesen Sie zwei Eingaben ein (jede in einer separaten Zeile):
    1. Modellname (String)
    2. Seriennummer (Integer)

    Erstellen Sie ein Objekt von jedem abgeleiteten Typ mit denselben Eingabewerten. Demonstrieren Sie dann die Zugriffsunterschiede:

    Für PublicDevice:

    • Rufen Sie showModel() direkt am Objekt auf (funktioniert, da die öffentliche Vererbung es öffentlich hält)
    • Greifen Sie direkt auf model zu und geben Sie Folgendes aus: Direct model access: <model>
    • Rufen Sie displaySerial() auf

    Für ProtectedDevice und PrivateDevice:

    • Rufen Sie nur displaySerial() auf (die geerbten showModel() und model sind von außen nicht mehr öffentlich zugänglich)

    Ausgabeformat:

    --- PublicDevice ---
    Model: <model>
    Direct model access: <model>
    Serial: <serial>
    --- ProtectedDevice ---
    Serial: <serial>
    --- PrivateDevice ---
    Serial: <serial>

Zum Beispiel mit den Eingaben Laptop und 12345:

--- PublicDevice ---
Model: Laptop
Direct model access: Laptop
Serial: 12345
--- ProtectedDevice ---
Serial: 12345
--- PrivateDevice ---
Serial: 12345

Beachten Sie, dass nur PublicDevice den externen Zugriff auf die geerbten öffentlichen Mitglieder erlaubt. Die anderen Vererbungstypen verbergen die Schnittstelle der Basisklasse vor externem Code, aber die abgeleiteten Klassen können intern über ihre eigenen Methoden weiterhin auf geschützte Mitglieder zugreifen.

Spickzettel

C++ bietet drei Vererbungsarten an, die steuern, wie auf Member der Basisklasse in abgeleiteten Klassen zugegriffen wird:

Basis-Memberpublic-Vererbungprotected-Vererbungprivate-Vererbung
publicpublicprotectedprivate
protectedprotectedprotectedprivate
privatenicht zugreifbarnicht zugreifbarnicht zugreifbar
class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
};

class PublicDerived : public Base {
    // pub ist public, prot ist protected, priv ist nicht zugreifbar
};

class ProtectedDerived : protected Base {
    // pub ist protected, prot ist protected, priv ist nicht zugreifbar
};

class PrivateDerived : private Base {
    // pub ist private, prot ist private, priv ist nicht zugreifbar
};

Public-Vererbung bildet „is-a“-Beziehungen (ist-ein) ab und ist am gebräuchlichsten. Externer Code kann über die abgeleitete Klasse auf öffentliche Member der Basisklasse zugreifen.

Protected- und Private-Vererbung bilden „implemented-in-terms-of“-Beziehungen (implementiert-mithilfe-von) ab. Sie verbergen die Schnittstelle der Basisklasse vor externem Code. Bei der Private-Vererbung verlieren sogar weiter abgeleitete Klassen den Zugriff auf die ursprünglichen Basis-Member.

Probier es selbst

#include <iostream>
#include <string>
#include "Device.h"

using namespace std;

int main() {
    // Eingabe lesen
    string modelName;
    int serialNum;
    
    getline(cin, modelName);
    cin >> serialNum;
    
    // TODO: Objekte jedes abgeleiteten Typs mit den Eingabewerten erstellen
    // PublicDevice pubDev(modelName, serialNum);
    // ProtectedDevice protDev(modelName, serialNum);
    // PrivateDevice privDev(modelName, serialNum);
    
    // TODO: Zugriff auf PublicDevice demonstrieren
    cout << "--- PublicDevice ---" << endl;
    // - showModel() direkt am Objekt aufrufen
    // - Direkt auf model zugreifen und ausgeben: Direct model access: <model>
    // - displaySerial() aufrufen
    
    // TODO: Zugriff auf ProtectedDevice demonstrieren
    cout << "--- ProtectedDevice ---" << endl;
    // - Nur displaySerial() aufrufen (showModel und model sind nicht öffentlich zugänglich)
    
    // TODO: Zugriff auf PrivateDevice demonstrieren
    cout << "--- PrivateDevice ---" << endl;
    // - Nur displaySerial() aufrufen (showModel und model sind nicht öffentlich zugänglich)
    
    return 0;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung