Menu
Coddy logo textTech

Implementierung der Datenkapselung

Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 33 von 70.

Datenkapselung geht über die bloße Verwendung von private Feldern hinaus. Es geht darum, Ihre Klasse so zu entwerfen, dass interne Implementierungsdetails für externen Code vollständig unsichtbar sind und nur das Notwendige über eine saubere öffentliche Schnittstelle offengelegt wird.

Betrachten Sie eine Klasse, die das Passwort eines Benutzers verwaltet. Sie möchten nicht, dass jemand auf das Passwort im Klartext zugreift – nicht einmal, um es zu lesen:

public class UserAccount
{
    private string passwordHash;
    
    public void SetPassword(string password)
    {
        passwordHash = HashPassword(password);
    }
    
    public bool VerifyPassword(string password)
    {
        return HashPassword(password) == passwordHash;
    }
    
    private string HashPassword(string password)
    {
        return password.GetHashCode().ToString();
    }
}

Beachten Sie, dass es keine Möglichkeit gibt, das Passwort oder gar den Hash abzurufen. Externer Code kann nur ein Passwort festlegen oder eines verifizieren – der interne Speichermechanismus ist vollständig verborgen. Die Methode HashPassword ist ebenfalls privat, da es sich um ein Implementierungsdetail handelt, das sich ändern könnte, ohne die Verwendung der Klasse zu beeinflussen.

Dieser Ansatz schützt Ihre Klasse vor Missbrauch und gibt Ihnen die Freiheit, Interna später zu ändern. Wenn Sie sich entscheiden, einen anderen Hashing-Algorithmus zu verwenden, bricht kein externer Code ab, da nichts davon abhing, wie das Passwort gespeichert wurde.

challenge icon

Aufgabe

Einfach

Lass uns ein sicheres Wallet-System entwickeln, das echtes Verbergen von Daten demonstriert. Du erstellst ein digitales Wallet, dessen Kontostand vollständig geschützt ist – externer Code kann nur einzahlen, abheben und prüfen, ob Transaktionen möglich sind, den tatsächlichen Kontostand aber niemals direkt sehen oder manipulieren.

Du organisierst deinen Code auf zwei Dateien:

  • Wallet.cs: Erstelle eine Wallet-Klasse im Namespace Finance, die ihren Kontostand vollständig verborgen hält. Das Wallet sollte Folgendes enthalten:
    • Ein privates Feld zum Speichern des Kontostands (Dezimalzahl)
    • Eine private Methode FormatBalance(), die den Kontostand als Währungszeichenfolge wie "$123.45" formatiert zurückgibt – dies ist eine interne Hilfsmethode, die nicht öffentlich zugänglich sein sollte
    • Eine öffentliche Methode Deposit(decimal amount), die den Kontostand nur erhöht, wenn der Betrag positiv ist, und bei Erfolg true, andernfalls false zurückgibt
    • Eine öffentliche Methode Withdraw(decimal amount), die den Kontostand nur verringert, wenn der Betrag positiv ist und den aktuellen Kontostand nicht überschreitet, und bei Erfolg true, andernfalls false zurückgibt
    • Eine öffentliche Methode CanAfford(decimal amount), die true zurückgibt, wenn der Kontostand größer oder gleich dem Betrag ist, andernfalls false
    • Eine öffentliche Methode GetStatement(), die intern die private Methode FormatBalance() verwendet und "Current balance: {formatted balance}" zurückgibt
    Beachte, dass es keine Möglichkeit gibt, den Kontostand direkt zu lesen oder zu setzen – du kannst nur über kontrollierte Methoden mit ihm interagieren!
  • Program.cs: Erstelle in deiner Hauptdatei ein Wallet und führe mithilfe von Eingabewerten eine Reihe von Transaktionen durch. Zeige, wie das Wallet seinen internen Zustand schützt und über seine öffentliche Schnittstelle dennoch nützliche Funktionen bereitstellt.

Du erhältst drei Eingaben:

  • Ursprünglicher Einzahlungsbetrag (Dezimalzahl)
  • Auszahlungsbetrag, der versucht werden soll (Dezimalzahl)
  • Betrag, für den die Bezahlbarkeit geprüft werden soll (Dezimalzahl)

Gib die Ausgabe in diesem Format aus:

Deposit {amount}: {True/False}
{GetStatement() result}
Withdraw {amount}: {True/False}
{GetStatement() result}
Can afford {amount}: {True/False}

Wenn die Eingaben beispielsweise 100.50, 30.25 und 80.00 lauten, sollte die Ausgabe wie folgt aussehen:

Deposit 100.50: True
Current balance: $100.50
Withdraw 30.25: True
Current balance: $70.25
Can afford 80.00: False

Die wichtigste Erkenntnis ist, dass externer Code niemals direkt auf das Kontostandsfeld zugreift. Selbst die formatierte Kontostandszeichenfolge wird über eine öffentliche Methode bereitgestellt, die intern eine private Hilfsmethode verwendet. Das ist Datenverbergung – die Implementierungsdetails sind vollständig unsichtbar, und du kannst jederzeit ändern, wie der Kontostand gespeichert oder formatiert wird, ohne Code zu beschädigen, der dein Wallet verwendet!

Probier es selbst

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // Eingabewerte lesen
        decimal depositAmount = Convert.ToDecimal(Console.ReadLine());
        decimal withdrawAmount = Convert.ToDecimal(Console.ReadLine());
        decimal checkAmount = Convert.ToDecimal(Console.ReadLine());

        // TODO: Eine Wallet-Instanz erstellen
        
        // TODO: Einzahlung durchführen und Ergebnis im Format "Deposit {amount}: {True/False}" ausgeben
        
        // TODO: Den Kontoauszug mit GetStatement() ausgeben
        
        // TODO: Auszahlung durchführen und Ergebnis im Format "Withdraw {amount}: {True/False}" ausgeben
        
        // TODO: Den Kontoauszug mit GetStatement() ausgeben
        
        // TODO: Erschwinglichkeit prüfen und Ergebnis im Format "Can afford {amount}: {True/False}" ausgeben
    }
}
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

Übe selbstständig: Online-C#-Compiler