CodeGym /Java blog /Véletlen /Java osztályok: saját osztályok írása, konstruktorok
John Squirrels
Szint
San Francisco

Java osztályok: saját osztályok írása, konstruktorok

Megjelent a csoportban
Szia! Ma a Java osztályokról fogunk beszélni. Mondhatnánk, hogy az osztályok képezik a Java programozás sarokkövét. Amikor programozó leszel, szinte az egész munkád a saját osztályok írása lesz, amelyeknek különféle funkciói vannak. Lássuk, mit jelent ez és hogyan működik. :) Mint tudod, a Java egy objektum-orientált programozási nyelv. Minden program olyan objektumokból áll, amelyek valamilyen módon kapcsolódnak egymáshoz. Az osztály lényegében egy objektum sablonja. Meghatározza, hogy az objektum hogyan fog kinézni, és milyen funkciói lesznek. Minden objektum valamilyen osztály tárgya. Tekintsük ezt a nagyon egyszerű példát:

public class Cat {

    String name;
    int age;

}
Tegyük fel, hogy olyan programot írunk, amely valamilyen okból kifolyólag macskákat érint (például van egy állatorvosi rendelőnk, amely hozzáférést biztosít egy online fiókhoz). Létrehoztunk egy Cat osztályt, és két változót deklaráltunk benne: String name és int age . Ezeket a tagváltozókat mezőknek nevezzük. Lényegében ez egy sablon minden macskához, amelyet a jövőben létrehozunk. Minden Cat objektumnak két változója lesz: egy név és egy életkor.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
    }

}
Íme, hogyan működik! Létrehozunk egy macskát, nevet és életkort adunk neki, és mindezt megjelenítjük a konzolon. Szelet torta. :) Az órák gyakrabban írnak le dolgokat és jelenségeket a való világban. Egy macska, egy asztal, egy személy, egy villám, egy könyvoldal, egy kerék – mindezeket a dolgokat létrehozhatja a programjaiban az egyes osztályok segítségével. Egyelőre koncentráljunk azokra a változókra, amelyeket a Cat osztályban deklaráltunk. Ezeket mezőknek vagy példányváltozóknak nevezzük. A nevük tényleg mindent elmond. A Cat osztály minden példánya (vagy objektum) rendelkezik ezekkel a változókkal. Minden általunk létrehozott macskának saját névváltozója és életkora leszváltozó. Ennek van értelme – alapvetően így van ez a valódi macskákkal. :) A példányváltozókon kívül vannak osztályváltozók is (statikus változók). Befejezzük a példánkat:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        Cat fluffy = new Cat();
        fluffy.age = 5;
        fluffy.name = "Fluffy";
        count++;

        System.out.println("We created a cat named " + smudge.name + ". His age is " + smudge.age);
        System.out.println("We created a cat named " + fluffy.name + ". His age is " + fluffy.age);

        System.out.println("Total number of cats = " + count);
    }
}
Konzol kimenet: Létrehoztunk egy Smudge nevű macskát. 3 éves. Létrehoztunk egy Fluffy nevű macskát. Életkora 5 éves A macskák összlétszáma = 2 Most az osztályunknak van egy új változója, a count. Felelős a létrehozott macskák megszámlálásáért. Minden alkalommal, amikor létrehozunk egy macskát a módszerrel növeljük ezt a változót 1-gyel. Ezt a változót a static kulcsszóval deklaráljuk. Ez azt jelenti, hogy az osztályhoz tartozik, nem pedig az osztály egy konkrét objektumához. Aminek természetesen van értelme: minden macska neve az adott macskához tartozik, de szükségünk van egy macskaszámlálóra, amely mindegyikre vonatkozik. Pontosan ezt éri el a static kulcsszó: a count változót egyetlen változóvá teszi az összes macska számára. Megjegyzés: amikor megjelenítjük a változót, nem használjuk a smudge.count vagy fluffy.count paramétereket. Nem tartozik sem a Smudge-hoz, sem a Fluffyhoz; az egész Cat osztályhoz tartozik . Ezért egyszerűen számítani kell. Azt is írhatnád, hogy Cat.count. Ez is helyes lenne. A névváltozó megjelenítésekor nem tennénk a következőket:

public class Cat {

    String name;
    int age;

    static int count = 0;

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";
        count++;

        System.out.println("We created a cat named " + name + ". His age is " + smudge.age);

        System.out.println("Total number of cats = " + count);
    }
}
Ez egy hiba! Minden macskának saját neve van. A fordító itt összezavarodik. "Kiírt egy nevet a konzolnak? Kinek a neve?" :/"

Mód

A változókon kívül minden osztálynak vannak metódusai. Róluk részletesebben egy külön leckében fogunk beszélni, de az általános elvek meglehetősen egyszerűek. A metódusok határozzák meg az osztály funkcionalitását, vagyis azt, hogy az osztályod objektumai mire képesek. Már ismeri az egyik metódust: a main() metódust. De, mint emlékezhet, a metódus statikus, ami azt jelenti, hogy az egész osztályhoz tartozik (a logika ugyanaz, mint a változóké). A szabványos, nem statikus metódusok azonban csak meghatározott, általunk létrehozott objektumokon hívhatók meg. Például, ha macskaosztályt akarunk írni, tudnunk kell, hogy a programunkban szereplő macskáknak milyen funkciókkal kell rendelkezniük. Ennek alapján írjunk néhány módszert macskánk számára:

public class Cat {

    String name;
    int age;

    public void sayMeow() {
        System.out.println("Meow!");
    }

    public void jump() {
        System.out.println("Pounce!");
    }

    public static void main(String[] args) {
        Cat smudge = new Cat();
        smudge.age = 3;
        smudge.name = "Smudge";

        smudge.sayMeow();
        smudge.jump();

    }
}
Nézd meg! Az osztályunk most sokkal közelebb áll ahhoz, hogy macskára hasonlítson! Most már nem csak egy macskánk van, akinek neve ("Smudge") és életkora (3). Ő is tud nyávogni és ugrani! Milyen macska lenne ez a "funkcionalitás" nélkül? :) Fogunk egy adott objektumot (smudge), és meghívjuk a sayMeow() és jump() metódusait. Nézzük a konzolt: Miau! Lecsap! Egy igazi macska! :)

Saját osztályok létrehozása. Absztrakció

A jövőben saját óráit kell írnia. Mire kell figyelned, amikor írod őket? Ha változókról beszélünk, akkor valami az úgynevezett absztrakciót kell használnia. Az absztrakció az objektumorientált programozás négy alapelvének egyike. Ez azt jelenti, hogy kiemeljük egy tárgy legfontosabb és legjelentősebb jellemzőit, és fordítva, a csekély vagy jelentéktelen tulajdonságokat figyelmen kívül hagyjuk. Például hozzunk létre egy irattárat a vállalati alkalmazottak számára. Alkalmazotti objektumok létrehozásához írtunk egy alkalmazottatosztály. Milyen jellemzők fontosak a munkavállalók jellemzői cégünk irattárában? Név, születési dátum, SSN és alkalmazotti azonosító. De nem valószínű, hogy szükségünk lesz az alkalmazott magasságára, szemszínére vagy hajszínére a cég alkalmazotti nyilvántartásához. A cégeknek nincs szükségük erre az információra. Tehát az Employee osztályban a következő változókat deklaráljuk: String name , int age , int socialSecurityNumber és int munkavállalóId. És elhagyjuk a felesleges információkat (például a szem színét). Más szóval, absztrakciót hozunk létre. Ha azonban iratszekrényt készítünk a modellügynökségek számára, a helyzet drámaian megváltozik. A modell magassága, szemszíne és hajszíne fontos jellemzők, de az SSN-je számunkra teljesen irreleváns. Tehát a Model osztályban a következő változókat kell létrehoznunk: String height , String hair , String eyes . Így működik az absztrakció – ez egyszerű! :)

Konstruktorok

Térjünk vissza a macskás példánkhoz.

public class Cat {

    String name;
    int age;

    public static void main(String[] args) {
        Cat smudge = new Cat();

        System.out.println("Here the program does something for 2 hours...");

        smudge.age = 3;
        smudge.name = "Smudge";

    }
}
Tekintse át ezt a kódot, és próbálja kitalálni, mi a probléma a programunkkal. A programunkban egy macska volt név és életkor nélkül 2 órán keresztül! Természetesen ez eredendően rossz. Az állatorvosi klinika adatbázisában nem szerepelhetnek információ nélküli macskák. Jelenleg macskánk a programozó kegyében van. Bízunk benne, hogy nem felejt el nevet és életkort megadni, és minden rendben lesz. Ha elfelejti, az adatbázisban gond lesz: névtelen macskák. Hogyan tudjuk megoldani ezt a problémát? Valahogy meg kell akadályoznunk, hogy macskákat név és kor nélkül hozzanak létre. Itt jönnek a kivitelezők segítségére. Mondjunk egy példát:

public class Cat {

    String name;
    int age;

    // Constructor for the Cat class
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
    }
}
A konstruktor lényegében egy osztály objektumainak sablonja. Ebben az esetben jelezzük, hogy minden cat objektumhoz két argumentumot kell megadni , egy Stringet és egy int . Ha most megpróbálunk létrehozni egy névtelen macskát, az nem fog menni.

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Most, hogy az osztálynak van konstruktora, a Java fordító tudja, hogyan kell kinézniük az objektumoknak, és nem teszi lehetővé az objektumok létrehozását az argumentumok megadása nélkül. Most vizsgáljuk meg a konstruktor belsejében látható ez kulcsszót. Ez is egyszerű. Ez a kulcsszó egy adott objektum jelzésére szolgál. A kód a konstruktorban

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}
szinte szó szerint értelmezhető: "Ennek a macskának a neve (amelyet létrehozunk) = a konstruktor névparaméteréhez átadott argumentum. Ennek a macskának a kora (amelyet létrehozunk) = a konstruktor által megadott argumentum életkor paraméter." A konstruktor lefutása után ellenőrizheti, hogy az összes szükséges érték hozzá van-e rendelve a macskánkhoz:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 5);
        System.out.println(smudge.name);
        System.out.println(smudge.age);
    }
}
Konzol kimenet: Smudge 5 A konstruktor meghívásakor:

Cat smudge = new Cat("Smudge", 5);
Valójában ez történt belülről:

this.name = "Smudge";
this.age = 5;
A konstruktornak átadott argumentumok értékei pedig a smudge objektumhoz lettek rendelve (ez ebben az esetben erre vonatkozik). Valójában, még ha nem is deklarálsz egyetlen konstruktőrt sem egy osztályban, akkor is hívni fog egy konstruktort! De hogyan lehetséges ez? О_О Mert minden Java osztálynak van úgynevezett alapértelmezett konstruktora. Nem igényel argumentumot, de minden alkalommal meghívódik, amikor létrehoz egy objektumot bármely osztályból.

public class Cat {

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Első pillantásra ez nem biztos, hogy nyilvánvaló. Létrehoztunk egy tárgyat, és mi van? Hol csinál itt valamit a kivitelező? Ennek megtekintéséhez írjunk egy üres konstruktort a Cat osztályhoz. A belsejében kiadunk néhány kifejezést a konzolra. Ha a kifejezés megjelenik, akkor a konstruktor meghívásra került.

public class Cat {

    public Cat() {
        System.out.println("A cat has been created!");
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // The default constructor is invoked here
    }
}
Konzol kimenet: Egy macska létrejött! Itt a megerősítés. Az alapértelmezett konstruktor mindig láthatatlanul jelen van az osztályokban. De még egy dolgot tudnod kell róla. Az alapértelmezett konstruktor kikerül az osztályból, miután létrehoz egy konstruktort argumentumokkal. Valójában a fentiekben már láttuk ennek bizonyítékát. Ebben a kódban volt:

public class Cat {

    String name;
    int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat(); // Error!
    }
}
Név és életkor nélkül nem tudtunk Cat-et létrehozni, mert egy Cat konstruktort deklaráltunk string és int paraméterekkel. Emiatt az alapértelmezett konstruktor azonnal eltűnt az osztályból. Ezért ügyeljen arra, hogy ha több konstruktorra van szüksége az osztályban, beleértve egy argumentum nélküli konstruktort is, akkor azt külön kell deklarálnia. Rendelőnk jót akar tenni és segíteni olyan hajléktalan cicáknak, akiknek a neve és életkora ismeretlen. Akkor a kódunknak így kell kinéznie:

public class Cat {

    String name;
    int age;

    // For cats with owners
    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // For street cats
    public Cat() {
    }

    public static void main(String[] args) {
        
        Cat smudge = new Cat("Smudge", 5);
        Cat streetCat = new Cat();
    }
}
Most, hogy megadtunk egy explicit alapértelmezett konstruktort, mindkét típusú macskát létrehozhatjuk. A konstruktorban közvetlenül hozzárendelhet értékeket. Nem kell mindig a vitákból kivonni őket. Például az adatbázisban lévő összes utcai macskát felcímkézhetjük az "Utcai macska száma <szám>" sablonként. :

public class Cat {

    String name;
    int age;

    static int count = 0;

    public Cat() {
        count++;
        this.name = "Street cat No. " + count;
    }

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat streetCat1 = new Cat();
        Cat streetCat2 = new Cat();
        System.out.println(streetCat1.name);
        System.out.println(streetCat2.name);
    }
}
Van egy számláló változónk, ami számolja az utcai macskáinkat. Minden alkalommal, amikor az alapértelmezett konstruktor végrehajtódik, a számot 1-gyel növeljük, és ezt a számot csatoljuk a macska nevéhez. Az argumentumok sorrendje nagyon fontos a konstruktorok számára. Cseréljük fel a konstruktorunknak átadott név és életkor argumentumokat.

public class Cat {

    String name;
    int age;

    public Cat(int age, String name) {
        this.name = name;
        this.age = age;
    }

    public static void main(String[] args) {

        Cat smudge = new Cat("Smudge", 10); // Error!
    }
}
Hibát kaptunk! A konstruktor egyértelműen előírja, hogy a Cat objektum létrehozásakor egy számot és egy karakterláncot kell átadni, ebben a sorrendben. Tehát a kódunk nem működik. Ügyeljen arra, hogy ne feledje és tartsa be ezt a szabályt, amikor bejelenti saját osztályait:

public Cat(String name, int age) {
    this.name = name;
    this.age = age;
}

public Cat(int age, String name) {
    this.age = age;
    this.name = name;
}
Ez két teljesen különböző konstruktőr! Most végezzen el néhány feladatot, hogy megszilárdítsa az anyag megértését. :)
  1. Régiségek Múzeuma.

    Az Ön feladata egy Műtárgy osztály megtervezése .
    A múzeumban háromféle műtárgyat őriznek.
    Az első típusról a múzeum által adott sorszámon kívül semmit sem tudunk (például: 212121).
    A második típusnál ismerjük a sorozatszámot és az azt létrehozó kultúrát (például: 212121, "Aztékok").
    A harmadik típusnál ismerjük a sorszámot, az azt létrehozó kultúrát és a keletkezés évszázadát (például: 212121, "Aztékok", 12).

    Hozzon létre egy Műtárgy osztályt, amely leírja a múzeumban őrzött régiségeket, és írja be az osztályhoz szükséges konstruktorkészletet. Ezután a main() metódusban hozzon létre egy-egy műterméket minden fajtából.

    
    public class Artifact {
        
        // Write your code here
    
        public static void main(String[] args) {
            // Write your code here
        }
    }
    
  2. Randi honlap

    Hozzunk létre egy felhasználói adatbázist egy társkereső webhelyhez.
    De itt van a probléma: elfelejtette az érvek szükséges sorrendjét, és nem áll rendelkezésre műszaki dokumentáció.
    Tervezzen meg egy User osztályt, amelynek a következő mezői lesznek: név ( String ), életkor ( short ) és magasság ( int ).
    Hozzon létre megfelelő számú konstruktort, hogy a név, az életkor és a magasság tetszőleges sorrendben megadható legyen.

    
    public class User {
    
        String name;
        short age;
        int height;
    
        // Write your code here
    
        public static void main(String[] args) {
            
        }
    }
    
A tanultak megerősítése érdekében javasoljuk, hogy nézzen meg egy videóleckét a Java-tanfolyamról
Hozzászólások
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION