Kapcsolatok

Java konstruktorok. Miért van szükség konstruktőrökre? Az alapértelmezett konstruktor fogalma

1. Az alapértelmezett konstruktor fogalma

Az alapértelmezett konstruktor olyan konstruktor, amely nem vesz fel paramétereket. Az alapértelmezett konstruktor kifejezetten deklarálható egy osztályban, vagy automatikusan generálható.

A legáltalánosabb esetben a ClassName osztálynál az alapértelmezett konstruktor így néz ki:

osztály Osztály név(... // konstruktőri nyilatkozat Osztály név() ( // konstruktor törzs // ... } ... }
2. Milyen esetekben generálódik automatikusan az alapértelmezett konstruktor az osztályban és melyikben nem? Példa

Ha nincs konstruktor deklarálva az osztályban, akkor egy alapértelmezett konstruktor jön létre. Vagyis egy alapértelmezett konstruktor csak akkor jön létre automatikusan egy osztályban, ha az osztály nem tartalmaz más konstruktorok implementációit. Ha egy osztály legalább egy konstruktor implementációját tartalmazza paraméterekkel, akkor az alapértelmezett konstruktor deklarálásához azt kifejezetten deklarálni kell az osztályban.

Például. A következő osztálydeklarációban automatikusan létrejön egy alapértelmezett konstruktor

osztály CMyClass( int d; int GetD() ( Visszatérés d; ) üres SetD( int nd) ( d = nd; ) )

A fenti kód azt jelenti, hogy deklarálhat egy osztályobjektumot az alapértelmezett konstruktor segítségével:

// működik, mert az osztály már nem implementál egyetlen konstruktort sem CMyClass mc = új CMyClass();

Ha legalább egy másik konstruktort hozzáadunk a CMyClass osztály törzséhez (például egy konstruktor egy paraméterrel), akkor az alapértelmezett konstruktor nem jön létre automatikusan

osztály CMyClass( int d; // Az alapértelmezett konstruktor már nem jön létre automatikusan CMyClass( int nd) ( d = nd; ) int GetD() ( Visszatérés d; ) üres Készlet( int nd) ( d = nd; ) )

A fenti megvalósítás után az objektum alapértelmezett konstruktorral történő deklarálása sikertelen lesz. Azonban lehetséges egy objektum deklarálása egy paraméterrel rendelkező konstruktor segítségével

// fordítási hiba, mert egy másik konstruktor már deklarálva van az osztályban // CMyClass mc = new CMyClass(); CMyClass mc2= új CMyClass(7); // és ez a kód működik

A fenti sor fordítási hibát eredményez:

A CMyClass() konstruktor nem definiált

Ahhoz, hogy legyen egy alapértelmezett konstruktor-megvalósítás, és egy osztályobjektum deklarálhasson egy alapértelmezett konstruktort, azt kifejezetten be kell állítani. Ez lehet például a következő

osztály CMyClass( int d; // kifejezett alapértelmezett konstruktor deklaráció CMyClass() ( d = 0; ) // konstruktor deklaráció 1 paraméterrel, CMyClass( int nd) ( d = nd; ) int GetD() ( Visszatérés d; ) üres Készlet( int nd) ( d = nd; ) )

Egy ilyen megvalósítás után például két konstruktor segítségével létrehozhatja az osztály példányát

CMyClass mc = új CMyClass(); // az alapértelmezett konstruktor meghívása mc.d = 25; CMyClass mc2= új CMyClass(5); // az 1 paraméterrel rendelkező konstruktor meghívása

3. Konstruktorok hívása más konstruktoroktól. Példa

A Java programozási nyelv lehetővé teszi, hogy osztálykonstruktorokat hívjunk meg ugyanabból az osztályból egy másik konstruktorból. Ehhez a this kulcsszót használjuk, amely az aktuális osztályra utal.

Példa. A példa a CPixel osztály használatát mutatja be, amely pixelt valósít meg a monitor képernyőjén.

// Osztály, amely pixelt implementál a monitor képernyőjén nyilvános osztály CPixel( // belső osztályváltozók magán int x, y; // pixel koordináták magán int szín; // pixel színe // konstruktor paraméterek nélkül (alapértelmezett konstruktor) CPixel() ( x = y = szín = 0; ) // konstruktor 2 paraméterrel, amely csak koordinátákat inicializál CPixel( int _x, int _y) ( x = _x; y = _y; szín = 0; ) // konstruktor 1 paraméterrel, amely csak a színt inicializálja CPixel( int _color) ( szín = _szín; x = y = 0; ) // 3 paraméteres konstruktor, amely meghívja a 2 paraméteres konstruktort CPixel( int _x, int _y, int _color) ( // konstruktor hívása 2 paraméterrel: kötelező első művelet és csak egyszer ez(_x, _y); //this(_color); // a konstruktor ismételt hívása tilos ez.color = _color; // szóval lehetséges ) // hozzáférési módszerek int GetX() ( Visszatérés x; ) int GetY() ( Visszatérés y; ) int GetColor() ( Visszatérés szín; ) )

A CPixel osztály használata egy másik programkódban (módszer)

CPixel cp1= új CPixel(2,8); // konstruktor hívása 2 paraméterrel CPixel cp2= új CPixel(3,5,8); // hívjon egy konstruktort, amely meghív egy másik konstruktort int d; d = cp1.GetX(); // d = 2 d = cp2.GetColor(); // d = 8 d = cp2.GetY(); // d = 5 ...

4. Milyen korlátozások (követelmények) vonatkoznak az osztálykonstruktorból más konstruktorok meghívására?

Más konstruktorok osztálykonstruktorból való helyes meghívásához a következő követelményeket (korlátozásokat) kell betartani:

  • csak egy másik osztálykonstruktor hívható meg. Tilos két vagy több másik konstruktor meghívása ebből az osztályból. Ez abból a logikából következik, hogy az osztálykonstruktort úgy tervezték, hogy egy osztályobjektumot csak egyszer hozzon létre (és nem kétszer vagy többször);
  • egy másik konstruktor meghívása kell, hogy legyen az első művelet a hívó konstruktorban. Ha a hívó konstruktorban egy másik konstruktor hívása valósul meg a második (harmadik stb.) művelettel, akkor a fordító hibát generál.

Módszer Java nyelven kifejezések halmaza, amelyek összessége lehetővé teszi egy bizonyos művelet végrehajtását. Így például a System.out.println() metódus meghívásakor a rendszer parancsok sorozatát hajtja végre, hogy kinyomtasson egy üzenetet a konzolra.

Ebben a lépésben megtudhatja, hogyan hozhat létre saját metódusokat visszatérési értékkel vagy anélkül, metódusokat hívhat meg paraméterekkel vagy anélkül, és hogyan izolálhatja el a metódusokat egy program fejlesztése során.

Hozzon létre egy módszert

Az alábbiakban egy metódus szintaxisát szemléltető példa látható, hogyan lehet módszert létrehozni Java nyelven.

Szintaxis

public static int metódusnév(int a, int b) ( // body )
  • publikus statikus - módosító;
  • int - visszatérési típus;
  • methodName - metódus neve;
  • a, b - formális paraméterek;
  • int a, int b - a paraméterek listája.

A metódus definícióját a metódus fejléce és törzse képviseli. Ugyanezt figyelhetjük meg a következő metódus létrehozási szintaxisban.

Szintaxis

módosító returnType nameOfMethod (paraméterlista) ( // metódus törzse )

A fenti szintaxis a következőket tartalmazza:

  • módosító - meghatározza a metódushoz való hozzáférés típusát és használatának lehetőségét.
  • returnType – a metódus visszaadhat egy értéket.
  • nameOfMethod – Megadja a metódus nevét. A metódus aláírása tartalmazza a metódus nevét és a paraméterek listáját.
  • Paraméterlista - a paraméterek listáját a metódusparaméterek típusa, sorrendje és száma jelöli. Ez az opció tetszőlegesen van beállítva, a metódusban null paraméter is lehet.
  • Metódustörzs – a metódustörzs határozza meg a parancsokkal való munkamódszert.

Példa

/* kódrészlet a két szám közötti minimumot adja vissza */ public static int minFunction(int n1, int n2) ( int min; if (n1 > n2) min = n2; else min = n1; return min; )

Módszer hívás

A metódus használata előtt meg kell hívni. Javaban kétféleképpen lehet metódusokat hívni, pl. a metódus visszatérési értéket ad vagy nem (nincs visszatérési érték).

A metódushívás algoritmusa meglehetősen egyszerű. Amikor egy program meghív egy metódust Java nyelven, a programozott vezérlés átkerül a meghívott metódusra. Ez a meghívott metódus ezután két esetben adja vissza a vezérlést a hívó kliensnek, ha:

  • egy return utasítás végrehajtásra kerül;
  • a metódus végének záró göndör kapcsát elértük.

A void return metódus meghívja a parancsot. Vegyünk egy példát:

System.out.!");

Az értékvisszaadási módszert a következő példával szemléltethetjük:

int eredmény = összeg(6, 9);

Az alábbi példa bemutatja, hogyan lehet Java-ban metódusokat meghatározni és meghívni.

Példa

public class PéldaMinNumber ( public static void main(String args) ( int a = 11; int b = 6; int c = minFunction(a, b); System.out.println("Min érték = " + c); ) / * A minimum két számot adja eredményül */ public static int minFunction(int n1, int n2) ( int min; if (n1 >

Minimális érték = 6

Az üres kulcsszó

Az üres kulcsszó Java-ban lehetővé teszi olyan metódusok létrehozását, amelyek nem adnak vissza értéket. Az alábbi példában egy üres típusú metódust vettünk figyelembe - methodRankPoints. A Java void metódusok nem adnak vissza értéket. A void típusú metódus meghívása parancs segítségével történik, pl. methodRankPoints(255.7);. Ez egy java kifejezés, amely pontosvesszővel végződik, amint az az alábbi példában látható:

Példa

public class PéldaVoid ( public static void main(String args) ( methodRankPoints(255.7); ) public static void methodRankPoints(double point) ( if (pontok >= 202.5) ( System.out.println("Rang A1"); )else if (pont >= 122,4) ( System.out.println("Rang A2"); )else ( System.out.println("Rang A3"); ) ) )

Ennek eredményeként a következő eredményt kapjuk:

Rangsor A1

Paraméterek átadása érték szerint Java nyelven

Amikor a hívási folyamat végrehajtódik, a Java argumentumokat ad át. Az eljárást a módszer specifikációjában a megfelelő paraméterek által meghatározott sorrendben kell végrehajtani. A paraméterek átadhatók értékkel vagy hivatkozással.

Java-ban a paraméterek érték szerinti átadása metódus meghívását jelenti paraméterrel. Emiatt az argumentum értéke átadásra kerül a paraméternek.

Példa

A következő program egy paraméter érték szerinti átadására mutat példát. Az argumentumértékek a metódus meghívása után is változatlanok maradnak.

Nyilvános osztálycserePélda ( public static void main(String args) ( int a = 30; int b = 45; System.out.println("Az átadás előtt az a = " + a + " és b = argumentumok értékei " + b ); // A swapFunction(a, b) átviteli metódus meghívása; System.out.println("\nMost, az argumentumok értékének átadása előtt és után "); System.out.println("változatlan maradt, a = " + a + " és b = " + b); ) public static void swapFunction(int a, int b) ( System. out. println("Csere előtt: a = " + a + " b = " + b) ); // Int paraméterek átadása c = a; a = b; b = c; System.out.println("Csere után: a = " + a + " b = " + b); ) )

A következő eredményt kapjuk:

Átadás előtt az a = 30 és b = 45 argumentumok értéke Csere előtt: a = 30 b = 45 Cseréje után: a = 45 b = 30 Most az átadás előtt és után az argumentumok értékei megmaradtak változatlan, a = 30 és b = 45

Módszer Túlterhelés

Módszer túlterhelés Java-ban- az az eset, amikor két vagy több metódus van az osztályban azonos nevű, de eltérő paraméterekkel. Ez a folyamat különbözik a felülbíráló módszerektől. A metódusok felülbírálásakor a metódust ugyanaz a név, típus, paraméterek száma stb. jellemzi.

Tekintsük a fent bemutatott példát egy egész típusú minimális számok meghatározásakor. Tegyük fel, hogy meg akarjuk határozni egy dupla típus minimális számát. Ebben az esetben a túlterhelés fogalmát vezetjük be, hogy két vagy több módszert hozzunk létre azonos névvel, de eltérő paraméterekkel.

A fenti példa illusztrálja a fentieket.

Példa

public class PéldaTúlterhelés ( public static void main(String args) ( int a = 7; int b = 3; double c = 5.1; double d = 7.2; int result1 = minFunction(a, b); // ugyanaz a függvény más paraméterekkel double result2 = minFunction(c, d); System.out.println("Minimális érték = " + eredmény1); System.out.println("Minimális érték = " + eredmény2; ) // egész számhoz nyilvános statikus int minFunction ( int n1, int n2) ( int min; if (n1 > n2) min = n2; else min = n1; return min; ) // for double public static double minFunction(double n1, double n2) ( double min; if ( n1 > n2) min = n2; különben min = n1; visszatérési min; ) )

Ennek eredményeként a következő eredményt kapjuk:

Minimális érték = 3 Minimális érték = 5,1

A túlterhelési módszerek olvashatóvá teszik a programot. Tehát két módszer létezik, amelyeknek ugyanaz a neve, de eltérő paraméterekkel. Ennek eredményeként a minimális int számot és a dupla típusszámot kaptuk.

Parancssori argumentumok használata

A program során előfordulhat, hogy bizonyos információkat át kell adnia. Ezt Javaban úgy lehet megtenni, hogy parancssori argumentumokat adunk át a main()-nak.

A Java nyelvben a parancssori argumentum azt az információt jelenti, amely közvetlenül követi a program nevét a parancssorban annak végrehajtása során. A parancssori argumentumokhoz való hozzáférés egy java programban nem nehéz. A main()-nak átadott string tömbben karakterláncként tárolódnak.

Példa

Az alábbi program megjeleníti az összes meghívott parancssori argumentumot.

Nyilvános osztály CommandLine ( public static void main(String args) ( for(int i = 0; i

Próbálja meg futtatni ezt a programot az alábbiak szerint:

A $java CommandLine a 300-200 parancssor

Ennek eredményeként a következő eredményt kapjuk:

args: ez args: parancssor args: string args: 300 args: -200

Konstruktor Java nyelven

Java nyelven konstruktőr létrehozásakor inicializálja az objektumot. A neve hasonló az osztály nevéhez, szintaxisa pedig egy metóduséhoz. Ez utóbbival ellentétben azonban a konstruktornak nincs visszatérési értéke.

Jellemzően a Java konstruktorja használható egy osztály által meghatározott példányváltozók kezdeti értékének beállítására, vagy bármilyen más indítási eljárás végrehajtására, amely egy teljesen kialakított objektum létrehozásához szükséges.

A konstruktorok minden osztályban jelen vannak, függetlenül attól, hogy hogyan vannak megadva, mert a Java automatikusan biztosít egy alapértelmezett konstruktort, amely az összes osztálytag változóját nullára inicializálja. A saját konstruktor definiálása után azonban az alapértelmezett konstruktor többé nem lesz használva.

Példa

Az alábbi példa egy paraméterek nélküli osztálykonstruktor használatát mutatja be.

// Egyszerű konstruktor. class MyClass ( int x; // Következik a MyClass() konstruktor ( x = 10; ) )

Az objektumok inicializálásához konstruktorhívást kell végrehajtania a következő példában látható módon.

Nyilvános osztály ConsDemo ( nyilvános statikus void main(String args) ( MyClass t1 = new MyClass(); MyClass t2 = new MyClass(); System.out.println(t1.x + " " + t2.x); ) )

Megkapjuk az eredményt:

Paraméterezett konstruktor

Leggyakrabban olyan konstruktorra van szükség, amely egy vagy több paramétert vesz fel. Paraméterek hozzáadása egy konstruktorhoz ugyanaz, mint egy metódushoz, csak a konstruktor neve után zárójelbe kell tenni őket.

Példa

// Egyszerű konstruktor. class MyClass ( int x; // A konstruktor alatt MyClass(int i) ( x = i; ) )

Az objektumok inicializálásához meg kell hívnia a konstruktort, mint a következő példában.

Nyilvános osztály ConsDemo ( nyilvános statikus void main(String args) ( MyClass t1 = new MyClass(10); MyClass t2 = new MyClass(20); System.out.println(t1.x + " " + t2.x); ) )

A következő eredményt kapjuk:

kulcsszó erre

kulcsszó erre- az aktuális osztályra való hivatkozásra szolgál egy példánymetódus vagy konstruktor esetén. Ezt a Java-ban használva hivatkozhat osztálypéldányokra, például konstruktorokra, változókra és metódusokra.

Jegyzet: ezt a kulcsszót csak példánymetódusokban vagy konstruktorokban használják.

Általában a Java kulcsszót a következőkre használják:

  • megkülönböztetés a példányváltozók és a helyi változók között, ha ugyanaz a név, egy konstruktor vagy metódus részeként.
osztály Diák ( int kor; tanuló (int kor) ( this.age = életkor; ) )
  • egy osztályon belül egy másik típusú konstruktor (paraméterezett konstruktor vagy alapértelmezett konstruktor) meghívása. Ezt a folyamatot explicit konstruktor meghívásnak is nevezik.
osztály Diák ( int kor Diák() ( this(20); ) Diák(int kor) ( this.age = életkor; ) )

Példa

Public class This_Example ( // Inicializálja a változót num int num = 11; This_Example() ( System. out. println("Ez egy példaprogram a this kulcsszóval"); ) This_Example(int num) ( // Az alapértelmezés meghívása konstruktor this( ); // A num helyi változó hozzárendelése a példányváltozóhoz: num this.num = num; ) public void greet() ( System.out.println("Szia! Üdvözlünk a ProgLangban!"); ) public void print() ( // Helyi változó num int num = 20; // A greet osztály metódusának meghívása this.greet(); // Helyi változó nyomtatása. System. out. println("A num helyi változó értéke: " + num); // Példányváltozó nyomtatása. System .out.println("Példányváltozó értéke num: " + this.num); ) public static void main(String args) ( // This_Example osztály inicializálása obj1 = new This_Example(); // A nyomtatási metódus hívása obj1.print() ; // A num változó új értékének átadása a paraméterezett konstruktoron This_Example obj2 = new This_Example(30); // Ön a nyomtatási metódus ismételt meghívása obj2.print(); ) )

Ennek eredményeként a következő eredményt kapjuk:

Ez egy példaprogram a következő kulcsszóval: Hello! Üdvözöljük a Proglangban! Num helyi változó értéke: 22 Num példányváltozó értéke: 11 Ez egy példaprogram ezzel a kulcsszóval Hello! Üdvözöljük a Proglangban! Num helyi változó értéke: 22 Num példányváltozó értéke: 30

Változó argumentumok (var-args)

A JDK 1.5 és újabb verziói lehetővé teszik változó számú azonos típusú argumentum átadását egy metódusnak. A metódusban egy paramétert a következőképpen deklarálunk:

TypeName... paraméterNév

A metódus deklarálásakor meg kell adni a típust, amelyet egy ellipszis követ (...). Egy metódusban csak egy változó hosszúságú paraméter adható meg, és ennek a paraméternek kell lennie az utolsó paraméternek. Bármilyen szabályos paraméternek meg kell előznie.

Példa

public class VarargsDemo ( public static void main(String args) ( // Metódus hívása args változóval printMax(27, 11, 11, 5, 77.1); printMax(new double(10, 11, 12, 77, 71)); ) public static void printMax(double... számok) ( if (számok.hossz == 0) ( System.out.println("Nincs átadott argumentum"); return; ) double result = számok; for (int i = 1 ; i eredmény) eredmény = számok[i]; System.out.println("Maximális érték " + eredmény); ) )

Ennek eredményeként a következő eredményt kapjuk:

Maximális érték 77,1 Maximális érték 77,0

finalize() metódus

finalize() metódus- olyan módszer, amelyet közvetlenül az objektum szemétgyűjtő általi végleges megsemmisítése előtt hív meg. (véglegesítő). A Java nyelvben a finalize() segítségével biztosítható egy objektum tiszta befejezése.

Például használhatjuk a finalize()-t, hogy megbizonyosodjunk arról, hogy egy adott objektumhoz tartozó megnyitott fájl be van zárva.

Ha véglegesítőt szeretne hozzáadni egy osztályhoz, egyszerűen meg kell határoznia egy finalize() metódust a Java-ban. A Java futási környezet közvetlenül az osztály objektumainak feldolgozása előtt hívja meg ezt a metódust.

A finalize() metódus részeként megadhatja azokat a műveleteket, amelyeket az objektum megsemmisítése előtt végre kell hajtani.

Általában a finalize() metódus így néz ki:

Védett void finalize() ( // a kód véglegesítése itt )

Itt a védett kulcsszó egy olyan specifikátort jelöl, amely megakadályozza, hogy a finalize() az osztályán kívül meghatározott kóddal hozzáférjen.

Ez azt jelzi, hogy nem tudhatja, hogy a finalize() hogyan és mikor kerül végrehajtásra. Például, ha a program a szemétgyűjtés előtt leáll, a finalize() nem kerül végrehajtásra.

A konstruktor egy speciális metódus, amelyet új objektum létrehozásakor hívunk meg. Nem mindig kényelmes az összes osztályváltozó inicializálása egy példány létrehozásakor. Néha könnyebb bizonyos értékeket alapértelmezés szerint létrehozni az objektum létrehozásakor. Valójában a konstruktorra a változók automatikus inicializálásához van szükség.

A konstruktor közvetlenül a létrehozáskor inicializálja az objektumot. A konstruktor neve megegyezik az osztály nevével, beleértve a kis- és nagybetűket is, és a konstruktor szintaxisa hasonló a visszatérési érték nélküli metóduséhoz.

Privát int Cat(); // így néz ki a Cat nevű metódus Cat(); // így néz ki a Cat osztály konstruktora

A metódusokkal ellentétben a konstruktor soha nem ad vissza semmit.

A konstruktor meghatározza az osztály objektumának létrehozásakor végrehajtandó műveleteket, és az osztály fontos része. A programozók általában megpróbálnak kifejezetten megadni egy konstruktort. Ha nincs kifejezett konstruktor, akkor a Java automatikusan létrehoz egyet alapértelmezett használatra. Amikor megvalósítottuk az osztályt doboz, akkor nem jött létre konstruktor.

Adjunk hozzá egy konstruktort az osztályhoz, amely egyszerűen beállítja a doboz kezdeti értékeit.

Class Box ( int szélesség; // doboz szélesség int magasság; // doboz magassága mélység; // doboz mélysége // Box() konstruktor ( szélesség = 10; magasság = 10; mélység = 10; ) // doboz térfogatának kiszámítása int getVolume() ( visszatérési szélesség * magasság * mélység; ) )

Ideiglenesen eltávolítottuk a módszert setDim()és hozzáadott egy konstruktort. Nézzük mi történik:

Box catBox = new Box(); mInfoTextView.setText("Box kötet: " + catBox.getVolume());

A program kiírja a doboz térfogatát, bár nem adtunk meg méretet. A konstruktornak köszönhetően minden létrehozott doboz fix térfogatú lesz.

Természetesen visszaadhat egy metódust setDim()(lásd az osztályokról szóló cikket), és állítsa be a doboz saját méreteit:

Box catBox = new Box(); // egyéni méretek beállítása a dobozhoz catBox setDim(10, 20, 30); mInfoTextView.setText("Box kötet: " + catBox.getVolume());

Mostanra már világosnak kell lennie, hogy mikor a kulcsszó után új zárójelbe írjuk az osztály nevét, akkor tulajdonképpen az osztálykonstruktort hívjuk.

Felmerül a kérdés - de eleinte az osztály létrehozásakor nem készítettünk konstruktort, viszont a kód newBox() dolgozott. A helyzet az, hogy ha a konstruktor nincs kifejezetten definiálva, akkor a Java létrehoz egy konstruktort, amelyet alapértelmezés szerint használ. Ebben az esetben egyszerűen nulla értéket rendel az összes változóhoz. Ha saját maga hozott létre egy konstruktort, akkor az alapértelmezett konstruktor nem kerül felhasználásra.

Mint minden metódusnak, a konstruktornak is lehetnek argumentumai. A konstruktor argumentumok paramétereket adnak át az objektum inicializálásához. Például ha az osztály macska van egy konstruktor, amely argumentumként egy egész számot vesz fel, amely a macska életkorát jelöli, majd az objektumokat macskaígy jön létre:

Cat cat = új Cat(8); // a macska 8 éves

Ha egy macska (int) az egyetlen osztálykonstruktor, a fordító nem engedi objektumok létrehozását macska valamilyen más módon.

De térjünk vissza a macskáknak szánt dobozokhoz. Az általunk készített konstruktor nem különösebben hasznos, mivel ugyanazokat a dobozokat hozza létre. Hozzunk létre egy konstruktort paraméterekkel az osztályban dobozés kommentálja az első paraméter nélküli konstruktort:

// Második konstruktor Box(int‐w, int h, int d) (szélesség = sz; magasság = h; mélység = d; )

Ha az osztály egy konstruktort tartalmaz paraméterekkel, akkor az osztály deklarálásakor meg kell adnia az értékeket:

// Ez a konstruktor már nem érvényes // Box catBox = new Box(); // A konstruktorban meg kell adni a dobozméret értékeit. Box catBox = new Box(100, 200, 100); mInfoTextView.setText("Box kötet: " + catBox.getVolume());

Egyébként ilyen konstruktorral a módszer setDim() már nincs rá szükségünk. A doboz méreteit közvetlenül a konstruktorban tudjuk beállítani. Mivel a doboz nagy valószínűséggel állandó, és nem változtatja meg a méretét, a módszer talán felesleges. De ha megváltoztatjuk a doboz méretét, akkor a módszert meg kell hagyni.

Egy osztálynak több konstruktora is lehet. Törölje az első konstruktor megjegyzéseit, és hozzon létre két dobozt - egy alapértelmezett és egy nagy dobozt.

Box defaultBox = new Box(); mInfoTextView.setText("Standard box kötet: " + defaultBox.getVolume()); Box bigBox = new Box(100, 200, 200); mInfoTextView.append("\nBig Box Volume: " + bigBox.getVolume());

Vagyis azt látjuk, hogy a konstruktorok támogatják a túlterhelést, ahogy a metódusok is.

Például létrehozhatunk egy másik konstruktort kifejezetten egy dobozhoz kocka formájában, ahol minden oldal egyenlő:

// Harmadik konstruktor a kockadobozhoz (int ​​len) (szélesség = magasság = mélység = len; )

Számítsa ki a kocka méretét:

Dobozkocka = new Box(5); intvol = kocka.getVolume(); mInfoTextView.setText("Kocka térfogata: " + térfogat);

Objektum használata paraméterként

A konstruktorokban eddig egyszerű típusokat használtunk paraméterként. De átadhatja magának az osztálynak egy objektumát is. Adjunk hozzá még egy konstruktort:

// Használjon Box Box(Box ob) típusú objektumot ( szélesség = ob.width; magasság = ob.height; mélység = ob.depth; )

A program kódjában a következőképpen használhatja a konstruktort:

Box1 = new Box(100, 200, 100); Box cloneBox = new Box(box1); intvol = cloneBox.getVolume(); mInfoTextView.setText("Box térfogata: " + térfogat);

Dobozosztály (forrás)

csomag hu.alexanderklimov.box; osztály Box ( int szélesség; // a doboz szélessége int magasság; // a doboz magassága a mélységben; // a doboz mélysége // Constructor Box() ( szélesség = 10; magasság = 10; mélység = 10; ) // Második konstruktor Box( int w, int h, int d) ( szélesség = sz; magasság = h; mélység = d; ) // A kocka harmadik konstruktora Box(int ​​len) ( szélesség = magasság = mélység = len; ) // Box Box(Box ob) típusú objektum használata ( szélesség = ob.width; magasság = ob.height; mélység = ob.depth; ) // doboz térfogatának kiszámítása int getVolume() ( visszatérési szélesség * magasság * mélység; ) // set box dimenziók void setDim (int w, int h, int d) (szélesség = sz; magasság = h; mélység = d; ) )

Túlterhelt konstruktorok hívása ezen keresztül ()

Ha túlterhelt konstruktorokkal foglalkozunk, célszerű az egyik konstruktort a másikból a kulcsszón keresztül meghívni ez. A konstruktor végrehajtásakor ez() először a paraméterlistának megfelelő túlterhelt konstruktor kerül végrehajtásra. Ezután az eredeti konstruktoron belüli utasítások, ha vannak, végrehajtásra kerülnek. Kivitelezői hívás ez() az első utasításnak kell lennie a konstruktorban.

Először is hozzunk létre egy olyan osztályt, amely nem használ konstruktort. ez() hogy megértsük a különbséget.

Class Cat ( int kor; int születésnap; // A változók explicit inicializálása Cat(int i, int j) ( életkor = i; születésnap = j; ) // Változók inicializálása azonos értékű Cat(int i) ( életkor = i; születésnap = i; ) // Állítsa be az alapértelmezett értékeket 0-ra Cat() ( életkor = 0; születésnap = 0; ) )

Létrehoztunk egy osztályt három konstruktorral. Írd át az osztályt a konstruktor segítségével! ez().

Class Cat( int életkor; int születésnap i); // Cat(i, i) meghívása; ) // Az alapértelmezett értékek beállítása 0 Cat()-ra ( this(0); // Cat(0); ) )

Most már csak egy konstruktorunk van, amely értékeket rendel a mezőkhöz - Cat(int, int). Mi történik az utasítás végrehajtásakor:

Cat cat = új Cat(8);

Konstruktor hívás macska (8) a konstruktor végrehajtását okozza ez(8, 8), ami egyenértékű a konstruktor meghívásával macska (8, 8).

Mi történik az utasítás végrehajtásakor:

Cat cat2 = new Cat();

Ebben az esetben a konstruktort hívják ez (0), ami a konstruktor végrehajtására készteti macska (0), mivel ez a konstruktor azon verziója, amelyik megfelel a paraméterlistának. Ugyanakkor a kivitelező macska (0) lényegében a konstruktort hívja macska(0; 0).

Túlterhelt konstruktorok használata konstruktoron keresztül ez() lehetővé teszi a kódduplikáció kiküszöbölését, csökkentve az osztálybetöltési időt.

De légy óvatos, mert a konstruktorok hívják a konstruktort ez(), valamivel lassabbak.

magán kivitelező

Néha egy osztály csak néhány statikus mező és statikus metódus tárolására jön létre. Az ilyen osztályokat szokás elnevezni segédprogramok, de ez nem kötelező. Egy ilyen osztályhoz nincs szükség konstruktorra, de ha az osztály szerzője nem hozott létre, akkor a rendszer maga készít egy alapértelmezett konstruktort. Egy ilyen konstruktornak nincs értelme, és hibaforrás is lehet. A probléma elkerülése érdekében kifejezetten létre kell hoznia egy üres konstruktort, és priváttá kell tennie.

Public class Utils ( private Utils() ( dob új AssertionError(); ) ... //a helyes kódod // Hibás kód, csak demonstrációs célból! public static void someMethod()( Utils utils = new Utils(); utils . toString(); ) )

Vonal dobj új AssertionError() nem kötelező, de segít elkapni a hibát, ha magán az osztályon hívja meg a konstruktort. A fordító kihagyja ezt az opciót, de a program hibával kilép.

Utils.someMethod(); // a program hibával bezárul

Ehhez az osztályhoz nem hozhat létre alosztályt.

A tény az, hogy:

1. Ha létrehoz egy osztályt, és definiál egy konstruktort argumentumokkal (AClass osztály, amelynek csak egy konstruktora van, amely int i-t vesz fel), akkor a fordító többé nem hoz létre alapértelmezett konstruktort. Mert ez felbontaná az AClass szerződését, amit érvek nélkül nem lehet inicializálni. Ha alapértelmezett konstruktort is szeretne, akkor most kifejezetten állítsa be.

Ellenkező esetben lehetetlen lenne megakadályozni egy alapértelmezett konstruktor létrehozását, ami rossz lenne.

2. Egy másik osztályból örökölt BClass osztály konstruktorainak létrehozásakor a fordító megköveteli, hogy a konstruktor első sora egy másik (örökölt vagy ebben az osztályban lévő) konstruktor hívása legyen.

Miért? Mert mivel egy osztályból származol, újra szeretné használni a logikáját. A konstruktor az osztály egy példányát valamilyen kezdeti integrál állapotba hozza. Az Ön esetében az AClass-nak egy argumentumra van szüksége az inicializáláshoz, amely nélkül a JVM nem tudja, hogyan inicializálja az osztály egy példányát.

Ha az osztályban nincsenek konstruktorok definiálva, akkor megpróbál létrehozni egy alapértelmezett konstruktort, pl. érvek nélkül:

nyilvános osztály AClass1 ( )

Mivel itt nincsenek kifejezetten definiálva konstruktorok ÉS az osztály nem öröklődik más osztályoktól, a fordító létrehoz egy alapértelmezett konstruktort.

Ez egyenértékű ezzel a meghatározással:

Nyilvános osztály AClass1 ( nyilvános AClass1() ( ) )

Most nézzük a BClass1-et:

nyilvános osztály A BClass1 kiterjeszti az AClass1-et ( )

A konstruktorok itt sincsenek kifejezetten definiálva, és a fordító megpróbál létrehozni egy alapértelmezett konstruktort. Mivel az AClass1 osztálynak van alapértelmezett konstruktora, létrehoz egy alapértelmezett konstruktort, amely meghívja az AClass1 konstruktorát. Ez a kód ezzel egyenértékű:

A BClass1 nyilvános osztály kiterjeszti az AClass1-et ( public BClass1() ( super(); ) )

Az Ön esetében egy osztály alapértelmezett konstruktor NÉLKÜL jön létre:

Nyilvános AClass ( nyilvános AClass(int i) ( ) )

Mivel (legalább egy) konstruktor itt deklarálva van, az alapértelmezett konstruktor többé nem jön létre. Vagyis egy ilyen kód többé nem fordítható le:

AClass a = new AClass(); // nem működik

kell valami hasonló

AClass a = new AClass(1);

Ennek megfelelően minden BClass konstruktornak meg kell hívnia valamilyen AClass vagy BClass konstruktort. Ezzel a leírással a fordító megesküszik:

A nyilvános BClass kiterjeszti az AClass()

Mivel megkísérlik majd meghívni az AClass osztály alapértelmezett konstruktorát, amely nincs definiálva:

A nyilvános BClass kiterjeszti az AClass-t ( public BClass() ( super(); // hiba; nincs ilyen konstruktor az AClass-ban ) )

Lehetőség van azonban egy BClass létrehozására alapértelmezett konstruktorral, ha az AClass konstruktort valamilyen értékre állítja:

Nyilvános osztály A BClass kiterjeszti az AClass-t ( public BClass() ( szuper(1); ) )

Ez összeállítja.

Szia! Ma egy nagyon fontos témát fogunk elemezni, amely tárgyainkat érinti. Itt túlzás nélkül kijelenthetjük, hogy ezt a tudást nap mint nap kamatoztatni fogja a valódi munkában! Majd megbeszéljük kivitelezők.

Lehet, hogy először hallottad ezt a kifejezést, de valójában valószínűleg konstruktorokat használtál, csak te magad nem vetted észre :) Ezt majd meglátjuk később.

Mik azok a konstruktőrök és miért van rájuk szükség?

Nézzünk két példát. public class Car ( String model; int maxSpeed; public static void main (String args) ( Car bugatti = new Car () ; bugatti. model = "Bugatti Veyron" ; bugatti. maxSpeed ​​​​= 407 ; ) ) Megalkottuk autónkat és telepítve neki modell és maximális sebesség. Egy valós projektben azonban az Autó objektumnak nyilvánvalóan nem lesz 2 mezője. És például 16 mező! public class Car ( String modell; //modell int maxSpeed; //teljes sebesség//motor térfogata//tulajdonos vezetékneve//ülések száma a kabinban HúrszalonAnyag; // belső anyag logikai biztosítás; //biztosítva van//termelő ország inttrunkVolume; // törzs térfogata belső gyorsulás 100 km-re; public static void main (String args) ( Autó bugatti = új autó () ; bugatti. szín = "kék" ; bugatti. gyorsulás 100 km-re = ​​3 ; bugatti. motorTérfogat = 6,3 ; bugatti. gyártóOrszág = "Olaszország" ; bugatti. tulajdonos Keresztnév = " Amigo" ; bugatti. kiadási év = 2016 ; bugatti. biztosítás = igaz ; bugatti. ár = 2000 000 ; bugatti. isNew = false ; bugatti. helyek a Szalonban = 2 ; bugatti. maxSpeed ​​​​= 407 ; bugatti. modellyron =" Bugatti. ) ) Létrehoztunk egy új Autó objektumot. Egy probléma: 16 mezőnk van, de csak 12-t inicializáltunk! Próbálja ki most kóddal, hogy megtalálja azokat, amelyeket elfelejtettünk! Nem olyan egyszerű, igaz? Ilyen helyzetben a programozó könnyen hibázhat, és kihagyhatja valamelyik mező inicializálását. Ennek eredményeként a program viselkedése hibás lesz: public class Car ( String model; //model int maxSpeed; //teljes sebesség belső kerekek; //lemez szélessége double engineVolume; //motor térfogata Stringcolor; //szín int yearOfIssue; //kiadás éve String ownerFirstName; //tulajdonos neve Karakterlánc tulajdonosLastName; //tulajdonos vezetékneve hosszú ár; //ár logikai érték isNew; //új vagy nem int helyekInTheSalon; //ülések száma a kabinban HúrszalonAnyag; // belső anyag logikai biztosítás; //biztosítva van HúrgyártóOrszág; //termelő ország inttrunkVolume; // törzs térfogata belső gyorsulás 100 km-re; //100 km/h-ra gyorsulás másodpercekben public static void main (String args) ( Autó bugatti = új autó () ; bugatti. szín = "kék" ; bugatti. gyorsulás 100 km-re = ​​3 ; bugatti. motorTérfogat = 6,3 ; bugatti. gyártóOrszág = "Olaszország" ; bugatti. tulajdonos Keresztnév = " Amigo" ; bugatti. kiadási év = 2016 ; bugatti. biztosítás = igaz ; bugatti. ár = 2000 000 ; bugatti. isNew = false ; bugatti. helyek a Szalonban = 2 ; bugatti. maxSpeed ​​​​= 407 ; bugatti. modellyron =" Bugatti. System. out.println( "Bugatti Veyron modell. Motorméret - "+ bugatti. motorVolume + ", csomagtartó - " + bugatti. trunkVolume+ ", szalon készült"+ bugatti. szalon Anyag + ", lemez szélessége - "+ bugatti. kerekek + ". 2018-ban vásárolta meg Mr. "+ bugatti. tulajdonos Vezetéknév); ) ) Konzol kimenet: Bugatti Veyron modell. Motorméret - 6.3, csomagtartó - 0, belseje null, kerékszélesség - 0. 2018-ban vásárolta Mr. null Az Ön vásárlója, aki 2 millió dollárt fizetett egy autóért, nyilvánvalóan nem fogja szeretni, ha megnevezik. null úr”! De komolyra fordítva a szót, ennek eredményeként a programunk egy helytelenül létrehozott objektummal végződött - egy 0-s korongszélességű autóval (vagyis egyáltalán nincs lemez), egy hiányzó csomagtartóval, egy ismeretlen anyagból készült belsővel és még hozzátartozóval is. valakinek, aki tudja. El lehet képzelni, hogy egy ilyen hiba hogyan „lőhet ki” a program futása közben! Valahogy el kell kerülnünk az ilyen helyzeteket. Szükséges, hogy programunknak legyen megkötése: amikor új gépobjektumot hozunk létre hozzá mindig meg kell adni, például a modellt és a maximális sebességet. Ellenkező esetben ne engedélyezze az objektum létrehozását. Ez a feladat könnyen megoldható konstruktor függvények. Okkal kapták a nevüket. A konstruktor létrehozza az osztály egyfajta "csontvázát", amelynek az osztály minden új objektumának meg kell felelnie. A kényelem kedvéért térjünk vissza a Car osztály két mezős egyszerűbb változatához. Követelményeink alapján a Car osztály konstruktora így fog kinézni: public Car (String modell, int maxSpeed) ( ez . modell = modell; ez . maxSpeed ​​= maxSpeed; ) És az objektum létrehozása most így néz ki: public static void main (String args) ( Car bugatti = new Car ("Bugatti Veyron" , 407 ) ; ) hogyan jön létre a konstruktor. Hasonló a hagyományos metódushoz, de nincs visszatérési típusa. Ebben az esetben a konstruktorban az osztály neve szerepel, szintén nagybetűvel. A mi esetünkben - Autó. Ezenkívül a konstruktor egy új kulcsszót használ az Ön számára ez. "this" angolul - "this one". Ez a szó egy adott tárgyra utal. A konstruktorban található kód: public Car (String modell, int maxSpeed) ( ez . modell = modell; ez . maxSpeed ​​​​= maxSpeed; ) szinte szó szerint lefordítható: " modell ehhez az autóhoz (amit jelenleg készítünk) = modell argumentum, amely a constructor.maxSpeed-ben van megadva ehhez a géphez (amit létrehozunk) = a konstruktorban megadott maxSpeed ​​argumentumhoz." Így is történt: public class Car ( String model; int maxSpeed; public Car (String model, int maxSpeed) ( ez . modell = modell; ez . maxSpeed ​​= maxSpeed; ) public static void main (String args) ( Car bugatti = új autó ("Bugatti Veyron" , 407 ) ; System. out. println (bugatti. modell) ; System. out. println (bugatti. maxSpeed) ; ) ) Konzol kimenet: Bugatti Veyron 407 A konstruktor sikeresen hozzárendelte a kívánt értékeket. Talán észrevetted, hogy a konstruktor nagyon hasonlít egy hagyományos metódushoz! Így van: a konstruktor egy metódus, csak egy kicsit specifikus :) Csakúgy, mint egy metódusnál, itt is paramétereket adtunk át a konstruktorunknak. És akárcsak egy metódus hívása, a konstruktor hívása is sikertelen lesz, ha nincsenek megadva: public class Car ( String model; int maxSpeed; public Car (String model, int maxSpeed) ( ez . modell = modell; ez . maxSpeed ​​= maxSpeed; ) public static void main (String args) ( Car bugatti = new Car () ; //hiba! ) ) Nézze, a kivitelező megtette, amit el akartunk érni. Most már nem hozhat létre autót sebesség vagy modell nélkül! A konstruktorok és a metódusok közötti hasonlóságok ezzel nem érnek véget. Akárcsak a metódusok, a konstruktorok is lehetnek túlterhelés. Képzeld el, hogy 2 macska van otthon. Az egyiket cicának vetted, a másodikat pedig felnőttként hoztad haza az utcáról, és nem tudod, hogy pontosan hány éves. Ez azt jelenti, hogy programunknak képesnek kell lennie kétféle macska létrehozására - az első macskának névvel és életkorral, a második macskának pedig csak névvel. Ehhez túlterheljük a konstruktort: ​​public class Cat ( String name; int age; //az első macskának //a második macskának public Cat (String name) ( this . name = name; ) public static void main (String args) ( Cat barsik = new Cat ("Barsik" , 5 ) ; Cat streetCatNamedBob = new Cat ("Bob" ) ; ) ) to az eredeti konstruktor a „name” és „age” paraméterekkel, hozzáadtunk még egyet, csak a névvel. Ugyanígy túlterheltük a módszereket az előző leckéken. Most már sikeresen elkészíthetjük a macskák mindkét változatát :)

Emlékszel, az előadás elején azt mondtuk, hogy használtál már konstruktorokat, de ezt magadtól nem vetted észre? És van. Az tény, hogy a Java-ban minden osztálynak van ún alapértelmezett konstruktor. Nem igényel argumentumot, de minden egyes osztály objektumának létrehozásakor elindul. public class Cat ( public static void main (String args) ( Cat smears = new Cat () ; ) ) Első pillantásra ez láthatatlan. Nos, létrehoztak egy tárgyat és megalkották, hol van a kivitelező munkája? Ennek megtekintéséhez írjunk közvetlenül egy üres konstruktort a Cat osztályhoz, és azon belül a konzolban jelenítünk meg valamilyen kifejezést. Ha megjelenik, akkor a konstruktor működött. public class Cat ( public Cat () ( System. out. println ("Macskát teremtett!" ) ; ) public static void main (String args) ( Cat smears = new Cat () ; //itt működött az alapértelmezett konstruktor } } Konzol kimenet: Létrehozott egy macskát! Itt a megerősítés! Az alapértelmezett konstruktor mindig láthatatlanul jelen van az osztályokban. De tudnia kell még egy tulajdonságát. Az alapértelmezett konstruktor eltűnik az osztályból, amikor létrehoz egy konstruktort argumentumokkal. Ennek bizonyítékát tulajdonképpen fentebb már láttuk. Itt ebben a kódban: public class Cat ( String name; int age; public Cat (String name, int age) ( this . name = név; this . age = kor; ) public static void main (String args) ( Cat barsik = új Cat () ; //hiba! ) ) Nem tudtunk macskát létrehozni név és életkor nélkül, mert meghatároztunk egy konstruktort a Cat számára: karakterlánc + szám. Az alapértelmezett konstruktor közvetlenül ezután eltűnt osztályból. Ezért ne feledje: ha több konstruktőrre van szüksége az osztályában, az üreset is beleértve, azt külön kell létrehozni. Például egy állatorvosi rendelő számára készítünk programot. Rendelőnk jót akar tenni és segíteni hajléktalan cicákon, akiknek sem a nevét, sem az életkorát nem tudjuk. Ekkor a kódunk így néz ki: public class Cat ( String name; int age; //házi macskáknak public Cat (String name, int age) ( ez . név = név; ez . életkor = életkor; ) //utcai macskáknak public Cat () ( ) public static void main (String args) ( Cat barsik = new Cat ("Barsik" , 5 ) ; Cat streetCat = new Cat () ; ) ) Most, hogy kifejezetten írtunk egy alapértelmezett konstruktort, megtehetjük készíts mindkét típusú macskát :) Egy konstruktornál (mint minden metódusnál) nagyon fontos az argumentumok sorrendje. Cseréljük fel a név és az életkor paramétereit a konstruktorunkban. public class Cat ( String name; int age; public Cat (int age, String name) ( this . name = name; this . age = kor; ) public static void main (String args) ( Cat barsik = new Cat ("Barsik " , 10 ) ; //hiba! ) ) Hiba! A konstruktor világosan leírja: Cat objektum létrehozásakor át kell adni szám és karakterlánc, ebben a sorrendben. Ezért a kódunk nem működik. Ügyeljen arra, hogy ezt tartsa szem előtt, és tartsa szem előtt a saját osztályok létrehozásakor: public Cat (String name, int age) ( this . name = név; ez . életkor = életkor; ) public Cat (int kor, Karakterlánc neve) ( ez . kor = életkor; ez .név = név; ) Ez két teljesen különböző konstruktor! Ha egy mondatban kifejezi a választ a kérdésre Miért van szükség konstruktorra?, mondhatod: hogy az objektumok mindig a megfelelő állapotban legyenek. Konstruktorok használatakor az összes változó helyesen inicializálódik, és nem lesznek 0 sebességű gépek és más „rossz” objektumok a programban. Használatuk elsősorban magának a programozónak nagyon előnyös. Ha saját maga inicializálja a mezőket, nagy a veszélye annak, hogy valamit kihagy, és hibázik. De ez nem fog megtörténni a konstruktorral: ha nem adtad át neki az összes szükséges argumentumot, vagy összekevered a típusukat, a fordító azonnal hibát jelez. Ezt külön érdemes megemlíteni a konstruktorba nem szabad beletenni a program logikáját. Ehhez az Ön rendelkezésére áll mód, amelyben leírhatja az összes szükséges funkciót. Nézzük meg, miért rossz ötlet a konstruktor logika: public class CarFactory ( String name; int age; int carsCount; public CarFactory (String name, int age, int carsCount)) ( this . name = name; this . age = age; this. carsCount = carsCount;system.out.println( "Alapították" "Átlagosan termel"+ (this . carsCount/ this . age) + "autók évente" ) ; ) public static void main (String args) ( CarFactory ford = new CarFactory ("Ford" , 115 , 50000000 ) ; ) ) Van egy osztályunk Autógyár, amely egy autógyárat ír le. A konstruktoron belül inicializáljuk az összes mezőt, és ide rakjuk a logikát: nyomtassunk ki néhány információt a gyárról a konzolra. Úgy tűnik, nincs ezzel semmi baj, a program tökéletesen működött. Konzol kimenet: Autógyárunk neve Ford 115 éve alakult Ez idő alatt 50 000 000 autót gyártott átlagosan évi 434 782 autót. De valójában időzített bombát helyeztünk el. És egy ilyen kód nagyon könnyen hibákhoz vezethet. Képzeld el, hogy most nem a Fordról beszélünk, hanem az új "Amigo Motors" gyárról, amely alig egy éve létezik és 1000 autót gyártott: állami osztályú CarFactory ( String név; int kor; int carsCount; public CarFactory (String) name, int age, int carsCount) ( this . name = name; this . age = kor; this . carsCount = carsCount; System. out. println ( "Autógyárunkat úgy hívják"+ ezt. név); Rendszer. ki. println ( "Alapították"+ ezt. életkor + "évekkel ezelőtt" ) ; Rendszer. ki. println ( "Ez idő alatt készült el"+ ezt. carsCount + "cars" ) ; Rendszer. ki. println ( "Átlagosan termel"+ (this . carsCount/ this . age) + "autók évente" ) ; ) public static void main (String args) ( CarFactory ford = new CarFactory ("Amigo Motors" , 0 , 1000 ) ; ) ) Konzol kimenet: Autógyárunk az Amigo Motors Exception nevet kapta a "main" szálban java.lang.ArithmeticException: / by zero 0 éve alapították Ez idő alatt 1000 autót gyártott a CarFactoryban. (CarFactory.java:15) itt: CarFactory.main(CarFactory.java:23) A folyamat az 1-es kilépési kóddal befejeződött Megérkeztünk! A program furcsa hibával ért véget. Kitalálod, mi az oka? Az ok abban a logikában rejlik, amelyet a konstruktorba helyeztünk. Pontosabban ebben a sorban: Rendszer. ki. println ( "Átlagosan termel"+ (this . carsCount/ this . age) + "autók évente" ) ; Itt elvégzünk egy számítást, és elosztjuk a gyártott gépek számát a gyár életkorával. És mivel a gyárunk új (vagyis 0 éves), az eredmény egy 0-val való osztás, ami a matematikában tilos. Ennek eredményeként a program hibával leáll. Hogyan kellett volna tennünk? Helyezze át az összes logikát egy külön metódusba, és hívja meg, például: printFactoryInfo() . Átadhat neki egy CarFactory objektumot paraméterként. Ott is elhelyezheti az összes logikát, és egyben - az esetleges hibák feldolgozását, mint a miénk nulla évnél. Mindenkinek a magáét. Konstruktorokra van szükség az objektum állapotának helyes beállításához. Az üzleti logikához vannak módszereink. Ne keverje az egyiket a másikkal. Íme néhány hasznos link, ahol többet olvashat a konstruktorokról:



Tetszett a cikk? Oszd meg