Kann ein Objekt einer Basisklasse Funktionen einer abgeleiteten Klasse verwenden?

Naphaneal

unregistriert
Thread Starter
Dabei seit
05.12.2007
Beiträge
4.085
Reaktionspunkte
343
hi!

ich lerne grade für ne OOP-klausur und hab da mal o.g. frage.

wie verhält sich das bei der vererbung im rückläufigen sinn? will sagen, wie ist das im umgekehrten fall?

geht das? wenn ja, wie? wenn nein, warum nicht?

greez

Naph
 
Wenn du nur eine Instanz der Basisklasse (und nicht eine auf die Basisklasse gecastete Instanz einer abgeleiteten Klasse) hast, geht das nicht. Im fehlt schlicht das Wissen über diese Methode. Ist es ein downcast, kannst du zumindest per Reflection oder Upcast dran kommen - wenn du weißt, welchen Typs das Objekt wirklich ist.
 
hmm...also müsste ich im voraus bereits wissen, welche funktion in der abgeleiteten klasse vorkommt und in der basisklasse eine virtuelle funktion deklarieren, hätte dann aber das problem, daß keine Objekte von der basisklasse mehr erzeugt werden könnten?
 
Ja richtig. Abstrakte Klassen lassen sich nicht instantiieren. Abgesehen davon wäre dann die Funktion nicht Bestandteil des Objektes. Der Downcast ist ja nur eine Maske. Das Objekt behält seinen Typ und damit auch die Methoden. Zusammengefasst: Nein du bekommst unter keinen Umständen Zugriff auf Methoden von abgeleiteten Klassen!
 
Nö, also in Objective-C ist das so nicht richtig.

Du kannst immer alles aufrufen, sollest halt vorher "doesRespondToSelector:" aufrufen und prüfen, ob das Objekt es kann.

Ob das gutes Design ist, das steht auf einem anderen Blatt.

Alex
 
Alex, wenn die Methode für eine abgeleitete Klasse definiert wurde, sollte eine Instanz einer Basisklasse auch kein Wissen davon haben, oder? Klar kannst du eine Methode/Message an einem Objekt einer abgeleiteten Klasse rufen. Das geht auch in C++ und Java durch den Upcast (mit einer Typprüfung). Eine echte Instanz der Basisklasse erlaubt aber keinen *erfolgreichen* Ruf. Oder irre ich mich? ;)

Edit: offensichtlich müssen wir hier zwischen Klasse, Interface, Objekt und Instanz unterscheiden, oder?
 
:hamma: Ja klar, wenn wir von einer echten Instanz der Basisklasse reden, natürlich nicht.

Ausser, Du willst eine Klassenmethode der abgeleiteten Klasse aufrufen, aber ich glaube, das will der TE gar nicht wissen.

Alex
 
hi!

ich lerne grade für ne OOP-klausur und hab da mal o.g. frage.

wie verhält sich das bei der vererbung im rückläufigen sinn? will sagen, wie ist das im umgekehrten fall?

geht das? wenn ja, wie? wenn nein, warum nicht?

greez

Naph

Vererbung ist unidirektional. Die Mutterklasse kennt Ihre Kindklassen gar nicht. Eine Mutterklasse könnte aber eine Kindklasse instanziieren und damit auf die Funktionen usw zugreifen.
 
Vererbung ist unidirektional. Die Mutterklasse kennt Ihre Kindklassen gar nicht. Eine Mutterklasse könnte aber eine Kindklasse instanziieren und damit auf die Funktionen usw zugreifen.

Könnte sie, die beiden teilen sich aber nicht unter allen Bedingungen ihren vollen State!
 
...
Ausser, Du willst eine Klassenmethode der abgeleiteten Klasse aufrufen, aber ich glaube, das will der TE gar nicht wissen.

äh, doch will er...genau, darum geht's mir...

Vererbung ist unidirektional. Die Mutterklasse kennt Ihre Kindklassen gar nicht. Eine Mutterklasse könnte aber eine Kindklasse instanziieren und damit auf die Funktionen usw zugreifen.

wenn ich aber eine kindklasse instanziiere, dann is die kindklasse ja ein objekt der basisklasse.
 
Der Unterschied zwischen Klassenmethode und Instanzmethode ist Dir klar?

Alex
 
bei den begrifflichkeiten den überblick zu behalten...:hum:

also...klassenmethode is ein statisches ding, kann ohne objekte einer klasse benutzt werden.
instanzmethoden dürften dann die sein, welche nur über objekte benutzbar sind...

also nochmal...

ich hätte gerne gewußt: ist es möglich, daß ein objekt einer basisklasse A, eine methode einer von der basisklasse abgeleiteten klasse B verwenden kann?
 
Zuletzt bearbeitet:
Klassenmethode: Ja

Alex

Die Bedingungen sollten aber geklärt sein, wie das geht:
Code:
class A {
 static void a () { 
  B.b();
 }
}

class B : A {
 static void b () { 
  /* ... */
 }
}

int main() {
 A.b(); // NEIN!!
 A.a(); // JA!! (Delegator)
}
 
hi!

ich lerne grade für ne OOP-klausur und hab da mal o.g. frage.

wie verhält sich das bei der vererbung im rückläufigen sinn? will sagen, wie ist das im umgekehrten fall?

geht das? wenn ja, wie? wenn nein, warum nicht?

greez

Naph

Ja, ein Objekt einer Basisklasse (bzw. ein Zeiger auf eine Basisklasse) kann Funktionen einer von ihr abgeleiteten Klasse benutzen. Aber nicht automatisch. Die Basisklasse weiß nicht, dass sie vererbt wurde. Du musst den Basisklassen Zeiger auf den jeweiligen Typ downcasten. Allgemein hat die Basisklasse die Funktionalitäten ihrer abgeleiteten Klassen nicht.

Compiler unterstützen automatisch nur den upcast, also den cast von einer abgeleiteten Klasse auf seine Basisklasse, da die abgeleitete Klasse auf jeden Fall auch die Funktionalität der Basisklasse besitzt.

Eine Vererbung im "rückläufigen Sinn" gibt es also nicht.
 
Die Basisklasse weiß nicht, dass sie vererbt wurde.

Das ist der Punkt. Das funktioniert nur, wenn man eine Instanz der Abgleiteten Klasse hat. Ein Downcast einer Instanz der Basisklasse geht IMHO nicht, da die abgeleitete Klasse für gewöhnlich einen größeren State hat, welcher nicht initialisiert wurde.

PS: Ich hab oben mal wieder Up- und Downcast verwechselt...
 
Ja, ein Objekt einer Basisklasse (bzw. ein Zeiger auf eine Basisklasse) kann Funktionen einer von ihr abgeleiteten Klasse benutzen. Aber nicht automatisch. Die Basisklasse weiß nicht, dass sie vererbt wurde. Du musst den Basisklassen Zeiger auf den jeweiligen Typ downcasten. Allgemein hat die Basisklasse die Funktionalitäten ihrer abgeleiteten Klassen nicht.

Compiler unterstützen automatisch nur den upcast, also den cast von einer abgeleiteten Klasse auf seine Basisklasse, da die abgeleitete Klasse auf jeden Fall auch die Funktionalität der Basisklasse besitzt.

Eine Vererbung im "rückläufigen Sinn" gibt es also nicht.

um das so zu machen, müsste ich aber mehrere dinge wissen, oder nicht? zum einen müsste mir doch der typ der klasse bekannt sein und zum anderen müsste ich wissen, wo der zeiger im speicher hindeutet. oder seh ich das falsch?
 
um das so zu machen, müsste ich aber mehrere dinge wissen, oder nicht? zum einen müsste mir doch der typ der klasse bekannt sein und zum anderen müsste ich wissen, wo der zeiger im speicher hindeutet. oder seh ich das falsch?

Genau! Du kannst nicht sicher sagen, ob der cast zulässig ist.

Ist er nicht zulässig bekommst du durch einen unerlaubten downcast Zugriff auf einen Speicherbereich, der geschützt ist. Im besten Fall stürzt dein Programm mit einem segmentation fault sofort ab, im schlechtesten Fall bleibt der Fehler wenn er passiert unentdeckt. Dein Programm stürzt dann an einer ganz anderen Stelle im Code völlig unvorhersehbar und schlecht reproduzierbar ab.

Arbeitet man in C++ (zum Beispiel) mit einem Basisklassenzeiger, der immer nur auf das jeweilige spezialisierte Objekt gecastet wird, gibt es deswegen den dynamic_cast-Operator, welcher zur Laufzeit überprüft, ob der downcast zulässig ist. Trotzdem sollte man den dynamic cast (oder noch schlimmer: den cross cast) möglichst vermeiden. Wird sowas häufig gebraucht, dann stimmt irgendwas mit dem Software design nicht.

Stell dir dieses gecaste wie eine Schablone vor, die du auf das Objekt legst. Bei einem upcast (von einer abgeleiteten Klasse auf die Basisklasse) wird mit der Basisklassen-Schablone einfach die Basisfunktionalität aus dem Objekt ausgeschnitten - es ist immer zulässig und es passiert nichts. Deswegen kann es der Compiler auch sofort.

Beim downcast legst du eine spezialisierte und damit erweiterte Schablone auf ein Objekt. Dies funktioniert nur, wenn das Objekt diese spezialisierte Funktionalität auch wirklich besitzt. Ansonsten, naja, siehe oben ;)

PS.: mein Senior-Ingenieur springt bei dem Thema downcast sofort im Dreieck :D :D
 
Zuletzt bearbeitet:
Zurück
Oben Unten