Was ist der Unterschied zwischen konkreten Klassen und abstrakten Klassen?


Antwort 1:

Der einzige wirkliche Unterschied besteht darin, dass eine konkrete Klasse instanziiert werden kann, da sie die Implementierung für alle ihre Methoden bereitstellt (oder übernimmt). Eine abstrakte Klasse kann nicht instanziiert werden, da mindestens eine Methode nicht implementiert wurde.

Abstrakte Klassen sollen erweitert werden. Wenn sie Implementierungsdetails bereitstellen, können diese von allen untergeordneten Klassen wiederverwendet werden. Ein Sonderfall ist die reine abstrakte Klasse, die überhaupt keine Implementierung bietet. Diese Klassen helfen nicht bei der Wiederverwendung von Code, wodurch sie sich grundlegend unterscheiden. Dieser Unterschied wird durch die beiden Arten der Vererbung beschrieben:

  1. Implementierungsvererbung - Bietet einen Mechanismus zur Wiederverwendung von Code. Schnittstellenvererbung - Bietet einen Mechanismus zur Untertypisierung.

Wenn Klasse B die Klasse A erweitert, bedeutet dies nicht unbedingt, dass B ein A ist. Es kann auch bedeuten, dass B einen Code von A erbt. Es ist nicht immer klar, und einige Sprachen verbinden dies mit Untertypen.

Java ist ein Beispiel für eine Sprache, die ein anderes Konstrukt für die Untertypisierung bereitstellt, das als Schnittstelle bezeichnet wird. Schnittstellen sind im Grunde genommen reine abstrakte Klassen. Wenn Klasse B Schnittstelle A implementiert, ist B ein A.

Wenn eine Sprache die Implementierungsvererbung von der Schnittstellenvererbung entkoppelt, können bestimmte Probleme unterschiedlich behandelt werden. Beispielsweise:

  1. Java umgeht die Komplexität der Mehrfachvererbung, indem es verbietet, dass eine Klasse zwei Superklassen hat. Es steht einer Klasse jedoch frei, eine beliebige Anzahl von Schnittstellen zu implementieren. Es ist einfacher, dem Prinzip der Bevorzugung der Komposition gegenüber der Vererbung zu folgen. Das Erweitern zu vieler Klassen kann zu komplexen Klassenhierarchien führen, die Implementierung zu vieler Schnittstellen ist jedoch weniger problematisch. Wenn es darum geht, den Ausführungsfluss durch ein Programm zu verfolgen, können Schnittstellen das Problem nicht komplizieren, da sie keinen ausführbaren Code enthalten.

Antwort 2:

Abstrakte Klassen sind in der Regel teilweise oder gar nicht implementiert. Auf der anderen Seite haben konkrete Klassen immer die volle Umsetzung ihres Verhaltens. Anders als konkrete Klassen können abstrakte Klassen nicht instanziiert werden. Daher müssen abstrakte Klassen erweitert werden, um sie nützlich zu machen. Abstrakte Klassen können abstrakte Methoden enthalten, konkrete Klassen jedoch nicht. Wenn eine abstrakte Klasse erweitert wird, werden alle Methoden (sowohl abstrakte als auch konkrete) vererbt. Die geerbte Klasse kann eine oder alle Methoden implementieren. Wenn nicht alle abstrakten Methoden implementiert sind, wird diese Klasse auch zu einer abstrakten Klasse.


Antwort 3:

Nehmen wir an, dass es eine Schnittstelle gibt, die von beiden Klassen implementiert werden muss.

Die konkrete Klasse implementiert alle Schnittstellenmethoden und kann so ohne weiteres instanziiert werden.

Wenn Sie aus irgendeinem Grund die Implementierung bestimmter Methoden auslassen möchten (z. B. wenn Sie zwei Implementierungen der Schnittstelle schreiben möchten, die sich kaum voneinander unterscheiden), schreiben Sie eine abstrakte Klasse, die nicht direkt instanziiert werden kann. Um eine abstrakte Klasse zu instanziieren, schreiben Sie entweder eine konkrete Unterklasse ("extend"), in der Sie die verbleibenden Methoden implementieren, oder Sie haben die Implementierung der letzteren beim Instanziieren angegeben (was technisch identisch ist: "Sie haben eine konkrete Unterklasse geschrieben", aber es ist eine anonyme).


Antwort 4:

Nehmen wir an, dass es eine Schnittstelle gibt, die von beiden Klassen implementiert werden muss.

Die konkrete Klasse implementiert alle Schnittstellenmethoden und kann so ohne weiteres instanziiert werden.

Wenn Sie aus irgendeinem Grund die Implementierung bestimmter Methoden auslassen möchten (z. B. wenn Sie zwei Implementierungen der Schnittstelle schreiben möchten, die sich kaum voneinander unterscheiden), schreiben Sie eine abstrakte Klasse, die nicht direkt instanziiert werden kann. Um eine abstrakte Klasse zu instanziieren, schreiben Sie entweder eine konkrete Unterklasse ("extend"), in der Sie die verbleibenden Methoden implementieren, oder Sie haben die Implementierung der letzteren beim Instanziieren angegeben (was technisch identisch ist: "Sie haben eine konkrete Unterklasse geschrieben", aber es ist eine anonyme).