CodeGym /Blog Java /Aleatoriu /Exemple specifice de clase abstracte în Java
John Squirrels
Nivel
San Francisco

Exemple specifice de clase abstracte în Java

Publicat în grup
Bună! În lecțiile anterioare, ne -am întâlnit cu interfețe și ne-am dat seama pentru ce sunt. Subiectul de astăzi va face ecou pe cel precedent. Să vorbim despre clasele abstracte în Java. Exemple specifice de clase abstracte în Java - 1

De ce orele sunt numite „abstracte”

Probabil vă amintiți ce este „abstracția” – am trecut deja peste ea. :) Dacă ai uitat, nu te teme. Amintiți-vă: este un principiu al OOP care spune că atunci când proiectăm clase și creăm obiecte, ar trebui să identificăm numai proprietățile principale ale entității și să renunțăm la minorul. De exemplu, dacă proiectăm o SchoolTeacherclasă, nu avem nevoie de o proprietate „ înălțime ”. Într-adevăr, această proprietate este irelevantă pentru un profesor. Dar dacă creăm o BasketballPlayerclasă, atunci creșterea ar fi o caracteristică importantă. Ascultă. O clasă abstractăeste la fel de abstract pe cât vin - un „gol” neterminat pentru un grup de clase viitoare. Semnul nu poate fi folosit ca atare. Este prea „brut”. Dar descrie anumite stări și comportament general care vor fi posedate de clasele viitoare care moștenesc clasa abstractă.

Exemple de clase Java abstracte

Luați în considerare un exemplu simplu cu mașini:

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;
   }
}
Așa arată cea mai simplă clasă abstractă. După cum puteți vedea, nu este nimic special :) De ce ne-ar trebui? În primul rând, descrie entitatea noastră necesară, o mașină, în cel mai abstract mod posibil. Există un motiv pentru care folosim cuvântul abstract . În lumea reală, nu există „mașini abstracte”. Există camioane, mașini de curse, sedanuri, coupe-uri și SUV-uri. Clasa noastră abstractă este pur și simplu un „plan” pe care îl vom folosi mai târziu pentru a crea clase de mașini.

public class Sedan extends Car {

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

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

}
Acest lucru este foarte asemănător cu ceea ce am vorbit în lecțiile despre moștenire. Dar în acele lecții aveam o clasă de mașini și metodele sale nu erau abstracte. Dar această soluție are o serie de dezavantaje care sunt fixate în clasele abstracte. În primul rând, nu puteți crea o instanță a unei clase abstracte :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Creatorii Java au conceput special această „funcție”. Încă o dată, ca o reamintire: o clasă abstractă este doar un model pentru viitoarele clase „normale” . Nu aveți nevoie de copii ale planului, nu? Și nu creați instanțe ale unei clase abstracte :) Dar dacă Carclasa nu ar fi abstractă, am putea crea cu ușurință instanțe ale acesteia:

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 fine. A car is created.
   }
}
Acum programul nostru are un fel de mașină de neînțeles - nu este un camion, nu este o mașină de curse, nu este un sedan și nu este total clar ce este. Aceasta este „mașina abstractă” care nu există în natură. Putem oferi același exemplu folosind animale. Imaginați-vă dacă Animalclasele ( animale abstracte ). Nu este clar ce fel de animal este, din ce familie aparține și ce caracteristici are. Ar fi ciudat să vezi asta în programul tău. Nu există „animale abstracte” în natură. Doar câini, pisici, vulpi, alunițe etc. Cursurile abstracte ne eliberează de obiectele abstracte. Ele ne oferă starea și comportamentul de bază. De exemplu, toate mașinile ar trebui să aibă un model , o culoare și o viteză maximă , iar tu ar trebui să poți aplicagaz si frana . Asta este. Acesta este un plan general abstract. Apoi proiectați clasele de care aveți nevoie. Notă: două metode din clasa abstractă sunt, de asemenea, desemnate ca abstract și nu au nicio implementare. Motivul este același: clasele abstracte nu creează un comportament implicit pentru mașinile abstracte. Ele indică doar ce ar trebui să poată face fiecare mașină. Cu toate acestea, dacă aveți nevoie de comportament implicit, puteți implementa metode într-o clasă abstractă. Java nu interzice acest lucru:

public abstract class Car {

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

   public void gas() {
       System.out.println("Gas!");
   }

   public abstract void brake();

   // Getters and setters
}


public class Sedan extends Car {

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

}

public class Main {

   public static void main(String[] args) {

       Sedan sedan = new Sedan();
       sedan.gas();
   }
}
Ieșire consolă: „Gas!” După cum puteți vedea, am implementat prima metodă în clasa abstractă, și nu a doua. Ca urmare, Sedancomportamentul clasei noastre este împărțit în două părți: dacă apelați metoda gas(), apelul „se ridică” la Carclasa părinte abstractă, dar am depășit brake()metoda din Sedanclasă. Acest lucru se dovedește a fi foarte convenabil și flexibil. Dar acum clasa noastră nu este atât de abstractă ? La urma urmei, jumătate din metodele sale sunt implementate. Aceasta este de fapt o caracteristică foarte importantă - o clasă este abstractă dacă cel puțin una dintre metodele sale este abstractă. Una dintre cele două metode, sau cel puțin una dintre o mie de metode - nu are nicio diferență. Putem chiar să implementăm toate metodele și să nu lăsăm nici una dintre ele abstractă. Atunci ar fi o clasă abstractă fără metode abstracte. În principiu, acest lucru este posibil, iar compilatorul nu va genera erori, dar este mai bine să o evitați: Cuvântul abstract își pierde sensul, iar colegii dvs. programatori vor fi foarte surprinși :/ În același timp, dacă o metodă este marcată cu cuvântul abstract, fiecare clasă copil trebuie să îl implementeze sau să îl declare abstract. În caz contrar, compilatorul va genera o eroare. Desigur, fiecare clasă poate moșteni o singură clasă abstractă, așa că în ceea ce privește moștenirea nu există nicio diferență între clasele abstracte și obișnuite. Nu contează dacă moștenim o clasă abstractă sau una obișnuită, poate exista o singură clasă părinte.

De ce Java nu are moștenire multiplă de clase

Am spus deja că Java nu are moștenire multiplă, dar nu am explorat cu adevărat de ce. Să încercăm să facem asta acum. Faptul este că, dacă Java ar avea moștenire multiplă, clasele copil nu ar putea decide ce comportament specific ar trebui să aleagă. Să presupunem că avem două clase - Toasterși NuclearBomb:

public class Toaster {


 public void on() {

       System.out.println("The toaster is on. Toast is being prepared!");
   }

   public void off() {

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


public class NuclearBomb {

   public void on() {

       System.out.println("Boom!");
   }
}
După cum puteți vedea, ambele au o on()metodă. Pentru un prăjitor de pâine, începe să se prăjească. Pentru o bombă nucleară, declanșează o explozie. Hopa: / Acum imaginați-vă că ați decis (nu mă întrebați de ce!) să creați ceva între ele. Și astfel ai o MysteriousDeviceclasă! Acest cod, desigur, nu funcționează și îl oferim doar ca exemplu „dar ar putea fi”:

public class MysteriousDevice extends Toaster, NuclearBomb {

   public static void main(String[] args) {

       MysteriousDevice mysteriousDevice = new MysteriousDevice();
       mysteriousDevice.on(); // So what should happen here? Do we get toast or a nuclear apocalypse?
   }
}
Să aruncăm o privire la ce avem. Dispozitivul misterios moștenește simultan Toaster și NuclearBomb. Ambele au on()metode. Ca urmare, dacă numim on()metoda, nu este clar care dintre ele ar trebui invocată pe MysteriousDeviceobiect. Nu există cum obiectul ar putea ști vreodată. Și pentru a culmea: NuclearBomb nu are o off()metodă, așa că dacă nu am ghicit bine, va fi imposibil să dezactivăm dispozitivul. Exemple specifice de clase abstracte în Java - 2Tocmai din cauza acestei „confuzii”, în care obiectul nu știe ce comportament să prezinte, creatorii Java au abandonat moștenirea multiplă. Cu toate acestea, vă veți aminti că clasele Java pot implementa mai multe interfețe. Apropo, în studiile tale, ai întâlnit deja cel puțin o clasă abstractă!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Este vechiul tău prieten, Calendarclasa. Este abstract și are mai mulți copii. Una dintre ele este GregorianCalendar. L-ai folosit deja în lecțiile despre întâlniri. :) Totul pare destul de clar. Există o singură întrebare: care este diferența fundamentală dintre clasele abstracte și interfețe? De ce le-au adăugat pe ambele în Java, în loc să limiteze limbajul la unul singur? La urma urmei, asta ar fi fost pe deplin adecvat. Vom vorbi despre asta în următoarea lecție ! Pana atunci :)
Comentarii
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION