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)