IIC2233 / syllabus-2020-1

Repositorio oficial del curso IIC2233 Programación Avanzada 🎉🎊
35 stars 68 forks source link

Herencia: Definir getter y setter en clases distintas #317

Closed mpmunoz13 closed 4 years ago

mpmunoz13 commented 4 years ago

Hola! Se puede definir el getter en una clase y el setter dentro de la sub-clase? o deben ir juntos?

igbasly commented 4 years ago

Hola @mpmunoz13 😄 Interesante pregunta acerca de herencia y uso de properties 🤔, según lo que estuve averiguando y probando, sí se puede definir el setter en una sub-clase, habiendo definido la property en la clase padre. Un ejemplo podría verse así:

class Clase1:
    def __init__(self):
        self.__atributo = 0

    @property
    def prop(self):
        print("Se ha llamado al getter")
        return self.__atributo

class Clase2(Clase1):
    def __init__(self):
        super().__init__()

    @Clase1.prop.setter
    def prop(self, value):
        self.__atributo = value
        print("Se ha establecido un nuevo valor:", value)

Hay que considerar que en las properties no es necesario definir getter y setter en conjunto, pude existir solo el getter. Claro, si intentas asignarle un valor al atributo, arrojará un error por la falta del método. Además, para poder definir el setter en una sub-clase, se debe hacer llamando a la property de la clase padre directamente @Clase1.prop.setter. Esto debido a que si solo pusieras @prop.setter, Python al momento de ejecutar el código y llegue a class Clase2(Clase1): para definir todos los métodos (recuerda que Python crea los métodos antes de ser instanciada la clase) se encontrará con que no existe un atributo prop, porque viene desde la super-clase, y a nivel de programa aún no se ha concretado la herencia (esto sucede en el super().__init__() al momento de instanciar la clase). En resumen, genera un error 😅 .

Como último detalle, siempre es válido que definas toda la property de nuevo en la clase heredada (overriding), no hay problema con eso tampoco.

Por favor comenta si algo no quedó claro o si surgió alguna otra duda producto de la explicación. Saludos :v:

NikiHV commented 4 years ago

Una pregunta, ¿sabes si usar @super().prop.setter funciona en lugar de @Clase1.prop.setter?

mpmunoz13 commented 4 years ago

Quedo clarisimo! Muchas Gracias!!

igbasly commented 4 years ago

Una pregunta, ¿sabes si usar @super().prop.setter funciona en lugar de @Clase1.prop.setter?

Hola @NikiHV :v: Respecto a tu pregunta, no, utilizar super() en vez de Clase1 no funciona para definir la property. Esto se puede explicar entendiendo un poco cómo funciona super, ya que en teoría super no es la clase padre, sino que una clase intermedia que nos permite acceder a instancias temporales de las super-clases. Por otro lado, el funcionamiento de super necesita que la clase esté definida, porque internamente el super que nosotros colocamos super(), Python lo transforma a super(ClaseActual, self) siendo ClaseActual la clase donde super está siendo utilizado. A lo que quiero llegar, es que si pusiéramos el super al definir la property como @super().prop.setter, esto se leería durante la definición de la clase, es decir, aún no está definida, por lo tanto, Python no podría completar el super porque no puede entregarle una clase que aún no existe, lo que arroja un error 😕 .

Lo siento si me alargué un poco, pero creo que es importante entender porque algo no funciona más allá un simple "no funciona" jajajaja. Espero haber sido claro en la explicación y hazme saber si aún hay alguna duda 😅

NikiHV commented 4 years ago

Gracias!! Se valora mucho que nos den explicaciones extensivas de porque ocurren las cosas, meritorio de estudiantes universitarios 😄 Me quedó clarito!! Muchas gracias!!