CodeGym /Java-blogg /Tilfeldig /Spesifikke eksempler på abstrakte klasser i Java
John Squirrels
Nivå
San Francisco

Spesifikke eksempler på abstrakte klasser i Java

Publisert i gruppen
Hei! I tidligere leksjoner møtte vi grensesnitt og fant ut hva de er til for. Dagens emne vil gjenta det forrige. La oss snakke om abstrakte klasser i Java. Spesifikke eksempler på abstrakte klasser i Java - 1

Hvorfor klasser kalles "abstrakt"

Du husker sikkert hva "abstraksjon" er - vi har allerede gått over det. :) Hvis du har glemt, ikke frykt. Husk: det er et prinsipp for OOP som sier at når vi designer klasser og lager objekter, skal vi bare identifisere enhetens hovedegenskaper og forkaste den mindreårige. For eksempel, hvis vi designer en SchoolTeacherklasse, trenger vi knapt en ' høyde' -egenskap. Faktisk er denne egenskapen irrelevant for en lærer. Men hvis vi lager en BasketballPlayerklasse, vil vekst være en viktig egenskap. Så hør. En abstrakt klasseer like abstrakte som de kommer - et uferdig "blank" for en gruppe fremtidige klasser. Tomten kan ikke brukes som den er. Det er for "rå". Men den beskriver visse tilstander og generell atferd som vil bli besatt av fremtidige klasser som arver den abstrakte klassen.

Eksempler på abstrakte Java-klasser

Tenk på et enkelt 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;
   }
}
Slik ser den enkleste abstrakte klassen ut. Som du kan se er det ikke noe spesielt :) Hvorfor skulle vi trenge det? Først og fremst beskriver den vår nødvendige enhet, en bil, på en mest mulig abstrakt måte. Det er en grunn til at vi bruker ordet abstrakt . I den virkelige verden er det ingen "abstrakte biler". Det er lastebiler, racerbiler, sedaner, coupéer og SUV-er. Vår abstrakte klasse er ganske enkelt en "blåkopi" som vi senere skal bruke for å lage 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 er veldig likt det vi snakket om i timene om arv. Men i disse leksjonene hadde vi en bilklasse og metodene var ikke abstrakte. Men den løsningen har en rekke ulemper som er fikset i abstrakte klasser. Først og fremst kan du ikke lage en forekomst av en abstrakt klasse :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Javas skapere designet spesielt denne "funksjonen". Nok en gang, som en påminnelse: en abstrakt klasse er bare en blåkopi for fremtidige "normale" klasser . Du trenger ikke kopier av tegningen, ikke sant? Og du lager ikke forekomster av en abstrakt klasse :) Men hvis klassen Carikke var abstrakt, kunne vi enkelt laget forekomster av 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.
   }
}
Nå har programmet vårt en slags uforståelig bil - det er ikke en lastebil, ikke en racerbil, ikke en sedan, og det er helt uklart hva det er. Dette er den "abstrakte bilen" som ikke finnes i naturen. Vi kan gi det samme eksempelet med dyr. Tenk deg om Animalklasser ( abstrakte dyr ). Det er uklart hva slags dyr det er, hvilken familie det tilhører, og hvilke egenskaper det har. Det ville være rart å se det i programmet ditt. Det er ingen "abstrakte dyr" i naturen. Bare hunder, katter, rever, føflekker osv. Abstrakte klasser befrir oss fra abstrakte objekter. De gir oss grunnleggende tilstand og atferd. For eksempel bør alle biler ha en modell , farge og maksimal hastighet , og du bør kunne brukegass ​​og brems . Det er det. Dette er en generell abstrakt plan. Deretter designer du klassene du trenger. Merk: to metoder i abstraktklassen er også utpekt som abstrakt , og de har ingen implementering. Årsaken er den samme: abstrakte klasser skaper ikke standardoppførsel for abstrakte biler. De indikerer bare hva hver bil skal kunne. Men hvis du trenger standard oppførsel, kan du implementere metoder i en abstrakt klasse. Java forbyr 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();
   }
}
Konsollutgang: "Gass!" Som du kan se, har vi implementert den første metoden i den abstrakte klassen, og ikke den andre. Som et resultat Sedaner klassens oppførsel delt inn i to deler: hvis du kaller metoden gas(), kalles kallet 'stiger' opp til den Carabstrakte overordnede klassen, men vi overstyrte brake()metoden i Sedanklassen. Dette viser seg å være veldig praktisk og fleksibelt. Men nå er ikke klassen vår så abstrakt ? Tross alt er halvparten av metodene implementert. Dette er faktisk en veldig viktig funksjon - en klasse er abstrakt hvis minst én av metodene er abstrakt. En av to metoder, eller minst én av tusen metoder - det spiller ingen rolle. Vi kan til og med implementere alle metodene og la ingen av dem være abstrakte. Da ville det vært en abstrakt klasse uten abstrakte metoder. I prinsippet er dette mulig, og kompilatoren vil ikke generere feil, men det er bedre å unngå det: Ordet abstrakt mister sin betydning, og dine andre programmerere vil bli veldig overrasket :/ Samtidig, hvis en metode er merket med ordet abstrakt må hver barneklasse implementere det eller erklære det som abstrakt. Ellers vil kompilatoren generere en feil. Selvfølgelig kan hver klasse bare arve én abstrakt klasse, så når det gjelder arv, er det ingen forskjell mellom abstrakte og vanlige klasser. Det spiller ingen rolle om vi arver en abstrakt klasse eller en vanlig klasse, det kan bare være én foreldreklasse.

Hvorfor Java ikke har flere klasser

Vi har allerede sagt at Java ikke har multippel arv, men vi har egentlig ikke undersøkt hvorfor. La oss prøve å gjøre det nå. Faktum er at hvis Java hadde flere arv, ville ikke barneklasser kunne bestemme hvilken spesifikk atferd de skulle velge. Anta 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 begynner den å riste. For en atombombe utløser den en eksplosjon. Oops: / Tenk deg nå at du bestemte deg (ikke spør meg hvorfor!) for å lage noe midt i mellom. Og dermed har du en MysteriousDeviceklasse! Denne koden fungerer selvfølgelig ikke, og vi gir den bare som et eksempel «men det kan 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?
   }
}
La oss ta en titt på hva vi har. Den mystiske enheten arver Toaster og NuclearBomb samtidig. Begge har on()metoder. Som et resultat, hvis vi kaller on()metoden, er det uklart hvilken som skal påberopes på objektet MysteriousDevice. Det er ingen måte objektet noen gang kan vite. Og for å toppe det hele: NuclearBomb har ikke en off()metode, så hvis vi ikke gjettet riktig, vil det være umulig å deaktivere enheten. Spesifikke eksempler på abstrakte klasser i Java - 2Det er nettopp på grunn av denne "forvirringen", der objektet ikke vet hvilken oppførsel det skal utvise, at Javas skapere forlot multippel arv. Du vil imidlertid huske at Java-klasser kan implementere flere grensesnitt. Forresten, i studiene dine har du allerede møtt minst én abstrakt klasse!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Det er din gamle venn, Calendarklassen. Den er abstrakt og har flere barn. En av dem er GregorianCalendar. Du har allerede brukt det i leksjonene om datoer. :) Alt virker klart nok. Det er bare ett spørsmål: hva er den grunnleggende forskjellen mellom abstrakte klasser og grensesnitt uansett? Hvorfor la de begge til Java i stedet for bare å begrense språket til ett? Det ville tross alt vært helt tilstrekkelig. Vi skal snakke om dette i neste leksjon ! Inntil da :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION