Oi! Nas lições anteriores, já nos familiarizamos brevemente com o conceito de herança. Hoje, vamos tocar neste tópico novamente, mas novamente não muito profundamente. Ainda teremos uma lição mais detalhada sobre isso no futuro. Hoje veremos apenas alguns exemplos práticos e conheceremos um operador interessante em Java.
Herança
Então, o que é herança? Herança é um mecanismo de programação (inclusive em Java) que permite declarar uma nova classe com base em uma já existente. A classe derivada obtém acesso aos campos e métodos da classe pai. Por que precisaríamos disso? Bem, imagine que você precise criar várias classes de carros em um programa: Truck, RaceCar, Sedan, Pickup, etc. Mesmo antes de escrever qualquer código, você sabe com certeza que todas essas classes têm muito em comum: todos os carros têm um modelo nome, ano de fabricação, cilindrada do motor, rotação máxima, etc. (sem contar que todos possuem rodas e outras partes em comum). Nesta situação, você pode:- Crie esses campos em cada classe (adicionando-os a cada nova classe de carro conforme você a cria)
- Traga os campos comuns a todos os carros para uma
Car
classe pai e, em seguida, use a palavra-chave extends para derivar todas as classes para tipos específicos de carros daCar
classe.
public class Car {
private String model;
private int maxSpeed;
private int yearOfManufacture;
public Car(String model, int maxSpeed, int yearOfManufacture) {
this.model = model;
this.maxSpeed = maxSpeed;
this.yearOfManufacture = yearOfManufacture;
}
}
public class Truck extends Car {
public Truck(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
public class Sedan extends Car {
public Sedan(String model, int maxSpeed, int yearOfManufacture) {
super(model, maxSpeed, yearOfManufacture);
}
}
No mínimo, evitamos a duplicação desnecessária de código (e devemos sempre nos esforçar para isso ao escrever programas). Além disso, temos uma estrutura de classes simples e compreensível, com todos os campos comuns a todos os carros consolidados em uma classe. Se os caminhões tiverem campos especiais que outros carros não tenham, eles poderão ser declarados na Truck
classe. O mesmo vale para os métodos. Todos os carros têm certo comportamento comum que pode ser descrito com métodos, por exemplo, ligar o carro, acelerar/frear, etc. Esses métodos comuns podem ser consolidados na Car
classe pai e cada tipo específico de carro pode definir suas ações exclusivas em suas classes derivadas .
public class Car {
public void gas() {
// Accelerate
}
public void brake() {
// Brake
}
}
public class F1Car extends Car {
public void pitStop() {
// Only race cars make pit stops
}
public static void main(String[] args) {
F1Car formula1Car = new F1Car();
formula1Car.gas();
formula1Car.pitStop();
formula1Car.brake();
}
}
Adicionamos os métodos comuns a todos os carros à Car
classe. Mas, olhe para a F1Car
classe, que representa os carros de corrida "Fórmula 1". Os pit stops (paradas para manutenção urgente do carro) são feitos apenas em corridas, então adicionamos essa funcionalidade específica à classe derivada relevante.
instância do operador
Em Java, existe um operador especial, instanceof , para verificar se um objeto foi criado com base em uma determinada classe. Retorna verdadeiro ou falso dependendo do resultado da verificação. Vamos ver como funciona usando as classes do nosso exemplo de carro:
public class Truck extends Car {
public static void main(String[] args) {
Truck truck = new Truck();
System.out.println(truck instanceof Car);
}
}
Saída: true O instanceof
operador retorna true , pois temos um Truck
objeto e todos os caminhões são carros. A Truck
classe é derivada da Car
classe. Todos os caminhões são criados com base no pai comum, a Car
classe. Observe atentamente como o instanceof
operador é usado. Você escreve sem ponto, já que é um operador, não um método ("objeto instanceof Class"). Vamos tentar de outra forma:
public static void main(String[] args) {
Car car = new Car();
System.out.println(car instanceof Truck);
}
Saída: false A Car
classe (e os objetos carro) não derivam da Truck
classe. Todos os caminhões são carros, mas nem todos os carros são caminhões. Car
os objetos não são baseados na Truck
classe. Mais um exemplo:
public static void main(String[] args) {
Car car = new Car();
Truck truck = new Truck();
System.out.println(car instanceof Object && truck instanceof Object);
}
Saída: True Aqui a lógica também é simples: todas as classes em Java, incluindo as classes que você cria, descendem da Object
classe (mesmo que você não escreva "extends Object" — já está implícito). Como e quando isso seria útil? O instanceof
operador é mais comumente usado ao substituir o equals()
método. Por exemplo, veja como o equals
método é implementado na String
classe:
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
Antes de comparar a String
com o objeto passado, o método testa para ver se o objeto é mesmo uma string? Só então começa a comparar as propriedades dos dois objetos. Se este teste não existisse, qualquer objeto com os campos value e length poderia ser passado para o método e comparado com uma String, o que estaria errado, claro.
GO TO FULL VERSION