Utilizzo di metodi specifici per una sottoclasse

0

Mi sono imbattuto in questa pagina SESE: Che cosa è un uso appropriato del downcasting? (per C #) - e parla di quando calpestare, e dei possibili svantaggi.

Nelle sotto classi Python sono leggermente diversi

Esempio:

Supponiamo che abbia la seguente classe abstract :

from abc import ABCMeta
from abc import abstractmethod

class Weapon(metaclass=ABCMeta):

    def __init__(self, name, damage):
        self.name = name
        self.damage = damage

    @abstractmethod
    def prepare(self):
        pass

    @abstractmethod
    def attack(self):
        pass

    @abstractmethod
    def cleanup(self):
        pass

    def __str__(self):
        return "Name: {} Damage: {}".format(self.name, self.damage) 

e Sottoclasse:

from Weapon import Weapon

class ChargeGun(Weapon):

    def __init__(self, name, damage):
        super().__init__(name, damage)

    def prepare(self):
        print("Aiming my Gun");

    def attack(self):
        print("Shooting")

    def cleanup(self):
        print("Lowering gun, and turning off laser sight")

    def charge(self):
        print("Charging Gun. Please hold..(elevator music playing)")

Nella mia sottoclasse ChargeGun , ho il metodo def charge(self): , e posso dichiarare nel principale un oggetto ChargeGun e usarlo, come questo:

cg = ChargeGun("Standard ChargeGun",5)
cg.prepare()
cg.charge()

Se dovessi introdurre Sword come sottoclasse Weapon , il charge(self): non sarebbe implementato e Sword non ne è nemmeno a conoscenza. In Python, non è necessario downcast o utilizzare un modello di progettazione.

Python non è Java / C #.

Domande

  1. Come dovresti pensare quando crei sottoclassi nelle lingue come Python? Dovremmo pensare da un punto di vista astratto, e refactoring il nostro codice?

    Esempio: def charge(self): potrebbe essere visto come un modo per preparare un ChargeGun in modo che possiamo rimuoverlo. Se avessi un silenziatore, questo è un componente di una pistola, quindi forse avrebbe senso avere una classe abstract WeaponComponent , un silenziatore e mirino laser potrebbero essere oggetti di quella classe e ognuno di essi sovrascriverebbe il metodo def prepare(self): . Una Spada potrebbe avere una gemma o una pietra che gli conferisce un'abilità extra di colpo, ecc.

Questo è solo un modo di pensare, non sto dicendo che è il modo migliore per refactoring.

  1. Va bene approfittare della capacità di Python di utilizzare i metodi di a sottoclasse direttamente?
posta ChrisW 26.02.2018 - 17:55
fonte

1 risposta

3

Dammi un'API che mi permetta di scrivere codice come questo:

def useWeapon(someWeapon) :
    someWeapon.charge()
    someWeapon.prepare()
    someWeapon.attack()
    someWeapon.cleanup()

useWeapon( ChargeGun("Standard ChargeGun",5) )

E non mi dispiacerebbe se charge() dovesse accadere all'istante o comunque non cambiasse lo stato dell'arma. Mi dispiacerebbe se si verificasse un errore o se dovessi verificare se l'arma ha bisogno di essere caricata. Certo, questo significa che gli oggetti devono avere la conoscenza di messaggi che sembrano non avere nulla a che fare con loro. Ma comprendi che l'interfaccia esiste per il cliente che usa l'arma. Non l'arma.

Se si lascia che la conoscenza di quale tipo di arma si stacchi fuori all'improvviso, il cliente deve CONOSCERE a cosa sta parlando. Questa è la morte del polimorfismo.

L'esempio preferito è dire agli animali domestici di parlare. Mi piace non dover dire a un cane di abbaiare o un'anatra di ciarlare. Posso solo dire pet.speak() e qualsiasi animale domestico che sia in grado di capire cosa fare. Se ho bisogno che la mia collezione di animali domestici a volte sia silenziosa, uso un gatto (altrimenti noto come il modello di oggetto nullo ). Digli di parlare e ti ignora (perché è un gatto). Il mio gatto è progettato con cura per accettare e ignorare tranquillamente ogni possibile messaggio. Posso mandare il mio gatto ovunque e le cose funzionano ancora bene senza far esplodere. Tuttavia, il mio pet rock è un altro problema. Dici al mio animaletto di parlare e fa un buco nel tessuto della realtà lamentandosi del fatto che non sa come parlare. Ora puoi stare attento e controllare le rocce, ma è più facile usare i gatti. Sono davvero bravi a non fare nulla.

    
risposta data 26.02.2018 - 18:23
fonte