Angenommen, Sie haben die folgende Situation
#include <iostream>
class Animal {
public:
virtual void speak() = 0;
};
class Dog : public Animal {
void speak() { std::cout << "woff!" <<std::endl; }
};
class Cat : public Animal {
void speak() { std::cout << "meow!" <<std::endl; }
};
void makeSpeak(Animal &a) {
a.speak();
}
int main() {
Dog d;
Cat c;
makeSpeak(d);
makeSpeak(c);
}
Wie Sie sehen können, ist makeSpeak eine Routine, die ein generisches Animal-Objekt akzeptiert. In diesem Fall ist Animal einer Java-Schnittstelle ziemlich ähnlich, da es nur eine rein virtuelle Methode enthält. makeSpeak kennt die Art des Tieres, an dem es übergeben wird, nicht. Es sendet nur das Signal "speak" und verlässt die späte Bindung, um sich darum zu kümmern, welche Methode aufgerufen werden soll: entweder Cat :: speak () oder Dog :: speak (). Dies bedeutet, dass für makeSpeak die Kenntnis, welche Unterklasse tatsächlich übergeben wird, irrelevant ist.
Aber was ist mit Python? Sehen wir uns den Code für denselben Fall in Python an. Bitte beachten Sie, dass ich für einen Moment versuche, dem C ++ - Fall so ähnlich wie möglich zu sein:
class Animal(object):
def speak(self):
raise NotImplementedError()
class Dog(Animal):
def speak(self):
print "woff!"
class Cat(Animal):
def speak(self):
print "meow"
def makeSpeak(a):
a.speak()
d=Dog()
c=Cat()
makeSpeak(d)
makeSpeak(c)
In diesem Beispiel sehen Sie dieselbe Strategie. Sie verwenden die Vererbung, um das hierarchische Konzept von Hunden und Katzen als Tiere zu nutzen. In Python ist diese Hierarchie jedoch nicht erforderlich. Das funktioniert genauso gut
class Dog:
def speak(self):
print "woff!"
class Cat:
def speak(self):
print "meow"
def makeSpeak(a):
a.speak()
d=Dog()
c=Cat()
makeSpeak(d)
makeSpeak(c)
In Python können Sie das Signal "Sprechen" an jedes gewünschte Objekt senden. Wenn das Objekt damit umgehen kann, wird es ausgeführt, andernfalls wird eine Ausnahme ausgelöst. Angenommen, Sie fügen beiden Codes eine Klasse Flugzeug hinzu und senden ein Flugzeugobjekt an makeSpeak. Im C ++ - Fall wird es nicht kompiliert, da Airplane keine abgeleitete Tierklasse ist. Im Fall von Python wird zur Laufzeit eine Ausnahme ausgelöst, die sogar ein erwartetes Verhalten sein kann.
Angenommen, Sie fügen auf der anderen Seite eine MouthOfTruth-Klasse mit einer Methode speak () hinzu. Im C ++ - Fall müssen Sie entweder Ihre Hierarchie umgestalten oder eine andere makeSpeak-Methode definieren, um MouthOfTruth-Objekte zu akzeptieren, oder Sie können in Java das Verhalten in ein CanSpeakIface extrahieren und die Schnittstelle für jedes implementieren. Es gibt viele Lösungen ...
Ich möchte darauf hinweisen, dass ich noch keinen einzigen Grund gefunden habe, die Vererbung in Python zu verwenden (abgesehen von Frameworks und Ausnahmebäumen, aber ich denke, dass es alternative Strategien gibt). Sie müssen keine von der Basis abgeleitete Hierarchie implementieren, um eine polymorphe Leistung zu erzielen. Wenn Sie die Vererbung verwenden möchten, um die Implementierung wiederzuverwenden, können Sie dies durch Eindämmung und Delegierung erreichen. Der zusätzliche Vorteil besteht darin, dass Sie sie zur Laufzeit ändern und die Schnittstelle des enthaltenen Systems klar definieren können, ohne unbeabsichtigte Nebenwirkungen zu riskieren.
Am Ende stellt sich also die Frage: Was ist der Sinn der Vererbung in Python?
Edit : danke für die sehr interessanten Antworten. Sie können es zwar für die Wiederverwendung von Code verwenden, aber ich bin immer vorsichtig, wenn Sie die Implementierung wiederverwenden. Im Allgemeinen neige ich dazu, sehr flache Vererbungsbäume oder gar keinen Baum zu erstellen, und wenn eine Funktionalität gemeinsam ist, überarbeite ich sie als gemeinsame Modulroutine und rufe sie dann von jedem Objekt aus auf. Ich sehe den Vorteil, einen einzigen Änderungspunkt zu haben (z. B. anstatt Hund, Katze, Elch usw. hinzuzufügen, füge ich nur Tier hinzu, was der grundlegende Vorteil der Vererbung ist), aber Sie können dasselbe mit erreichen eine Delegierungskette (z. B. a la JavaScript). Ich behaupte nicht, dass es besser ist, nur auf eine andere Weise.
Ich habe diesbezüglich auch einen ähnlichen Beitrag gefunden .