2011-01-17 8 views

Antwort

71

Sicher, und Sie müssen nicht einmal eine Methode in der Basisklasse definieren. In Python sind Methoden besser als virtuell - sie sind komplett dynamisch, da die Eingabe in Python ist, tippen Sie Ente.

class Dog: 
    def say(self): 
    print "hau" 

class Cat: 
    def say(self): 
    print "meow" 

pet = Dog() 
pet.say() # prints "hau" 
another_pet = Cat() 
another_pet.say() # prints "meow" 

my_pets = [pet, another_pet] 
for a_pet in my_pets: 
    a_pet.say() 

Cat und Dog in Python müssen nicht einmal von einer gemeinsamen Basisklasse ableiten, dieses Verhalten zu ermöglichen - Sie können es kostenlos gewinnen. Das heißt, einige Programmierer bevorzugen es, ihre Klassenhierarchien in einer strengeren Weise zu definieren, um es besser zu dokumentieren und die Strenge der Typisierung zu erzwingen. Dies ist auch möglich - siehe zum Beispiel die abc standard module.

+0

'cat.say()' sollte 'another_pet.say()' – dusan

+0

@dusan sein: danke. Fest. –

+9

+1 für ein Beispiel. In welcher Sprache sagen Hunde übrigens "hau"? – JeremyP

40

Python-Methoden sind immer virtuell.

16

Eigentlich in Version 2.6 Python bietet sth abstrakte Basisklassen aufgerufen und Sie können virtuelle Methoden wie dies explizit festgelegt:

from abc import ABCMeta 
from abc import abstractmethod 
... 
class C: 
    __metaclass__ = ABCMeta 
    @abstractmethod 
    def my_abstract_method(self, ...): 

Es funktioniert sehr gut, die Klasse zur Verfügung gestellt nicht von Klassen nicht erben, die bereits metaclasses verwenden .

Quelle: http://docs.python.org/2/library/abc.html

7

Python Methoden immer virtuell sind

wie Ignacio sagte noch Irgendwie Klassenvererbung kann ein besserer Ansatz zu implementieren sein, was Sie wollen.

class Animal: 
    def __init__(self,name,legs): 
     self.name = name 
     self.legs = legs 

    def getLegs(self): 
     return "{0} has {1} legs".format(self.name, self.legs) 

    def says(self): 
     return "I am an unknown animal" 

class Dog(Animal): # <Dog inherits from Animal here (all methods as well) 

    def says(self): # <Called instead of Animal says method 
     return "I am a dog named {0}".format(self.name) 

    def somethingOnlyADogCanDo(self): 
     return "be loyal" 

formless = Animal("Animal", 0) 
rover = Dog("Rover", 4) #<calls initialization method from animal 

print(formless.says()) # <calls animal say method 

print(rover.says()) #<calls Dog says method 
print(rover.getLegs()) #<calls getLegs method from animal class 

Ergebnisse sollte sein:

I am an unknown animal 
I am a dog named Rover 
Rover has 4 legs 
13

NotImplementedError ist die empfohlene Ausnahme auf „rein virtuelle Methoden“ der „abstrakten“ Basisklassen zu erhöhen, die eine Methode nicht implementieren.

Wie andere schon sagten, ist dies meistens eine Dokumentationskonvention und nicht erforderlich, aber auf diese Weise erhalten Sie eine aussagekräftigere Ausnahme als einen fehlenden Attributfehler.

https://docs.python.org/3.5/library/exceptions.html#NotImplementedError sagt:

Diese Ausnahme von RuntimeError abgeleitet wird. In benutzerdefinierten Basisklassen sollten abstrakte Methoden diese Ausnahme auslösen, wenn sie abgeleitete Klassen benötigen, um die Methode zu überschreiben.

z.:

class Base(object): 
    def virtualMethod(self): 
     raise NotImplementedError() 
    def usesVirtualMethod(self): 
     return self.virtualMethod() + 1 

class Derived(Base): 
    def virtualMethod(self): 
     return 1 

print Derived().usesVirtualMethod() 
Base().usesVirtualMethod() 

gibt:

2 
Traceback (most recent call last): 
    File "./a.py", line 13, in <module> 
    Base().usesVirtualMethod() 
    File "./a.py", line 6, in usesVirtualMethod 
    return self.virtualMethod() + 1 
    File "./a.py", line 4, in virtualMethod 
    raise NotImplementedError() 
NotImplementedError 

Verwandte: Is it possible to make abstract classes in python?

2

Python Methoden sind immer virtuell.

... vorausgesetzt, sie sind nicht privat! Schade für einen C++ - Typ.

Verwandte Themen