CodeGym /Java blog /Véletlen /Az OOP alapelvei
John Squirrels
Szint
San Francisco

Az OOP alapelvei

Megjelent a csoportban
A Java egy objektumorientált nyelv. Ez azt jelenti, hogy Java programokat objektumorientált paradigmával kell írni. És ez a paradigma magában foglalja az objektumok és osztályok használatát a programjaiban. Próbáljuk meg példákkal megérteni, mik az osztályok és objektumok, és hogyan alkalmazzuk az alapvető OOP-elveket (absztrakció, öröklődés, polimorfizmus és tokozás) a gyakorlatban.

Mi az a tárgy?

A világ, amelyben élünk, tárgyakból áll. Körülnézve láthatjuk, hogy házak, fák, autók, bútorok, edények és számítógépek vesznek körül bennünket. Mindezek a dolgok tárgyak, és mindegyiknek megvan a maga sajátos jellemzői, viselkedése és célja. Megszoktuk a tárgyakat, és mindig nagyon konkrét célokra használjuk őket. Például, ha munkába kell mennünk, autót használunk. Ha enni akarunk, használjunk edényeket. Ha pedig pihenni akarunk, keressünk egy kényelmes kanapét. Az emberek hozzászoktak ahhoz, hogy tárgyakban gondolkodjanak, hogy megoldják a mindennapi problémákat. Ez az egyik oka annak, hogy objektumokat használnak a programozásban. Ezt a megközelítést objektum-orientált programozásnak nevezik. Mondjunk egy példát. Képzelje el, hogy új telefont fejlesztett, és tömeggyártásba szeretne kezdeni. A telefon fejlesztőjeként Ön tudja, mire való, hogyan működik, és milyen részei vannak (test, mikrofon, hangszóró, vezetékek, gombok stb.). Ráadásul csak Ön tudja, hogyan kell ezeket a részeket összekapcsolni. De nem tervezi, hogy személyesen készítse el a telefonokat – ehhez egy egész csapat dolgozik. Annak érdekében, hogy ne kelljen ismételten elmagyarázni a telefon alkatrészeinek csatlakoztatását, és hogy az összes telefon azonos módon készüljön, a gyártás megkezdése előtt el kell készítenie egy rajzot, amely leírja a telefon felépítését. Az OOP-ban az ilyen leírást, rajzot, diagramot vagy sablont osztálynak nevezzük. Ez képezi az objektumok létrehozásának alapját a program futása közben. Az osztály bizonyos típusú objektumok leírása – például egy közös sablon, amely mezőkből, metódusokból és egy konstruktorból áll. Az objektum egy osztály példánya.

Absztrakció

Most gondoljuk át, hogyan léphetünk át egy objektumról a való világban egy objektumra egy programban. Példaként a telefont használjuk. Ennek a kommunikációs eszköznek több mint 100 éves története van. A modern telefon sokkal összetettebb készülék, mint 19. századi elődje. A telefon használata során nem gondolunk a szervezetére és a benne lezajló folyamatokra. Egyszerűen csak a telefon fejlesztői által biztosított funkciókat használjuk: gombokat vagy érintőképernyőt a telefonszám megadásához és a hívások kezdeményezéséhez. Az egyik első telefon interfész egy hajtókar volt, amelyet hívás kezdeményezéséhez el kellett forgatni. Ez persze nem volt túl kényelmes. De funkcióját kifogástalanul betöltötte. Ha összehasonlítja a legmodernebb és a legelső telefonokat, azonnal azonosíthatja a 19. század végi készülék és a modern okostelefon legfontosabb funkcióit. Ezek a képességek hívások kezdeményezésére és hívások fogadására. Valójában ettől lesz a telefon telefon, és nem valami más. Most az OOP elvét alkalmaztuk: azonosítsa az objektum legfontosabb jellemzőit és információit. Ezt az elvet absztrakciónak nevezik. Az OOP-ban az absztrakció úgy is definiálható, mint egy valós feladat elemeinek objektumként való ábrázolásának módszere egy programban. Az absztrakció mindig az objektum bizonyos tulajdonságainak általánosításával jár, ezért a lényeg az, hogy az adott feladat kontextusában elkülönítsük az értelmes információt a jelentéktelentől. Ezenkívül az absztrakciónak több szintje is lehet. hagyjuk s próbáljuk meg alkalmazni az absztrakció elvét a telefonunkra. Kezdésként azonosítjuk a leggyakoribb telefontípusokat – a legelső telefonoktól a mai telefonokig. Például ábrázolhatjuk őket az 1. ábra diagramja formájában. Az OOP alapelvei - 2Az absztrakció segítségével immár azonosíthatjuk az általános információkat ebben az objektumhierarchiában: az általános absztrakt objektumot (telefon), a telefon közös jellemzőit (pl. létrehozásának éve), és a közös interfészt (minden telefon képes fogadni és kezdeményezni hívásokat). Így néz ki Java nyelven:

public abstract class AbstractPhone {
    private int year;

    public AbstractPhone(int year) {
        this.year = year;
    }
    public abstract void call(int outgoingNumber);
    public abstract void ring(int incomingNumber);
}
Egy programban új típusú telefonokat hozhatunk létre ennek az absztrakt osztálynak a felhasználásával és az OOP egyéb alapelvei alkalmazásával, amelyeket alább megvizsgálunk.

Egységbezárás

Az absztrakcióval azonosítjuk, mi a közös minden objektumra. De minden telefontípus egyedi, valamiben különbözik a többitől. Egy programban hogyan húzzuk meg a határokat és azonosítsuk ezt az egyéniséget? Hogyan tegyük úgy, hogy véletlenül vagy szándékosan senki ne törhesse össze a telefonunkat, vagy ne próbálja meg egyik modellt a másikká átalakítani? A való világban a válasz kézenfekvő: minden alkatrészt egy telefontokba kell tenni. Hiszen ha nem teszed – ahelyett, hogy a telefon összes belső alkatrészét és a csatlakozó vezetékeket kívül hagynád –, néhány kíváncsi kísérletező mindenképpen "javítani" szeretné a telefonunkat. Az ilyen trükközés elkerülése érdekében az objektumok tervezése és működése során a tokozás elvét alkalmazzák. Ez az elv kimondja, hogy egy objektum attribútumai és viselkedése egyetlen osztályban, az objektumban egyesül. s belső megvalósítása el van rejtve a felhasználó elől, és nyilvános felület biztosított az objektummal való munkavégzéshez. A programozó feladata annak meghatározása, hogy egy objektum attribútumai és metódusai közül mely attribútumok és metódusok legyenek nyilvánosan elérhetőek, és melyek azok a belső megvalósítási részletek, amelyekhez nem szabad hozzáférni.

Tokozás és hozzáférés-szabályozás

Tegyük fel, hogy egy telefonra vonatkozó információ (gyártási éve vagy a gyártó logója) a hátára van gravírozva, amikor azt gyártják. Az információ (állapota) az adott modellre jellemző. Elmondhatjuk, hogy a gyártó gondoskodott arról, hogy ez az információ változhatatlan – nem valószínű, hogy bárkinek is eszébe jutna eltávolítani a gravírozást. A Java világban egy osztály írja le a jövőbeli objektumok állapotát mezők segítségével, viselkedésüket pedig metódusokkal. Az objektumok állapotához és viselkedéséhez való hozzáférést a mezőkre és metódusokra alkalmazott módosítók szabályozzák: privát, védett, nyilvános és alapértelmezett. Például úgy döntöttünk, hogy a gyártási év, a gyártó neve és az egyik metódus az osztály belső megvalósítási adatai, és a program más objektumai nem módosíthatják azokat. A kódban,

public class SomePhone {

    private int year;
    private String company;
    public SomePhone(int year, String company) {
        this.year = year;
        this.company = company;
    }
private void openConnection(){
    // findSwitch
    // openNewConnection...
}
public void call() {
    openConnection();
    System.out.println("Calling");
}

public void ring() {
    System.out.println("Ring-ring");
}

 }
A privát módosító csak ezen az osztályon belül teszi lehetővé az osztály mezőinek és metódusainak elérését. Ez azt jelenti, hogy a privát mezőkhez kívülről nem lehet hozzáférni, mert a privát metódusok nem hívhatók meg. Az openConnection metódushoz való hozzáférés korlátozása lehetőséget ad arra is, hogy szabadon változtassuk a metódus belső megvalósítását, mivel a metódus garantáltan nem fogja használni más objektumok munkáját, és nem szakítja meg más objektumok munkáját. Az objektumunkkal való munkavégzés érdekében a nyilvános módosító használatával elérhetővé kell hagyni a hívási és csengetési metódust. A nyilvános módszerek biztosítása az objektumokkal való munkavégzéshez szintén a beágyazás része, mivel ha a hozzáférést teljesen megtagadnák, az használhatatlanná válna.

Öröklés

Vessünk még egy pillantást a telefonok diagramjára. Látható, hogy ez egy hierarchia, amelyben egy modell rendelkezik az ága mentén magasabban elhelyezkedő modellek összes jellemzőjével, és hozzáad néhányat a sajátjából. Például egy okostelefon mobilhálózatot használ a kommunikációhoz (a mobiltelefon tulajdonságaival rendelkezik), vezeték nélküli és hordozható (a vezeték nélküli telefon tulajdonságaival rendelkezik), és képes hívásokat fogadni és kezdeményezni (a telefon tulajdonságaival rendelkezik). Itt van az objektumtulajdonságok öröklődése. A programozásban az öröklés azt jelenti, hogy meglévő osztályokat használunk újak meghatározására. Nézzünk egy példát az öröklődés használatára okostelefon-osztály létrehozásához. Minden vezeték nélküli telefon újratölthető akkumulátorral működik, amelyeknek meghatározott élettartama van. Ennek megfelelően ezt a tulajdonságot adjuk hozzá a vezeték nélküli telefonok osztályához:

public abstract class CordlessPhone extends AbstractPhone {

    private int hour;

    public CordlessPhone (int year, int hour) {
        super(year);
        this.hour = hour;
    }
    }
A mobiltelefonok öröklik a vezeték nélküli telefon tulajdonságait, és ebben az osztályban valósítjuk meg a hívás és csengetés metódust:

public class CellPhone extends CordlessPhone {
    public CellPhone(int year, int hour) {
        super(year, hour);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming call from " + incomingNumber);
    }
}
És végül megvan az okostelefon osztály, amely a klasszikus mobiltelefonokkal ellentétben teljes értékű operációs rendszerrel rendelkezik. Kibővítheti okostelefonja funkcióit új programok hozzáadásával, amelyek futhatnak az operációs rendszerén. A kódban az osztály a következőképpen írható le:

public class Smartphone extends CellPhone {
    
    private String operationSystem;

    public Smartphone(int year, int hour, String operationSystem) {
        super(year, hour);
        this.operationSystem = operationSystem;
    }
public void install(String program) {
    System.out.println("Installing " + program + " for " + operationSystem);
}

}
Amint látja, elég sok új kódot hoztunk létre az Smartphone osztály leírására, de kaptunk egy új osztályt új funkciókkal. Az OOP ezen elve lehetővé teszi a szükséges Java kód mennyiségének jelentős csökkentését, ezzel megkönnyítve a programozó életét.

Polimorfizmus

A különböző típusú telefonok megjelenésében és kialakításában mutatkozó különbségek ellenére megállapíthatunk néhány közös viselkedést: mindegyik képes hívásokat fogadni és kezdeményezni, és mindegyiknek meglehetősen világos és egyszerű kezelőszervei vannak. A programozást illetően az absztrakció elve (amelyet már ismerünk) lehetővé teszi, hogy azt mondjuk, hogy a telefonobjektumok közös felülettel rendelkeznek. Emiatt az emberek könnyedén használhatják az azonos kezelőszervekkel (mechanikus gombokkal vagy érintőképernyővel) rendelkező telefonok különböző modelljeit anélkül, hogy belemélyednének a készülék műszaki részleteibe. Így Ön folyamatosan mobiltelefont használ, és könnyedén kezdeményezhet hívást barátja vezetékes telefonjáról. Polimorfizmusnak nevezzük az OOP azon elvét, amely szerint a program közös interfésszel rendelkező objektumokat használhat anélkül, hogy az objektum belső szerkezetére vonatkozóan bármi információ lenne. hagyjuk s képzeljük el, hogy szükségünk van a programunkra egy olyan felhasználó leírására, aki bármilyen telefont használhat egy másik felhasználó felhívására. Így tehetjük meg:

public class User {
    private String name;

    public User(String name) {
        this.name = name;
            }

    public void callAnotherUser(int number, AbstractPhone phone){
// And here's polymorphism: using the AbstractPhone type in the code!
        phone.call(number);
    }
}
 }
Most többféle telefont ismertetünk. Az egyik első telefon:

public class ThomasEdisonPhone extends AbstractPhone {

public ThomasEdisonPhone(int year) {
    super(year);
}
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Crank the handle");
        System.out.println("What number would you like to connect to?");
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
Egy átlagos vezetékes telefon:

public class Phone extends AbstractPhone {

    public Phone(int year) {
        super(year);
    }

    @Override
    public void call(int outgoingNumber) {
        System.out.println("Calling " + outgoingNumber);
    }

    @Override
    public void ring(int incomingNumber) {
        System.out.println("The phone is ringing");
    }
}
És végül egy klassz videotelefon:

public class VideoPhone extends AbstractPhone {

    public VideoPhone(int year) {
        super(year);
    }
    @Override
    public void call(int outgoingNumber) {
        System.out.println("Connecting video call to " + outgoingNumber);
    }
    @Override
    public void ring(int incomingNumber) {
        System.out.println("Incoming video call from " + incomingNumber);
    }
  }
Objektumokat hozunk létre a main() metódusban, és teszteljük a callAnotherUser() metódust:

AbstractPhone firstPhone = new ThomasEdisonPhone(1879);
AbstractPhone phone = new Phone(1984);
AbstractPhone videoPhone=new VideoPhone(2018);
User user = new User("Jason");
user.callAnotherUser(224466, firstPhone);
// Crank the handle
// What number would you like to connect to?
user.callAnotherUser(224466, phone);
// Calling 224466
user.callAnotherUser(224466, videoPhone);
// Connecting video call to 224466
Ugyanazon metódus meghívása a felhasználói objektumon eltérő eredményeket ad. A hívási metódus egy adott megvalósítása dinamikusan kerül kiválasztásra a callAnotherUser() metóduson belül, a program futása során átadott objektum adott típusa alapján. Ez a polimorfizmus fő előnye – az a képesség, hogy futás közben kiválasztható a megvalósítás. A telefonosztályok fenti példáiban metódus-felülbírálást alkalmaztunk – egy olyan trükköt, ahol az alaposztályban meghatározott metódus megvalósítását a metódus aláírásának megváltoztatása nélkül változtatjuk meg. Ez lényegében lecseréli a metódust: az alosztályban definiált új metódus hívódik meg a program végrehajtásakor. Általában, amikor felülírunk egy metódust, az @Overrideannotáció használatos. Azt mondja a fordítónak, hogy ellenőrizze a felülírt és felülbíráló metódusok aláírásait. Végül, annak biztosításához, hogy Java-programjai összhangban legyenek az OOP elveivel, kövesse az alábbi tippeket:
  • azonosítsa az objektum főbb jellemzőit;
  • azonosítsa a közös tulajdonságokat és viselkedést, és használja az öröklést az osztályok létrehozásakor;
  • az objektumok leírásához használjon absztrakt típusokat;
  • próbálja meg mindig elrejteni az osztály belső megvalósításához kapcsolódó metódusokat és mezőket.
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION