Herança
Herança é uma das características centrais da OOP, permitindo reutilização de código.
O que é Herança
Herança permite que uma subclasse herde atributos e métodos de uma classe pai, permitindo reutilização de código.
Benefícios da Herança
| Benefício | Descrição |
|---|---|
| Reutilização de código | Não é necessário reescrever o código da classe pai |
| Extensibilidade | Subclasses podem adicionar seus próprios atributos e métodos |
| Base para polimorfismo | Herança é um pré-requisito para polimorfismo |
A Palavra-chave extends
Sintaxe
public class ClasseFilha extends ClassePai {
// Atributos e métodos específicos da classe filha
}
Exemplo: Herança
// Classe pai
public class Animal {
String name;
int age;
public void eat() {
System.out.println(name + " está comendo");
}
public void sleep() {
System.out.println(name + " está dormindo");
}
}
// Classe filha
public class Dog extends Animal {
String breed;
public void bark() {
System.out.println(name + " está latindo");
}
}
public class Cat extends Animal {
String color;
public void meow() {
System.out.println(name + " está miando");
}
}
public class InheritanceDemo {
public static void main(String[] args) {
Dog dog = new Dog();
dog.name = "Buddy";
dog.age = 3;
dog.breed = "Golden Retriever";
dog.eat(); // Buddy está comendo (herdado de Animal)
dog.sleep(); // Buddy está dormindo (herdado de Animal)
dog.bark(); // Buddy está latindo (método próprio do Dog)
Cat cat = new Cat();
cat.name = "Whiskers";
cat.age = 2;
cat.color = "White";
cat.eat(); // Whiskers está comendo
cat.meow(); // Whiskers está miando
}
}
A Palavra-chave super
super é uma referência à classe pai.
Uso 1: Chamar Construtor Pai
public class Animal {
String name;
int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
}
public class Dog extends Animal {
String breed;
public Dog(String name, int age, String breed) {
super(name, age); // Chamar construtor pai
this.breed = breed;
}
}
Uso 2: Chamar Método Pai
public class Animal {
public void eat() {
System.out.println("Animal está comendo");
}
}
public class Dog extends Animal {
@Override
public void eat() {
super.eat(); // Chamar eat do pai
System.out.println("Cão está roendo um osso");
}
}
Exemplo: Usando super
public class Person {
protected String name;
protected int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void showInfo() {
System.out.println("Nome: " + name + ", Idade: " + age);
}
}
public class Student extends Person {
private double score;
public Student(String name, int age, double score) {
super(name, age); // Chamar construtor pai
this.score = score;
}
@Override
public void showInfo() {
super.showInfo(); // Chamar showInfo do pai
System.out.println("Pontuação: " + score);
}
}
public class SuperDemo {
public static void main(String[] args) {
Student stu = new Student("Alice", 20, 95.5);
stu.showInfo();
// Nome: Alice, Idade: 20
// Pontuação: 95.5
}
}
Sobrescrita de Métodos
Subclasses podem sobrescrever métodos da classe pai para implementar comportamento diferente.
Regras de Sobrescrita
| Regra | Descrição |
|---|---|
| Mesmo nome de método | Obrigatório |
| Mesma lista de parâmetros | Obrigatório |
| Mesmo tipo de retorno | Ou uma subclasse do tipo de retorno do pai |
| Acesso não pode ser mais restritivo | Pode ser mais permissivo |
Anotação @Override
public class Dog extends Animal {
@Override
public void eat() {
System.out.println("Cão está roendo um osso");
}
}
@Override ao sobrescrever métodos. O compilador verificará se a sobrescrita está correta.
A Classe Object
Todas as classes herdam direta ou indiretamente da classe Object.
Métodos Comuns de Object
| Método | Descrição |
|---|---|
toString() |
Retorna uma representação em string do objeto |
equals() |
Compara objetos para igualdade |
hashCode() |
Retorna o código hash do objeto |
getClass() |
Retorna informações da classe do objeto |
Sobrescrevendo toString()
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{name='" + name + "', age=" + age + "}";
}
public static void main(String[] args) {
Student stu = new Student("Alice", 20);
System.out.println(stu); // Chama toString() automaticamente
// Saída: Student{name='Alice', age=20}
}
}
Sobrescrevendo equals()
public class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
Student other = (Student) obj;
return age == other.age && name.equals(other.name);
}
@Override
public int hashCode() {
return name.hashCode() * 31 + age;
}
public static void main(String[] args) {
Student s1 = new Student("Alice", 20);
Student s2 = new Student("Alice", 20);
System.out.println(s1 == s2); // false (objetos diferentes)
System.out.println(s1.equals(s2)); // true (mesmo conteúdo)
}
}
instanceof
O operador instanceof verifica se um objeto é uma instância de uma classe específica.
public class InstanceofDemo {
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // true
System.out.println(dog instanceof Animal); // true
System.out.println(dog instanceof Object); // true
}
}
Notas sobre Herança
| Nota | Descrição |
|---|---|
| Herança simples | Java só suporta herança simples |
| Não pode herdar private | Membros privados não podem ser herdados |
| Não pode herdar construtores | Construtores não podem ser herdados |
| Object é classe raiz | Todas as classes herdam de Object |
❓ Perguntas Frequentes
P: Por que Java não suporta herança múltipla? R: Para evitar o problema do diamante (ambiguidade quando múltiplos pais têm o mesmo método). Java usa interfaces para funcionalidade similar.
P: Quando devo usar herança? R: Quando duas classes têm uma relação "é-um", como Cão é um Animal.
P: Como escolher entre herança e composição? R: Prefira composição (relação "tem-um"). Herança aumenta o acoplamento.
📖 Resumo
- Herança usa a palavra-chave extends para reutilização de código
- super é usado para chamar construtores e métodos da classe pai
- Sobrescrita de métodos: subclasses substituem métodos da classe pai
- Todas as classes herdam da classe Object
- instanceof verifica o tipo do objeto
📝 Exercícios
- Hierarquia de formas: Defina uma classe pai Shape com subclasses Circle e Rectangle, calcule áreas
- Hierarquia de funcionários: Defina uma classe pai Employee com subclasses Manager e Developer
- toString/equals: Sobrescreva os métodos toString e equals em uma classe Student
Próxima Lição
Na próxima lição, aprenderemos sobre Polimorfismo e Abstração — características centrais da OOP.



