2011-01-17 28 views

Respuesta

71

Claro, y ni siquiera tiene que definir un método en la clase base. En Python, los métodos son mejores que virtuales, son completamente dinámicos, ya que el tipado en Python es pato escribiendo.

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 y Dog en Python ni siquiera tienen que derivar de una clase base común para permitir que este comportamiento - a obtener de forma gratuita. Dicho esto, algunos programadores prefieren definir sus jerarquías de clase de una manera más rígida para documentarlo mejor e imponer algunos rigurosidad de tipeo. Esto también es posible; consulte, por ejemplo, el abc standard module.

+0

'cat.say()' debe ser 'another_pet.say()' – dusan

+0

@dusan: gracias. fijo. –

+9

+1 para un ejemplo. ¿En qué idioma los perros dicen "hau" por cierto? – JeremyP

40

Los métodos de Python son siempre virtuales.

16

En realidad, en la versión 2.6 de Python proporciona sth llamada base abstracta clases y se puede establecer explícitamente los métodos virtuales como esto:

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

funciona muy bien, siempre y cuando la clase no hereda de clases que ya utilizan metaclases .

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

7

métodos de Python son siempre virtuales

como Ignacio dijo sin embargo herencia alguna manera clase puede ser un mejor enfoque para poner en práctica lo que quiere.

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 

resultados deben ser:

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

NotImplementedError es la excepción recomendado hasta que el "métodos virtuales puros" de clases base "abstractos" que no implementan un método.

Como han dicho otros, esta es principalmente una convención de documentación y no es necesaria, pero de esta manera se obtiene una excepción más significativa que la de un error de atributo faltante.

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

Esta excepción se deriva de RuntimeError. En las clases base definidas por el usuario, los métodos abstractos deberían plantear esta excepción cuando requieren clases derivadas para anular el método.

E.g.:

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() 

da:

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 

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

2

métodos de Python son siempre virtual.

... ¡siempre que no sean privadas! Muy mal para un chico de C++.

Cuestiones relacionadas