JavaRush /Blogue Java /Random-PT /Classes abstratas em Java com exemplos concretos

Classes abstratas em Java com exemplos concretos

Publicado no grupo Random-PT
Olá! Nas palestras anteriores, conhecemos interfaces e descobrimos para que servem. O tema de hoje terá algo em comum com o anterior. Vamos falar sobre classes abstratas em Java. Classes abstratas em Java com exemplos concretos - 1

Por que as classes são chamadas de "abstratas"

Você provavelmente se lembra do que é “abstração” - já cobrimos isso :) Se você esqueceu de repente, tudo bem, vamos lembrar: este é o princípio do OOP , segundo o qual ao projetar classes e criar objetos, é necessário destacar apenas as propriedades principais de uma entidade e descartar as secundárias. Por exemplo, se estivermos projetando uma turma SchoolTeacher– um professor escolar – é improvável que precisemos da característica “ altura ”. Na verdade: para um professor esta característica não é importante. Mas se criarmos uma classe no programa BasketballPlayer- um jogador de basquete - a altura se tornará uma das principais características. Portanto, uma classe abstrata é o “espaço em branco” mais abstrato e aproximado para um grupo de classes futuras. Esta preparação não pode ser utilizada na sua forma final - é demasiado “crua”. Mas descreve um certo estado geral e comportamento que as classes futuras - herdeiras da classe abstrata - terão.

Exemplos de classes abstratas Java

Vejamos um exemplo simples com carros:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public abstract void gas();

   public abstract void brake();

   public String getModel() {
       return model;
   }

   public void setModel(String model) {
       this.model = model;
   }

   public String getColor() {
       return color;
   }

   public void setColor(String color) {
       this.color = color;
   }

   public int getMaxSpeed() {
       return maxSpeed;
   }

   public void setMaxSpeed(int maxSpeed) {
       this.maxSpeed = maxSpeed;
   }
}
Esta é a aparência da classe abstrata mais simples. Como você pode ver, nada de especial :) Para que precisamos disso? Em primeiro lugar, ele descreve a entidade de que necessitamos da forma mais abstrata possível - um carro. A palavra resumo está aqui por uma razão. Não existem “apenas máquinas” no mundo. Existem caminhões, carros de corrida, sedãs, cupês, SUVs. Nossa classe abstrata é simplesmente um “projeto” a partir do qual criaremos posteriormente classes de carros.
public class Sedan extends Car {

   @Override
   public void gas() {
       System.out.println("The sedan accelerates!");
   }

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}
Isso é muito parecido com o que falamos nas palestras sobre herança. Só aí tínhamos uma classe Care seus métodos que não eram abstratos. Mas esta solução tem uma série de desvantagens, que são corrigidas em classes abstratas. Em primeiro lugar, uma instância de uma classe abstrata não pode ser criada:
public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Este “truque” foi implementado especificamente pelos criadores do Java. Mais uma vez, só para lembrar: uma classe abstrata é apenas um modelo para futuras classes "normais" . Você não precisa de cópias do desenho, certo? Portanto não há necessidade de criar instâncias de uma classe abstrata :) E se a classe Carnão fosse abstrata, poderíamos facilmente criar seus objetos:
public class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       // some logic
   }

   public  void brake() {
       // some logic
   }
}


public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Everything is OK, the machine has been created
   }
}
Agora temos algum tipo de carro estranho em nosso programa - não um caminhão, não um carro de corrida, não um sedã, mas algo em geral. Esse mesmo “apenas uma máquina” que não existe na natureza. O mesmo exemplo pode ser dado com os animais. Imagine se objetos aparecessem no seu programa Animal- “ apenas um animal ”. Que tipo é, a que família pertence, que características possui - não está claro. Seria estranho vê-lo no programa. Não existem “apenas animais” na natureza. Apenas cães, gatos, raposas, toupeiras e outros. As classes abstratas nos libertam de “ apenas objetos ”. Eles nos dão um estado e comportamento básicos. Por exemplo, todos os carros devem ter modelo , cor e velocidade máxima , e também devem ser capazes de acelerar e frear . Isso é tudo. Este é um esquema geral abstrato, então você mesmo cria as classes necessárias. Observação: dois métodos em uma classe abstrata também são designados como abstract e não são implementados de forma alguma. A razão é a mesma: classes abstratas não criam “comportamento padrão” para “meras máquinas”. Eles apenas dizem que deveriam ser capazes de fabricar todos os carros. No entanto, se você ainda precisar do comportamento padrão, poderá implementar métodos em uma classe abstrata. Java não proíbe isso:
public abstract class Car {

   private String model;
   private String color;
   private int maxSpeed;

   public void gas() {
       System.out.println("Let's go!");
   }

   public abstract void brake();

   //getters and setters
}


public class Sedan extends Car {

   @Override
   public void brake() {
       System.out.println("The sedan slows down!");
   }

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Saída do console: “Acelere!” Como você pode ver, implementamos um método na classe abstrata, mas não implementamos o segundo. Como resultado, o comportamento de nossa classe Sedanfoi dividido em duas partes: se você chamar um método nela gas(), ele “puxará” da classe abstrata pai Care brake()redefinimos o método na classe Sedan. Acabou sendo muito conveniente e flexível. Mas agora nossa classe não é tão abstrata ? Afinal, na verdade, metade de seus métodos são implementados. Na verdade – e esta é uma característica muito importante – uma classe é abstrata se pelo menos um de seus métodos for abstrato . Pelo menos um dos dois, pelo menos um dos mil métodos - não importa. Podemos até implementar todos os métodos e não deixar nenhum abstrato. Haverá uma classe abstrata sem métodos abstratos. Em princípio, isso é possível, e o compilador não produzirá erros, mas é melhor não fazer isso: a palavra abstrato perderá o significado e seus colegas programadores ficarão muito surpresos ao ver isso :/ Além disso, se um método está marcado com a palavra abstract, cada classe descendente deve implementar ou ser declarada abstrata. Caso contrário, o compilador gerará um erro . É claro que cada classe pode herdar apenas uma classe abstrata, portanto, em termos de herança, não há diferença entre classes abstratas e regulares. Não importa se herdamos de uma classe abstrata ou de uma classe normal, só pode haver uma classe pai.

Por que não há herança de múltiplas classes em Java?

Já dissemos que não existe herança múltipla em Java, mas ainda não descobrimos o porquê. Vamos tentar isso agora. A questão é que se Java tivesse herança múltipla, as classes filhas não seriam capazes de decidir qual comportamento escolher. Digamos que temos duas classes - Tostere NuclearBomb:
public class Toster {


 public void on() {

       System.out.println("The toaster is on, the toast is getting ready!");
   }

   public void off() {

       System.out.println("The toaster is off!");
   }
}


public class NuclearBomb {

   public void on() {

       System.out.println("Взрыв!");
   }
}
Como você pode ver, ambos possuem um método on(). No caso de uma torradeira, ela começa a cozinhar torradas e, no caso de uma bomba nuclear, provoca uma explosão. Ah :/ Agora imagine que você decidiu (não sei por que de repente!) Criar algo intermediário. E aqui está a sua aula - MysteriousDevice! Este código, claro, não funciona, e o apresentamos simplesmente como um exemplo de “como poderia ser”:
public class MysteriousDevice extends Toster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // And what should happen here? Will we get a toast, or a nuclear apocalypse?
   }
}
Vamos ver o que temos. O misterioso dispositivo vem tanto da Torradeira quanto da Bomba Nuclear. Ambos têm um método on()e, como resultado, não está claro qual método on()deve ser acionado no objeto MysteriousDevicese o chamarmos. O objeto não será capaz de entender isso. Bom, como cereja no bolo: a Bomba Nuclear não tem método off(), então se adivinharmos errado, não haverá como desligar o aparelho. Classes abstratas em Java com exemplos concretos - 2 É precisamente por causa dessa confusão, quando um objeto não está claro qual comportamento deveria escolher, que os criadores do Java abandonaram a herança múltipla. Entretanto, você lembra que as classes Java implementam muitas interfaces. A propósito, você já encontrou pelo menos uma aula abstrata em seus estudos! Embora, talvez eu não tenha percebido :)
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Esta é a sua velha turma de amigos Calendar. É abstrato e tem vários herdeiros. Um deles é GregorianCalendar. Você já usou nas aulas sobre datas :) Tudo parece claro, só falta um ponto: qual a diferença fundamental entre classes abstratas e interfaces ? Por que eles adicionaram ambos ao Java e não se limitaram a apenas um? Isto poderia muito bem ser suficiente. Falaremos sobre isso na próxima palestra! Vê você:)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION