2011-08-16 3 views
2

J'ai une instance d'une classe de base, puis je veux en faire une instance d'une classe enfant de cette classe de base. Peut-être que je prends le problème dans un mauvais sens et qu'il y a quelque chose d'important que je n'ai pas compris dans OOP. Le code est seulement là pour illustrer et une approche très différente peut être suggérée. Toute aide appréciée.Héritage: transforme une instance de classe de base en instance de classe enfant

class Car(object): 
    def __init__(self, color): 
     self.color = color 

    def drive(self): 
     print "Driving at 50 mph" 

class FastCar(Car): 
    def __init__(self, color, max_speed=100): 
     Car.__init__(self, color) 
     self.max_speed = max_speed 

    def drive_fast(self): 
     print "Driving at %s mph" %self.max_speed 

one_car = Car('blue') 

# After the instanciation, I discovered that one_car is not just a classic car 
# but also a fast one which can drive at 120 mph. 
# So I want to make one_car a FastCar instance. 

Je vois une question très similaire, mais aucune des réponses convient à mon problème:

  • Je ne veux pas faire FastCar une enveloppe autour de voiture qui saura comment rouler vite: Je veux vraiment que FastCar prolonge la voiture;

  • Je ne veux pas vraiment utiliser la méthode __new__ dans FastCar de faire quelques tests sur les arguments et décider si __new__ doit retourner une nouvelle instance de voiture ou l'instance que je lui donna (exemple: def __new__(cls, color, max_speed=100, baseclassinstance=None)).

+0

Pourquoi ne pas le faire: one_car = FastCar (one_car.color, 120)? Ce n'est pas vraiment l'héritage ou quoi que ce soit mais devrait fonctionner. – Bogdan

+3

Votre conception de POO semble un peu éteinte. J'imagine que FastCar implémenterait aussi drive(), mais le ferait à la vitesse supérieure (ce que vous avez implémenté comme drive_fast). Avec ce que vous avez maintenant, l'appelant doit connaître le type pour savoir quelle méthode appeler (mauvais), au lieu d'appeler la même méthode et avoir les différents types implémenter cette méthode comme approprié (bon). Vous pouvez également le faire en ajoutant 'drive = drive_fast' à la fin de la classe FastCar. – PaulMcG

+0

Ok.Un meilleur exemple: 'FastCar' n'a pas de méthode' drive_fast' mais une méthode 'overtake', qui n'existe pas pour' Car'. – Andy

Répondre

0

Vous pouvez emprunter la notion C++ d'un "constructeur de copie" pour faire quelque chose comme ça.

Permet au constructeur de Car de prendre une instance Car et de copier toutes ses propriétés. FastCar doit alors accepter les instances Car ou les instances FastCar.

Alors, pour convertir la voiture, vous feriez simplement one_car = FastCar(one_car). Notez que cela n'affectera pas les références à l'objet Car original, qui restera pointé vers la même voiture.

2
class FastCar(Car): 
    def __init__(self, color, max_speed=100): 
     Car.__init__(self, color) 
     self.max_speed = max_speed 

    def drive_fast(self): 
     print "Driving at %s mph" %self.max_speed 

    @staticmethod 
    def fromOtherCar(car): 
     return FastCar(car.color) 

actually_fast = FastCar.fromOtherCar(thought_was_classic) 

Ceci est la méthode standard.

En fonction de la réelle mise en page de classe, vous pourrez peut-être faire quelque chose comme:

classic = Car('blue') 

classic.__class__ = FastCar 
classic.__dict__.update(FastCar(classic.color).__dict__) 

classic.drive_fast() 

Mais je ne le recommanderais pas - c'est un hack, cela ne fonctionnera pas toujours, et l'autre façon est plus propre.

Modifier: Était sur le point d'ajouter fondamentalement ce que le commentaire de @ PaulMcGuire dit. Suivez ce conseil, il a raison.

0

Pourquoi ne pas utiliser un seul cours?

class Car(object): 
    def __init__(self, color, max_speed = 50): 
     self.color = color 
     self.max_speed = max_speed 
    def drive(self): 
     print "Driving at %s mph"%self.max_speed 

c=Car('blue') 
c.max_speed = 100 
0

Il n'est pas courant dans la POO de changer le type (classe) d'un objet vivant après l'instanciation. Je connais à peine deux langues qui permettraient cela comme un bidouille sale. L'objectif des types (classes) est de savoir à l'avance quelles opérations un objet peut et ne peut pas effectuer. Si vous voulez quelque chose comme ça, vous confondez probablement l'idée de POO.

+0

Si vous étiez nouveau à la POO, je pense que vous pourriez penser à faire une chaîne à partir d'un tableau de caractères en changeant le type d'un objet. C'est faire un nouvel objet à partir du contenu de l'ancien, c'est ce qu'il veut vraiment faire (il ne le sait pas). – agf

+0

Merci, mais je ne pense pas que ce que je veux faire. Je ne veux vraiment pas créer un nouvel objet. – Andy

Questions connexes