DEV Community

Cover image for Compartilhando Comportamentos usando Herança no Ruby
Ewerton
Ewerton

Posted on Originally published at ewertoncodes.github.io

Compartilhando Comportamentos usando Herança no Ruby

Um dos pilares da programação orientada a objetos é a herança, que é um conceito que permite que uma classe herde atributos e métodos de outra classe. No Ruby, a herança é feita usando o operador <.

Vamos criar uma classe base simples:

class Character
  def attack
    "Attack"
  end
end
Enter fullscreen mode Exit fullscreen mode

O uso básico do super

O super é a palavra-chave usada para invocar um método da classe pai a partir de uma classe filha. Veja o exemplo de um Guerreiro (Warrior) que herda de Character:

class Warrior < Character
  def attack
    super + " with sword"
  end
end

Warrior.new.attack
#=> "Attack with sword"
Enter fullscreen mode Exit fullscreen mode

Neste caso, chamar super funciona perfeitamente. A classe Warrior herda os métodos de Character e sobrescreve o método attack. A chamada para super executa o attack da classe pai.

A diferença entre super e super()

A confusão começa quando o método da classe filha exige argumentos que a classe pai não espera (ou vice-versa).

Por padrão, chamar apenas super invoca o método da classe pai repassando de forma implícita todos os mesmos argumentos que foram entregues ao método da classe filha.

Se tentarmos criar um Mago (Mage) cujo ataque recebe o nome de uma magia (spell), o uso apenas de super causará um erro:

class Mage < Character
  # O método filho espera 1 argumento (spell)
  def attack(spell)
    super # Isso automaticamente tentará passar o 'spell' para o método pai!
  end
end

Mage.new.attack("Fireball")
#=> "ArgumentError: wrong number of arguments (given 1, expected 0)"
Enter fullscreen mode Exit fullscreen mode

O erro ArgumentError ocorre porque o argumento spell (no caso, "Fireball") foi repassado automaticamente por debaixo dos panos para o método Character#attack, mas a classe Character estava esperando zero argumentos.

Para resolver isso, precisamos usar super() com os parênteses:

class Mage < Character
  def attack(spell)
    super() + " with spell #{spell}"
  end
end

Mage.new.attack("Fireball")
#=> "Attack with spell Fireball"
Enter fullscreen mode Exit fullscreen mode

Resumo:

  • super: Invoca o método da classe pai repassando exatamente os mesmos argumentos que o método atual recebeu.
  • super(): Invoca o método da classe pai explicitamente sem nenhum argumento, não importa quantos argumentos o método atual tenha recebido.

Como sempre, ser explícito no seu código é uma boa prática e evita comportamentos inesperados ao sobrescrever métodos!

Top comments (0)