CodeGym /Java blog /Véletlen /Konkrét példák a Java absztrakt osztályaira
John Squirrels
Szint
San Francisco

Konkrét példák a Java absztrakt osztályaira

Megjelent a csoportban
Szia! Az elmúlt órákon találkoztunk interfészekkel , és rájöttünk, mire valók. A mai téma az előzőt visszhangozza. Beszéljünk a Java absztrakt osztályairól .Konkrét példák absztrakt osztályokra a Java nyelven - 1

Miért nevezik az osztályokat "absztraktnak"

Valószínűleg emlékszel, mi az „absztrakció” – már túl vagyunk rajta. :) Ha elfelejtette, ne féljen. Ne feledje: az OOP alapelve szerint osztályok tervezésekor és objektumok létrehozásakor csak az entitás fő tulajdonságait kell azonosítanunk, a minort pedig el kell vetnünk. Például, ha egy osztályt tervezünk SchoolTeacher, aligha van szükségünk „ magasság ” tulajdonságra. Valójában ez a tulajdonság irreleváns egy tanár számára. De ha osztályt hozunk létre BasketballPlayer, akkor a növekedés fontos jellemző lenne. Szóval figyelj. Absztrakt osztályolyan elvont, amilyen csak jönnek – befejezetlen „üres” a jövőbeli osztályok egy csoportja számára. A blank nem használható úgy, ahogy van. Túl 'nyers'. De leír bizonyos állapotokat és általános viselkedést, amelyek az absztrakt osztályt öröklő jövőbeli osztályok birtokában lesznek.

Példák absztrakt Java osztályokra

Vegyünk egy egyszerű példát autókkal:

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;
   }
}
Így néz ki a legegyszerűbb absztrakt osztály. Amint látod, semmi különös :) Miért is lenne rá szükségünk? Mindenekelőtt a lehető legelvontabb módon írja le a szükséges entitásunkat, egy autót. Megvan az oka annak, hogy miért használjuk az absztrakt szót . A való világban nincsenek „absztrakt autók”. Vannak teherautók, versenyautók, szedánok, kupék és terepjárók. Absztrakt osztályunk egyszerűen egy „tervrajz”, amelyet később az autóosztályok létrehozásához fogunk használni.

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

}
Ez nagyon hasonlít ahhoz, amiről az örökléssel foglalkozó leckéken beszéltünk. De azokon az órákon volt egy Autó osztályunk, és a módszerei nem voltak elvontak. Ennek a megoldásnak azonban számos hátránya van, amelyeket az absztrakt osztályokban rögzítenek. Az első és legfontosabb, hogy nem hozhat létre egy absztrakt osztály példányát :

public class Main {

   public static void main(String[] args) {

       Car car = new Car(); // Error! The Car class is abstract!
   }
}
A Java alkotói kifejezetten ezt a „funkciót” tervezték. Még egyszer emlékeztetőül: egy absztrakt osztály csak egy tervrajz a jövőbeli „normál” osztályokhoz . Nincs szükség másolatokra a tervrajzról, igaz? És nem hoz létre egy absztrakt osztály példányait :) De ha az Carosztály nem lenne absztrakt, akkor könnyen létrehozhatunk belőle példányokat:

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.
   }
}
Most a programunkban van valami érthetetlen autó – ez nem teherautó, nem versenyautó, nem szedán, és teljesen homályos, hogy mi az. Ez az a nagyon „absztrakt autó”, ami a természetben nem létezik. Ugyanezt a példát mutathatjuk be állatok felhasználásával is. Képzeld el, ha Animalosztályok ( absztrakt állatok ). Nem világos, hogy milyen állatról van szó, milyen családhoz tartozik, és milyen tulajdonságokkal rendelkezik. Furcsa lenne ezt látni a programodban. A természetben nincsenek „absztrakt állatok”. Csak kutyák, macskák, rókák, vakondok stb. Az absztrakt osztályok megszabadítanak minket az absztrakt tárgyaktól. Alapállapotot és viselkedést adnak nekünk. Például minden autónak rendelkeznie kell egy modellel , színnel és maximális sebességgel , és képesnek kell lennie agáz és fék . Ez az. Ez egy általános absztrakt terv. Ezután megtervezi a szükséges osztályokat. Megjegyzés: az absztrakt osztály két metódusa is absztrakt , és nincs implementációjuk. Az ok ugyanaz: az absztrakt osztályok nem hoznak létre alapértelmezett viselkedést az absztrakt autók számára. Csak azt jelzik, hogy minden autónak mire kell képesnek lennie. Ha azonban alapértelmezett viselkedésre van szüksége, a metódusokat megvalósíthatja egy absztrakt osztályban. A Java ezt nem tiltja:

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();
   }
}
Konzol kimenete: „Gáz!” Amint látja, az első metódust valósítottuk meg az absztrakt osztályban, és nem a másodikat. Ennek eredményeként osztályunk Sedanviselkedése két részre oszlik: ha meghívja a gas()metódust, a hívás 'felemelkedik' az Carabsztrakt szülőosztályig, de felülírtuk a brake()metódust az Sedanosztályban. Ez nagyon kényelmesnek és rugalmasnak bizonyult. De most már nem olyan elvont az osztályunk ? Végül is a metódusainak fele implementálva van. Ez valójában egy nagyon fontos jellemző - egy osztály absztrakt, ha legalább egy metódusa absztrakt. A két módszer egyike, vagy legalább egy az ezer módszer közül – ez nem számít. Akár az összes módszert megvalósíthatjuk, és egyiket sem hagyjuk elvontnak. Akkor ez egy absztrakt osztály lenne absztrakt módszerek nélkül. Ez elvileg lehetséges, és a fordító nem fog hibát generálni, de jobb elkerülni: Az absztrakt szó értelmét veszti, és a programozó társaid nagyon meg fognak lepődni :/ Ugyanakkor, ha egy metódus ki van jelölve az absztrakt szóval minden gyermekosztálynak végre kell hajtania, vagy absztraktnak kell nyilvánítania. Ellenkező esetben a fordító hibát generál. Természetesen minden osztály csak egy absztrakt osztályt örökölhet, így az öröklődés szempontjából nincs különbség az absztrakt és a közönséges osztályok között. Mindegy, hogy absztrakt vagy közönséges osztályt örökölünk, szülőosztály csak egy lehet.

Miért nem rendelkezik a Java osztályok többszörös öröklésével?

Azt már mondtuk, hogy a Java-nak nincs többszörös öröklődése, de nem igazán vizsgáltuk, hogy miért. Próbáljuk meg most megtenni. A tény az, hogy ha a Java többszörös öröklődésű lenne, a gyermekosztályok nem tudnák eldönteni, hogy melyik viselkedést válasszák. Tegyük fel, hogy két osztályunk van – Toasterés 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!");
   }
}
Amint látja, mindkettőnek megvan a maga on()módszere. Kenyérpirítónál elkezd pirítani. Egy atombomba esetében robbanást indít el. Hoppá: / Most képzeld el, hogy úgy döntöttél (ne kérdezd, miért!), hogy létrehozol valamit a kettő között. És így van egy MysteriousDeviceosztályod! Ez a kód természetesen nem működik, és csak példaként adjuk meg "de lehet":

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?
   }
}
Nézzük meg, mi van. A titokzatos eszköz egyszerre örökli a Toastert és a NuclearBombot. Mindkettőnek van on()módszere. Ennek eredményeként, ha meghívjuk a on()metódust, nem világos, hogy melyiket kell meghívni az objektumon MysteriousDevice. Lehetetlen, hogy a tárgy valaha is megtudja. És mindennek a tetejébe: A NuclearBombnak nincs off()módszere, így ha nem jól tippeltünk, lehetetlen lesz letiltani az eszközt. Konkrét példák absztrakt osztályokra a Java nyelven - 2Pontosan ennek a „zavarnak” köszönhetően, amikor az objektum nem tudja, milyen viselkedést tanúsítson, a Java alkotói felhagytak a többszörös öröklődéssel. Emlékeztetni kell azonban arra, hogy a Java osztályok több felületet is megvalósíthatnak. Egyébként a tanulmányaid során találkoztál már legalább egy absztrakt osztállyal!

public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar>
Ez a régi barátod, az Calendarosztály. Absztrakt, és több gyermeke van. Az egyikük GregorianCalendar. Már használtad a dátumokról szóló leckéken. :) Minden elég világosnak tűnik. Csak egy kérdés van: mi az alapvető különbség az absztrakt osztályok és az interfészek között? Miért adták hozzá mindkettőt a Java-hoz, ahelyett, hogy csak egy nyelvre korlátozták volna a nyelvet? Végül is ez teljesen megfelelő lett volna. Erről a következő leckében fogunk beszélni ! Addig :)
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION