
Animal
classe pai, que representa os animais, e criar um
speak
método nela:
public class Animal {
public void speak() {
System.out.println("Hello!");
}
}
Embora tenhamos acabado de começar a escrever nosso programa, você provavelmente pode ver um problema em potencial: o mundo está cheio de muitos animais e todos eles "falam" de maneira diferente: gatos miam, patos grasnam, cobras sibilam, etc. Nosso objetivo é simples:

meow()
método para miar,
hiss()
sibilar, etc., queremos que a cobra sibile, o gato mie e o cachorro latir quando o
speak()
método for chamado. Podemos conseguir isso facilmente usando
substituição de método . A Wikipédia explica o termo da seguinte forma:
Substituição de método, na programação orientada a objetos, é um recurso de linguagem que permite que uma subclasse ou classe filha forneça uma implementação específica de um método que já é fornecido por uma de suas superclasses ou classes pai. Isso é basicamente correto. A substituição permite que você pegue algum método de uma classe pai e escreva sua própria implementação em cada classe derivada. A nova implementação na classe filha "substitui" a da classe pai. Vamos ver como isso se parece com um exemplo. Vamos criar 4 descendentes da nossa
Animal
classe:
public class Bear extends Animal {
@Override
public void speak() {
System.out.println("Growl!");
}
}
public class Cat extends Animal {
@Override
public void speak() {
System.out.println("Meow!");
}
}
public class Dog extends Animal {
@Override
public void speak() {
System.out.println("Woof!");
}
}
public class Snake extends Animal {
@Override
public void speak() {
System.out.println("Hiss!");
}
}
Aqui está um pequeno macete para o futuro: para sobrescrever os métodos de uma classe pai, entre no código da classe derivada no
IntelliJ IDE , pressione
Ctrl+O e selecione
Substituir métodos... no menu. Acostume-se a usar teclas de atalho desde o início. Eles vão acelerar a codificação! Para obter o comportamento desejado, fizemos algumas coisas:
- Em cada classe descendente, criamos um método com o mesmo nome do método na classe pai.
-
Dissemos ao compilador que não estamos apenas dando ao método o mesmo nome da classe pai, mas queremos sobrescrever seu comportamento. Essa "mensagem" para o compilador é transmitida por meio da anotação @Override .
A anotação @Override acima de um método informa ao compilador (bem como a outros programadores que leem seu código): "Não se preocupe. Isso não é um erro ou descuido. Estou ciente de que esse método já existe e quero substituí-lo . - Escrevemos a implementação necessária para cada classe descendente. Quando o
speak()
método é chamado, uma cobra deve assobiar, um urso deve rosnar e assim por diante.
public class Main {
public static void main(String[] args) {
Animal animal1 = new Dog();
Animal animal2 = new Cat();
Animal animal3 = new Bear();
Animal animal4 = new Snake();
animal1.speak();
animal2.speak();
animal3.speak();
animal4.speak();
}
}
Saída do console:
Woof!
Meow!
Growl!
Hiss!
Ótimo, tudo funciona como deveria! Criamos 4 variáveis de referência cujo tipo é a
Animal
classe pai e atribuímos a elas 4 objetos diferentes das classes descendentes. Como resultado, cada objeto se comporta de maneira diferente. Para cada uma das classes derivadas, o
speak()
método substituído substitui o método existente
speak()
da
Animal
classe (que simplesmente exibe "Speaking:" no console).

-
Um método substituído deve ter os mesmos argumentos que o método na classe pai.
Se o
speak
método da classe pai receber aString
como entrada, o método substituído na classe descendente também deverá receber aString
como entrada. Caso contrário, o compilador irá gerar um erro:public class Animal { public void speak(String s) { System.out.println("Speaking: " + s); } } public class Cat extends Animal { @Override // Error! public void speak() { System.out.println("Meow!"); } }
-
O método substituído deve ter o mesmo tipo de retorno que o método na classe pai.
Caso contrário, obteremos um erro de compilação:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override public String speak() { // Error! System.out.println("Meow!"); return "Meow!"; } }
-
O modificador de acesso do método substituído também não pode diferir do original:
public class Animal { public void speak() { System.out.println("Hello!"); } } public class Cat extends Animal { @Override private void speak() { // Error! System.out.println("Meow!"); } }
speak()
método para todos, em vez de vários métodos diferentes, por exemplo
bark()
,
meow()
, etc.
GO TO FULL VERSION