Requisitos previos: herencia , anulación de función
En un nivel bastante abstracto, super()
proporciona el acceso a los métodos de la superclase (clase principal) que se han anulado en una subclase (clase secundaria) que hereda de ella. Considere el ejemplo de código que se proporciona a continuación, aquí tenemos una clase llamada Square
y otra clase llamada Cube
que hereda la clase Square
.
class Square: def __init__(self, side): self.side = side def area(self): return self.side * self.side class Cube(Square): def area(self): face_area = self.side * self.side return face_area * 6 def volume(self): face_area = self.side * self.side return face_area * self.side
Nota: Como Cube class
no tiene __init__()
método, se usará __init__()
of para la inicialización de instancias (propiedad básica de herencia).Square class
Cube
Teniendo en cuenta este ejemplo, sabemos que cada cara de un cubo es un cuadrado y, por lo tanto, face_area
Cubo representa area
un Cuadrado. Ahora, tiene sentido evaluar face_area
usando area()
el método de la clase Square
en lugar de calcularlo manualmente, no solo nos evitará volver a escribir el código, sino que también nos permitirá cambiar la area()
lógica desde un solo lugar. Pero como hemos anulado el area()
método en Cube
, no podemos llamar al area()
método de Square
usar self.area()
.
Ahora, esta es una situación en la que super()
viene el rescate. super()
devuelve un objeto proxy de la clase principal y luego llama al método de su elección en ese objeto proxy, por lo tanto, podemos llamar al area()
método de Square class
uso super()
como,super().area()
. Aquí sigue una definición modificada de class Cube
.
class Cube(Square): def area(self): return super().area() * 6 def volume(self): return super().area() * self.side()
Tenga en cuenta que podríamos haber llamado al método area()
of como en lugar de , pero este último creador es más fácil de cambiar la superclase o cambiarle el nombre cuando sea necesario, lo que hace que el código sea mucho más fácil de mantener. Pasar argumentos : en la sección anterior, discutimos cómo usar sin ningún parámetro, pero eso solo nos brinda acceso a los métodos de esa superclase que es el padre inmediato de la subclase.Square
Square.area()
super().area()
super()
super()
Para acceder a los métodos de esa superclase que no es un padre inmediato de la subclase, usamos super()
dos argumentos. Consideremos un ejemplo de tres clases llamadas Square
, SquarePrism
y Cube
para entender cómo usarlas super()
con argumentos.
Ahora, un cubo es solo un tipo especial de prisma cuadrado cuya altura es igual al lado de su base y, por lo tanto, un cubo se parece mucho más a un prisma cuadrado que a un cuadrado. Por lo tanto, en este ejemplo class Cube
heredará el class SquarePrism
, y heredará el . Para clase usaremos la misma definición que usamos en la sección anterior. A continuación se muestra la definición de nuestra clase recién definida, .class
SquarePrismclass Square
Square
SquarePrism
class SquarePrism(Square): def __init__(self, side, height): self.side = side self.height = height def face_area(self): base_area = super().area() lateral_area = self.side * self.height return base_area, lateral_area def area(self): base_area = super().area() lateral_area = self.side * self.height return 2 * base_area + 4 * lateral_area
Una SquarePrism
instancia tiene dos atributos, el lado de su base cuadrada y la altura del prisma cuadrado. El método de instancia face_area()
devuelve una tupla de dos números que representan el área de la base del prisma cuadrado y el área lateral del prisma cuadrado. Como la base es un cuadrado, para el área de la base del prisma cuadrado, llamamos al Square.area()
método super().area()
. El area()
método devuelve el área de superficie total del prisma cuadrado.
Hasta ahora, hemos usado super()
sin parámetros, ahora sigue la definición de la nueva clase Cube
que demostrará el uso de super()
con parámetros.
class Cube(SquarePrism): def __init__(self, side) super().__init__(side = side, height = side) def face_area(self): return super(SquarePrism, self).area() def area(self): return super().area()
A diferencia de los métodos __init__()
y area()
, el face_area()
método de Cube
es algo diferente de su contraparte SquarePrism.face_area()
. Para un cubo, el área lateral es igual al área de la base y, por lo tanto, no tiene sentido que el face_area()
método devuelva una tupla; por lo tanto, el face_area()
de class Cube
devolverá el área de una de las caras del cubo.
Ahora, dado que cada cara del cubo es un cuadrado, nuevamente tiene sentido usar el area()
método de class Square
. Ahora, dado que the class Square
no es un padre inmediato de class Cube
, no podemos acceder al area()
método de class Square
as super().area()
, ya que llamará al método SquarePrism.area()
en su lugar.
Aquí usamos super(SquarePrism, self).face_area()
para llamar al area()
método del class Square
. En el primer argumento, SquarePrism
significa que super()
busca el area()
método en el padre inmediato de la clase SquarePrism,
que está en el class Square
. El uso de self
como segundo parámetro proporciona el contexto del Cube
objeto actual para que actúe el método super()
solicitado .area()
Recuerde que, para usar super()
en forma de dos argumentos, es necesario que el objeto pasado como segundo argumento sea una instancia del type
pasado como primer argumento.
Nota: dado que la clase Cube
es un hijo de class SquarePrism
, una Cube
instancia también es una instancia de class SquarePrism
y el class Square
.
Pruebe el siguiente fragmento de código y observe el resultado para aclarar el punto anterior.
class Square: def __init__(self): pass class SquarePrism(Square): def __init__(self): pass class Cube(SquarePrism): def __init__(self): pass square = Square() squareprism = SquarePrism() cube = Cube() print(isinstance(squareprism, Square)) print(isinstance(cube, Square))
Vale la pena señalar que la forma de argumento cero de super()
solo se puede usar dentro de una definición de clase, ya que el compilador la completa automáticamente con los parámetros apropiados, es decir, si usamos super()
dentro de una clase, digamos X
, el compilador la super()
convertirá en super(X, self)
.
Si bien la forma de cero argumentos super()
es popular entre los desarrolladores, la forma de dos argumentos puede no parecer muy útil por ahora. Pero en la herencia múltiple, la forma de dos argumentos juega un papel muy importante.
Publicación traducida automáticamente
Artículo escrito por Manthanchauhan y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA