CodeGym /Java blogg /Slumpmässig /Specifika exempel på abstrakta klasser i Java
John Squirrels
Nivå
San Francisco

Specifika exempel på abstrakta klasser i Java

Publicerad i gruppen
Hej! I tidigare lektioner träffade vi gränssnitt och kom på vad de är till för. Dagens ämne kommer att upprepa det föregående. Låt oss prata om abstrakta klasser i Java. Specifika exempel på abstrakta klasser i Java - 1

Varför klasser kallas "abstrakta"

Du kommer säkert ihåg vad "abstraktion" är - vi har redan gått igenom det. :) Om du glömde, frukta inte. Kom ihåg: det är en princip för OOP som säger att när vi designar klasser och skapar objekt ska vi endast identifiera enhetens huvudegenskaper och kassera den mindre. Om vi ​​till exempel designar en SchoolTeacherklass behöver vi knappast en " höjd "-egenskap. Den här egenskapen är faktiskt irrelevant för en lärare. Men om vi skapar en BasketballPlayerklass, då skulle tillväxt vara en viktig egenskap. Så lyssna. En abstrakt klassär lika abstrakta som de kommer — ett oavslutat "blankt" för en grupp framtida klasser. Tomten kan inte användas som den är. Det är för "rå". Men den beskriver visst tillstånd och allmänt beteende som kommer att ägas av framtida klasser som ärver den abstrakta klassen.

Exempel på abstrakta Java-klasser

Tänk på ett enkelt exempel med bilar:

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å här ser den enklaste abstrakta klassen ut. Som ni ser är det inget speciellt :) Varför skulle vi behöva det? Först och främst beskriver den vår nödvändiga enhet, en bil, på ett så abstrakt sätt som möjligt. Det finns en anledning till att vi använder ordet abstrakt . I den verkliga världen finns det inga "abstrakta bilar". Det finns lastbilar, racerbilar, sedaner, coupéer och stadsjeepar. Vår abstrakta klass är helt enkelt en "blåkopia" som vi kommer att använda senare för att skapa 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!");
   }

}
Detta är väldigt likt det vi pratade om på lektionerna om arv. Men på de lektionerna hade vi en bilklass och dess metoder var inte abstrakta. Men den lösningen har ett antal nackdelar som är fixade i abstrakta klasser. Först och främst kan du inte skapa en instans av en abstrakt klass :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
Javas skapare designade specifikt denna "funktion". Återigen, som en påminnelse: en abstrakt klass är bara en plan för framtida "normala" klasser . Du behöver inga kopior av ritningen, eller hur? Och du skapar inte instanser av en abstrakt klass :) Men om klassen Carinte var abstrakt skulle vi enkelt kunna skapa instanser 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.
   }
}
Nu har vårt program någon sorts obegriplig bil — det är inte en lastbil, inte en racerbil, inte en sedan, och det är helt oklart vad det är. Detta är den mycket "abstrakta bilen" som inte finns i naturen. Vi kan ge samma exempel med djur. Tänk dig om Animalklasser ( abstrakta djur ). Det är oklart vilken typ av djur det är, vilken familj det tillhör och vilka egenskaper det har. Det skulle vara konstigt att se det i ditt program. Det finns inga "abstrakta djur" i naturen. Endast hundar, katter, rävar, mullvadar etc. Abstrakta klasser befriar oss från abstrakta föremål. De ger oss grundläggande tillstånd och beteende. Till exempel bör alla bilar ha en modell , färg och maximal hastighet , och du bör kunna tillämpagas och broms . Det är allt. Detta är en allmän abstrakt plan. Därefter designar du de klasser du behöver. Obs: två metoder i abstraktklassen är också betecknade som abstrakt , och de har ingen implementering. Anledningen är densamma: abstrakta klasser skapar inte standardbeteende för abstrakta bilar. De anger bara vad varje bil ska kunna göra. Men om du behöver standardbeteende kan du implementera metoder i en abstrakt klass. Java förbjuder inte detta:

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();
   }
}
Konsolutdata: "Gas!" Som du kan se har vi implementerat den första metoden i den abstrakta klassen, och inte den andra. Som ett resultat Sedandelas vår klasss beteende upp i två delar: om du anropar metoden gas(), anropet "stiger" upp till den Carabstrakta överordnade klassen, men vi åsidosatte brake()metoden i Sedanklassen. Detta visar sig vara väldigt bekvämt och flexibelt. Men nu är vår klass inte så abstrakt ? När allt kommer omkring är hälften av dess metoder implementerade. Detta är faktiskt en mycket viktig egenskap - en klass är abstrakt om åtminstone en av dess metoder är abstrakt. En av två metoder, eller åtminstone en av tusen metoder - det gör ingen skillnad. Vi kan till och med implementera alla metoder och lämna ingen av dem abstrakt. Då skulle det vara en abstrakt klass utan abstrakta metoder. I princip är detta möjligt, och kompilatorn kommer inte att generera fel, men det är bättre att undvika det: Ordet abstrakt förlorar sin betydelse, och dina andra programmerare kommer att bli mycket förvånade :/ Samtidigt, om en metod markeras med ordet abstrakt måste varje barnklass implementera det eller förklara det som abstrakt. Annars kommer kompilatorn att generera ett fel. Naturligtvis kan varje klass bara ärva en abstrakt klass, så när det gäller arv är det ingen skillnad mellan abstrakta och vanliga klasser. Det spelar ingen roll om vi ärver en abstrakt klass eller en vanlig, det kan bara finnas en förälderklass.

Varför Java inte har flera arv av klasser

Vi har redan sagt att Java inte har flera arv, men vi har inte riktigt utforskat varför. Låt oss försöka göra det nu. Faktum är att om Java hade flera arv, skulle barnklasser inte kunna bestämma vilket specifikt beteende de skulle välja. Anta att vi har två klasser - Toasteroch 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 båda en on()metod. För en brödrost börjar den rosta. För en kärnvapenbomb sätter den igång en explosion. Oj: / Föreställ dig nu att du bestämde dig (fråga mig inte varför!) för att skapa något däremellan. Och därmed har du en MysteriousDeviceklass! Den här koden fungerar naturligtvis inte, och vi tillhandahåller den bara som ett exempel "men det kan vara":

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?
   }
}
Låt oss ta en titt på vad vi har. Den mystiska enheten ärver Brödrost och NuclearBomb samtidigt. Båda har on()metoder. Som ett resultat, om vi anropar on()metoden, är det oklart vilken som ska anropas på objektet MysteriousDevice. Det finns inget sätt att objektet någonsin kan veta. Och till råga på allt: NuclearBomb har ingen off()metod, så om vi inte gissade rätt kommer det att vara omöjligt att inaktivera enheten. Specifika exempel på abstrakta klasser i Java - 2Det är just på grund av denna "förvirring", där objektet inte vet vilket beteende det ska uppvisa, som Javas skapare övergav flera arv. Du kommer dock ihåg att Java-klasser kan implementera flera gränssnitt. Förresten, i dina studier har du redan stött på minst en abstrakt klass!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Det är din gamla vän, klassen Calendar. Den är abstrakt och har flera barn. En av dem är GregorianCalendar. Du använde det redan i lektionerna om datum. :) Allt verkar tydligt nog. Det finns bara en fråga: vad är den grundläggande skillnaden mellan abstrakta klasser och gränssnitt egentligen? Varför lade de till båda i Java istället för att bara begränsa språket till ett? Det hade trots allt varit helt lagom. Vi kommer att prata om detta i nästa lektion ! Tills dess :)
Kommentarer
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION