Python | super() en herencia simple

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 Squarey otra clase llamada Cubeque 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 classno tiene __init__()método, se usará __init__()of para la inicialización de instancias (propiedad básica de herencia).Square classCube

Teniendo en cuenta este ejemplo, sabemos que cada cara de un cubo es un cuadrado y, por lo tanto, face_areaCubo representa areaun Cuadrado. Ahora, tiene sentido evaluar face_areausando area()el método de la clase Squareen 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 Squareusar 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 classuso 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.SquareSquare.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, SquarePrismy Cubepara 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 Cubeheredará 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
SquarePrism
class SquareSquareSquarePrism

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 SquarePrisminstancia 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 Cubeque 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 Cubees 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 Cubedevolverá 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 Squareno es un padre inmediato de class Cube, no podemos acceder al area()método de class Squareas 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, SquarePrismsignifica que super()busca el area()método en el padre inmediato de la clase SquarePrism,que está en el class Square. El uso de selfcomo segundo parámetro proporciona el contexto del Cubeobjeto 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 typepasado como primer argumento.

Nota: dado que la clase Cubees un hijo de class SquarePrism, una Cubeinstancia también es una instancia de class SquarePrismy 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

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *