CodeGym /Java blog /Tilfældig /Specifikke eksempler på abstrakte klasser i Java
John Squirrels
Niveau
San Francisco

Specifikke eksempler på abstrakte klasser i Java

Udgivet i gruppen
Hej! I tidligere lektioner mødte vi grænseflader og fandt ud af, hvad de er til for. Dagens emne vil gentage det forrige. Lad os tale om abstrakte klasser i Java. Specifikke eksempler på abstrakte klasser i Java - 1

Hvorfor klasser kaldes 'abstrakt'

Du husker sikkert, hvad 'abstraktion' er - vi har allerede gennemgået det. :) Hvis du har glemt det, så frygt ikke. Husk: det er et princip i OOP , der siger, at når vi designer klasser og skaber objekter, skal vi kun identificere entitetens hovedegenskaber og kassere den mindre. For eksempel, hvis vi designer en SchoolTeacherklasse, har vi næppe brug for en ' højde ' egenskab. Faktisk er denne egenskab irrelevant for en lærer. Men hvis vi skaber en BasketballPlayerklasse, så ville vækst være en vigtig egenskab. Så hør. En abstrakt klasseer lige så abstrakte som de kommer - et ufærdigt 'blankt' for en gruppe fremtidige klasser. Emnet kan ikke bruges som det er. Det er for 'rå'. Men det beskriver visse tilstande og generel adfærd, som vil blive besiddet af fremtidige klasser, der arver den abstrakte klasse.

Eksempler på abstrakte Java-klasser

Overvej et simpelt eksempel med biler:

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;
   }
}
Sådan ser den enkleste abstrakte klasse ud. Som du kan se, er det ikke noget særligt :) Hvorfor skulle vi have brug for det? Først og fremmest beskriver den vores påkrævede enhed, en bil, på den mest abstrakte måde som muligt. Der er en grund til, at vi bruger ordet abstrakt . I den virkelige verden er der ingen 'abstrakte biler'. Der er lastbiler, racerbiler, sedaner, coupéer og SUV'er. Vores abstrakte klasse er simpelthen en 'blueprint', som vi senere vil bruge til at oprette bilklasser.

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!");
   }

}
Dette minder meget om det, vi talte om i lektionerne om arv. Men i de lektioner havde vi en bilklasse, og dens metoder var ikke abstrakte. Men den løsning har en række ulemper, som er løst i abstrakte klasser. Først og fremmest kan du ikke oprette en instans af en abstrakt klasse :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Javas skabere designet specifikt denne 'funktion'. Endnu en gang, som en påmindelse: en abstrakt klasse er blot en plan for fremtidige 'normale' klasser . Du behøver ikke kopier af planen, vel? Og du opretter ikke forekomster af en abstrakt klasse :) Men hvis klassen Carikke var abstrakt, kunne vi nemt oprette forekomster af den:

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.
   }
}
Nu har vores program en slags uforståelig bil - det er ikke en lastbil, ikke en racerbil, ikke en sedan, og det er fuldstændig uklart, hvad det er. Dette er den meget 'abstrakte bil', der ikke findes i naturen. Vi kan give det samme eksempel med dyr. Forestil dig, hvis Animalklasser ( abstrakte dyr ). Det er uklart, hvilken slags dyr det er, hvilken familie det tilhører, og hvilke egenskaber det har. Det ville være mærkeligt at se det i dit program. Der er ingen 'abstrakte dyr' i naturen. Kun hunde, katte, ræve, muldvarpe osv. Abstrakte klasser befrier os fra abstrakte objekter. De giver os grundlæggende tilstand og adfærd. For eksempel skal alle biler have en model , farve og maksimal hastighed , og du skal være i stand til at anvendegas og bremse . Det er det. Dette er en generel abstrakt plan. Dernæst designer du de klasser, du har brug for. Bemærk: To metoder i abstraktklassen er også udpeget som abstrakt , og de har ingen implementering. Årsagen er den samme: abstrakte klasser skaber ikke standardadfærd for abstrakte biler. De angiver blot, hvad enhver bil skal kunne. Men hvis du har brug for standardadfærd, kan du implementere metoder i en abstrakt klasse. Java forbyder ikke dette:

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();
   }
}
Konsoloutput: "Gas!" Som du kan se, har vi implementeret den første metode i den abstrakte klasse og ikke den anden. Som et resultat Sedaner vores klasses adfærd opdelt i to dele: hvis du kalder metoden gas(), kaldes opkaldet 'stiger' op til den Carabstrakte overordnede klasse, men vi tilsidesatte brake()metoden i Sedanklassen. Dette viser sig at være meget praktisk og fleksibelt. Men nu er vores klasse ikke så abstrakt ? Når alt kommer til alt, er halvdelen af ​​dens metoder implementeret. er faktisk et meget vigtigt træk - en klasse er abstrakt, hvis mindst en af ​​dens metoder er abstrakt. En af to metoder, eller mindst en af ​​tusind metoder - det gør ingen forskel. Vi kan endda implementere alle metoderne og efterlade ingen af ​​dem abstrakte. Så ville det være en abstrakt klasse uden abstrakte metoder. I princippet er dette muligt, og compileren vil ikke generere fejl, men det er bedre at undgå det: Ordet abstrakt mister sin betydning, og dine medprogrammører vil blive meget overraskede :/ Samtidig, hvis en metode er markeret med ordet abstrakt skal hver børneklasse implementere det eller erklære det som abstrakt. Ellers vil compileren generere en fejl. Selvfølgelig kan hver klasse kun arve én abstrakt klasse, så med hensyn til arv er der ingen forskel mellem abstrakte og almindelige klasser. Det er lige meget om vi arver en abstrakt klasse eller en almindelig klasse, der kan kun være én forældreklasse.

Hvorfor Java ikke har flere klasser

Vi har allerede sagt, at Java ikke har multiple arv, men vi har ikke rigtig undersøgt hvorfor. Lad os prøve at gøre det nu. Faktum er, at hvis Java havde flere arv, ville børneklasser ikke være i stand til at bestemme, hvilken specifik adfærd de skulle vælge. Antag, at vi har to klasser - Toasterog 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!");
   }
}
Som du kan se, har begge en on()metode. For en brødrister begynder den at riste. For en atombombe udløser det en eksplosion. Ups: / Forestil dig nu, at du besluttede (spørg mig ikke hvorfor!) for at skabe noget midt imellem. Og dermed har du en MysteriousDeviceklasse! Denne kode virker selvfølgelig ikke, og vi giver den kun som et eksempel 'men det kunne være':

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?
   }
}
Lad os tage et kig på, hvad vi har. Den mystiske enhed arver samtidig Toaster og NuclearBomb. Begge har on()metoder. Som et resultat, hvis vi kalder metoden on(), er det uklart, hvilken der skal påberåbes på MysteriousDeviceobjektet. Der er ingen måde, objektet nogensinde kunne vide. Og for at toppe det hele: NuclearBomb har ikke en off()metode, så hvis vi ikke gættede rigtigt, vil det være umuligt at deaktivere enheden. Specifikke eksempler på abstrakte klasser i Java - 2Det er netop på grund af denne 'forvirring', hvor objektet ikke ved hvilken adfærd det skal udvise, at Javas skabere opgav multiple arv. Du vil dog huske, at Java-klasser kan implementere flere grænseflader. Forresten, i dine studier har du allerede stødt på mindst én abstrakt klasse!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Det er din gamle ven, Calendarklassen. Det er abstrakt og har flere børn. En af dem er GregorianCalendar. Du brugte det allerede i lektionerne om datoer. :) Alt virker klart nok. Der er bare et spørgsmål: hvad er den grundlæggende forskel mellem abstrakte klasser og grænseflader? Hvorfor føjede de begge til Java i stedet for blot at begrænse sproget til et? Det ville trods alt have været helt tilstrækkeligt. Vi taler om dette i næste lektion ! Indtil da :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION