detewe89 hat geschrieben:Kannst du mir eine kleine Beispiel-Implementierung (C++/Java) zeigen? Bei Beispielen lern ich immer am schnellsten^^
Wie schon korrekt vermutet, will ich auf Klassen hinaus. Eine Klasse "klassifiziert" zunächst Daten, das ist erforderlich um objektorientiert arbeiten zu können. Dabei entsteht ein neuer Datentyp. Wenn man allerdings nicht objektorientiert arbeiten muss, sondern nur Daten als eigene Typen braucht, eignen sich dafür Klassen ebenfalls. Man hat ausschließlich Basisklassen, aber diese sind nicht miteinander kompatibel - und genau das möchte man ja erreichen.
typedef erzeugt einen Identifier, der für ein anderen Typ steht.
Ein typedef unsigned int MatrikelNummer ist mit unsigned int beschreibbar und implizit castbar. Man kann semantisch ausdrücken, dass man eine Matrikelnummer verwenden möchte, aber die Typprüfung des Compilers ist hier nicht idiotensicher. Also braucht man eine Klasse.
Code: Alles auswählen
class Matrikelnummer
{
private:
unsigned int Nummer;
public:
explicit Matrikelnummer( unsigned int data ) : Nummer( data ) {}
unsigned int AsInteger() { return Nummer; }
};
Du kannst damit die Matrikelnummer übergeben. Du kannst damit nicht unbekümmert rechnen, also
Code: Alles auswählen
Matrikelnummer m = MatrikelNummer( 83803 );
m++; // idiotisch => geht nicht
Als meine Fachhochschule sich mit anderen Fachhochschulen zusammenschloss, änderte sich meine Matrikelnummer auf 2083803.
Hier könnte man nun intern die Methode 'AsInteger()' für einen internen Gebrauch ändern oder entsprechende Konstruktoren erstellen. Man packt eine HochschulId dazu und weiß damit, wo der Student studiert.
Code: Alles auswählen
Matrikelnummer( HochschulId id, unsigned int data ) : SchulId( id ), Nummer( data ) {}
unsigned int AsInteger() { return SchulId.Matrikelprafix + Data; }
unsigned int AsInternalInteger() { return Data; }
HochschulId GetSchulId() { return SchulId; }
Nun könnte man den anderen Konstruktor lahmlegen und bekommt damit vom Compiler alle Stellen, die eine Matrikelnummer erzeugen ohne die Hochschule anzugeben und ich wüsste sofort, wo ich das Programm korrigieren muss, um es fehlerfrei zu halten. Die Funktion AsInteger() hat sich verändert - aber wer immer die Matrikelnummer ausliest um sie z.B. auf eine Notenübersicht zu drucken hat gar nicht mitbekommen, dass sich die Nummer nun anders berechnet wird.
Man entschuldige das Denglisch... Get, As, Is, Set und Has sind Prefixe, die ich weniger gern übersetze. Die Klassen 'Matrikelnummer' und 'HochschulId' würde ich auch englisch bezeichnen, aber wir fingen damit hier so an. Wie du siehst, kapsle ich auch die Identifikationsnummer der Hochschule. Wären beides unsigned ints gewesen, dann könnte man sie verwechseln => nicht idiotensicher.
Ich programmiere jetzt seit 24 Jahren. Ich kapsele alles. Ich versuche es idiotensicher zu machen, denn wenn ich in der Zeit etwas gelernt habe, dann dass man als Entwickler immer Fehler macht und man die Qualität seiner Arbeit massiv steigern kann, wenn man sich dem Compiler als Idiot offenbart. Wer seine Schwächen im Griff haben will, muss alle Möglichkeiten nutzen, sich abzusichern und ausführliche Typisierung hilft hier sehr gut helfen. Aufgurnd dieser Erfahrung überlege ich noch, ob ich primitive Typen in meiner Sprache als Parameter zu verbieten.