CodeGym/Java Blog/Random/Mga Tagabuo ng Java
John Squirrels
Antas
San Francisco

Mga Tagabuo ng Java

Nai-publish sa grupo
Hi! Ngayon ay isasaalang-alang natin ang isang napakahalagang paksa na may kinalaman sa ating mga bagay. Nang walang pagmamalabis, masasabi nating gagamitin mo ang paksang ito sa totoong buhay araw-araw! Pinag-uusapan natin ang tungkol sa Java Constructors. Maaaring ito ang unang pagkakataon na maririnig mo ang terminong ito, ngunit nakagamit ka na talaga ng mga constructor. Hindi mo lang narealize :) We convince ourselves of this later.

Ano sa mundo ang mga konstruktor at bakit kailangan ang mga ito?

Isaalang-alang natin ang dalawang halimbawa.
public class Car {

   String model;
   int maxSpeed;

   public static void main(String[] args) {

       Car bugatti = new Car();
       bugatti.model = "Bugatti Veyron";
       bugatti.maxSpeed = 378;

   }
}
Ginawa namin ang aming sasakyan, at itinakda ang modelo at pinakamataas na bilis nito. Ngunit ang object ng Kotse ay malinaw na walang 2 field sa isang tunay na proyekto. Halimbawa, maaaring mayroon itong 16 na field!
public class Car {

   String model;// model
   int maxSpeed;// maximum speed
   int wheels;// wheel width
   double engineVolume;// engine volume
   String color;// color
   int productionYear;// production year
   String ownerFirstName;// first name of owner
   String ownerLastName;// last name of owner
   long price;// price
   boolean isNew;// flag indicating whether car is new
   int seatsInTheCar;// number of seats in the car
   String cabinMaterial;// interior material
   boolean insurance;// flag indicating whether car is insured
   String manufacturerCountry;// manufacturer country
   int trunkVolume;// size of the trunk
   int accelerationTo100km;// how long it takes to accelerate to 100 km/h (in seconds)


   public static void main(String[] args) {
       Car bugatti = new Car();

       bugatti.color = "blue";
       bugatti.accelerationTo100km = 3;
       bugatti.engineVolume = 6.3;
       bugatti.manufacturerCountry = "Italy";
       bugatti.ownerFirstName = "Amigo";
       bugatti.productionYear = 2016;
       bugatti.insurance = true;
       bugatti.price = 2000000;
       bugatti.isNew = false;
       bugatti.seatsInTheCar = 2;
       bugatti.maxSpeed = 378;
       bugatti.model = "Bugatti Veyron";

   }

}
Gumawa kami ng bagong bagay sa Kotse . May isang problema: mayroon kaming 16 na field, ngunit 12 lang ang sinimulan namin ! Tingnan ang code ngayon at subukang hanapin ang mga field na nakalimutan namin! Hindi ganoon kadali, ha? Sa sitwasyong ito, ang isang programmer ay madaling magkamali at hindi makapagsimula ng ilang field. Bilang resulta, mali ang kilos ng programa:
public class Car {

   String model;// model
   int maxSpeed;// maximum speed
   int wheels;// wheel width
   double engineVolume;// engine volume
   String color;// color
   int productionYear;// production year
   String ownerFirstName;// first name of owner
   String ownerLastName;// last name of owner
   long price;// price
   boolean isNew;// flag indicating whether car is new
   int seatsInTheCar;// number of seats in the car
   String cabinMaterial;// interior material
   boolean insurance;// flag indicating whether car is insured
   String manufacturerCountry;// manufacturer country
   int trunkVolume;// size of the trunk
   int accelerationTo100km;// how long it takes to accelerate to 100 km/h (in seconds)


   public static void main(String[] args) {
       Car bugatti = new Car();

       bugatti.color = "blue";
       bugatti.accelerationTo100km = 3;
       bugatti.engineVolume = 6.3;
       bugatti.manufacturerCountry = "Italy";
       bugatti.ownerFirstName = "Amigo";
       bugatti.productionYear = 2016;
       bugatti.insurance = true;
       bugatti.price = 2000000;
       bugatti.isNew = false;
       bugatti.seatsInTheCar = 2;
       bugatti.maxSpeed = 378;
       bugatti.model = "Bugatti Veyron";

       System.out.println("Model: Bugatti Veyron. Engine volume: " + bugatti.engineVolume + ". Trunk volume: " + bugatti.trunkVolume + ". Cabin material: " + bugatti.cabinMaterial +
       ". Wheel width: " + bugatti.wheels + ". Purchased in 2018 by Mr. " + bugatti.ownerLastName);

   }

}
Output ng console: Modelo: Bugatti Veyron. Dami ng makina: 6.3. Dami ng puno ng kahoy: 0. Materyal sa cabin: null. Lapad ng gulong: 0. Binili noong 2018 ni Mr. null Ang iyong bumibili, na nagbigay ng $2 milyon para sa kotse, ay halatang hindi magugustuhan na tawaging " Mr. null "! Ngunit seryoso, ang punto ay ang aming programa ay lumikha ng isang bagay nang hindi tama: isang kotse na may lapad ng gulong na 0 (ibig sabihin, walang mga gulong sa lahat), isang nawawalang puno ng kahoy, isang cabin na gawa sa hindi kilalang materyal, at higit sa lahat, isang hindi natukoy na may-ari . Maaari mo lamang isipin kung paano maaaring "pumunta" ang gayong pagkakamali kapag tumatakbo ang programa! Kailangan nating iwasan ang mga ganitong sitwasyon kahit papaano. Kailangan naming paghigpitan ang aming programa: kapag gumagawa ng bagong Kotseobject, gusto namin ang mga patlang, tulad ng modelo at maximum na bilis, na palaging tinukoy. Kung hindi, gusto naming pigilan ang paglikha ng bagay. Hinahawakan ng mga konstruktor ang gawaing ito nang madali. Nakuha nila ang kanilang pangalan para sa isang dahilan. Ang constructor ay lumilikha ng isang uri ng klase na "skeleton" na dapat tumugma sa bawat bagong bagay. Para sa kaginhawahan, bumalik tayo sa mas simpleng bersyon ng klase ng Kotse na may dalawang field. Isinasaalang-alang ang aming mga kinakailangan, ang constructor ng klase ng Kotse ay magiging ganito:
public Car(String model, int maxSpeed) {
   this.model = model;
   this.maxSpeed = maxSpeed;
}

// And creating an object now looks like this:

public static void main(String[] args) {
   Car bugatti = new Car("Bugatti Veyron", 378);
}
Pansinin kung paano idineklara ang isang constructor. Ito ay katulad ng isang regular na pamamaraan, ngunit wala itong uri ng pagbabalik. Bukod dito, tinutukoy ng tagabuo ang pangalan ng klase ( Kotse ) na nagsisimula sa isang malaking titik. Bilang karagdagan, ang constructor ay ginagamit sa isang keyword na bago para sa iyo: ito . Ang keyword na ito ay para sa pagpahiwatig ng isang partikular na bagay. Ang code sa constructor
public Car(String model, int maxSpeed) {
   this.model = model;
   this.maxSpeed = maxSpeed;
}
maaaring bigyang-kahulugan halos verbatim: "Ang modelo para sa kotse na ito (ang ginagawa namin ngayon) ay ang modelong argumento na ipinasa sa constructor. Ang maxSpeed ​​para sa kotse na ito (ang ginagawa namin) ay ang maxSpeed ​​na argumento na ipinasa sa tagabuo." At iyon lang ang nangyayari:
public class Car {

   String model;
   int maxSpeed;

   public Car(String model, int maxSpeed) {
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   public static void main(String[] args) {
       Car bugatti = new Car("Bugatti Veyron", 378);
       System.out.println(bugatti.model);
       System.out.println(bugatti.maxSpeed);
   }

}
Output ng console: Bugatti Veyron 378 Tamang itinalaga ng constructor ang mga kinakailangang value. Maaaring napansin mo na ang isang tagabuo ay halos kapareho sa isang ordinaryong pamamaraan! Kaya ito ay. Ang isang konstruktor ay talagang isang pamamaraan, ngunit may mga partikular na tampok :) Katulad ng mga pamamaraan, ipinasa namin ang mga argumento sa aming tagabuo. At tulad ng pagtawag sa isang pamamaraan, ang pagtawag sa isang constructor ay hindi gagana maliban kung tinukoy mo ang mga ito:
public class Car {

   String model;
   int maxSpeed;

   public Car(String model, int maxSpeed) {
       this.model = model;
       this.maxSpeed = maxSpeed;
   }

   public static void main(String[] args) {
       Car bugatti = new Car(); // Error!
   }

}
Makikita mo na nagagawa ng constructor ang sinusubukan naming makamit. Ngayon ay hindi ka makakagawa ng kotse nang walang bilis o modelo! Ang pagkakatulad sa pagitan ng mga konstruktor at mga pamamaraan ay hindi nagtatapos dito. Tulad ng mga pamamaraan, ang mga konstruktor ay maaaring ma-overload. Isipin na mayroon kang 2 alagang pusa sa bahay. Nakuha mo ang isa sa kanila bilang isang kuting. Ngunit ang pangalawa ay kinuha mo mula sa kalye noong ito ay lumaki na, at hindi mo alam kung gaano katagal ito. Sa kasong ito, gusto naming makalikha ang aming programa ng dalawang uri ng pusa: ang may pangalan at edad (para sa unang pusa), at ang may pangalan lang (para sa pangalawang pusa). Para dito, i-overload natin ang constructor:
public class Cat {

   String name;
   int age;

   // For the first cat
   public Cat(String name, int age) {
       this.name = name;
       this.age = age;
   }

   // For the second cat
   public Cat(String name) {
       this.name = name;
   }

   public static void main(String[] args) {

       Cat smudge = new Cat("Smudge", 5);
       Cat streetCatNamedBob = new Cat("Bob");
   }

}
Bilang karagdagan sa orihinal na constructor na may "pangalan" at "edad" na mga parameter, nagdagdag kami ng isa pa na may parameter lang ng pangalan. Sa eksaktong parehong paraan na nag-overload kami ng mga pamamaraan sa mga nakaraang aralin. Ngayon ay maaari na tayong lumikha ng parehong uri ng pusa :)
Bakit kailangan natin ng mga constructor?  - 2
Tandaan na sa simula ng aralin sinabi namin na nakagamit ka na ng mga constructor nang hindi mo namamalayan? Sinadya namin ang sinabi namin. Ang katotohanan ay ang bawat klase sa Java ay may tinatawag na default constructor. Hindi ito nangangailangan ng anumang mga argumento, ngunit ito ay hinihingi sa bawat oras na lumikha ka ng anumang bagay ng anumang klase.
public class Cat {

   public static void main(String[] args) {

       Cat smudge = new Cat(); // The default constructor is invoked here
   }
}
Sa unang tingin, hindi ito nakikita. Gumawa kami ng isang bagay, kaya ano? Nasaan ang gumagawa ng anumang bagay dito? Para makita ito, tahasang magsulat tayo ng walang laman na constructor para sa klase ng Cat . Magpapakita kami ng ilang parirala sa loob nito. Kung ang parirala ay ipinapakita, kung gayon ang tagabuo ay tinawag.
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
   }
}
Output ng console: Isang pusa ang nagawa! Ayan na ang confirmation! Ang default na tagabuo ay palaging hindi nakikita sa iyong mga klase. Ngunit kailangan mong malaman ang isa pang bagay tungkol dito. Ang default na constructor ay tinanggal mula sa isang klase kapag lumikha ka ng isang constructor na may mga argumento. Sa katunayan, nakita na natin ang patunay nito sa itaas. Ito ay nasa code na ito:
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!
   }
}
Hindi kami makakagawa ng Cat nang walang pangalan at edad, dahil nagdeklara kami ng Cat constructor na may string at int na mga parameter. Naging sanhi ito upang ang default na tagabuo ay agad na mawala sa klase. Kaya siguraduhing tandaan na kung kailangan mo ng ilang mga konstruktor sa iyong klase, kabilang ang isang walang-argumentong tagabuo, kakailanganin mong ideklara ito nang hiwalay. Halimbawa, ipagpalagay na gumagawa tayo ng isang programa para sa isang beterinaryo na klinika. Nais ng aming klinika na gumawa ng mabubuting gawa at tumulong sa mga kuting na walang tirahan na hindi alam ang mga pangalan at edad. Kung gayon ang aming code ay dapat magmukhang ganito:
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();
   }
}
Ngayong nakapagsulat na kami ng tahasang default na constructor, maaari kaming lumikha ng parehong uri ng pusa :) Tulad ng anumang paraan, ang pagkakasunud-sunod ng mga argumento na ipinasa sa isang constructor ay napakahalaga. Palitan natin ang mga argumento ng pangalan at edad sa ating constructor.
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!
   }
}
Isang error! Malinaw na itinatakda ng tagabuo na kapag nilikha ang isang bagay na Cat , dapat itong magpasa ng isang numero at isang string, sa ganitong pagkakasunud-sunod. Kaya, hindi gumagana ang aming code. Tiyaking tandaan ito at isaisip kapag nagdedeklara ng sarili mong mga klase:
public Cat(String name, int age) {
   this.name = name;
   this.age = age;
}

public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Ito ay dalawang ganap na magkaibang mga konstruktor! Kung ihahayag natin sa isang pangungusap ang sagot sa tanong na "Bakit kailangan ko ng constructor?", maaari nating sabihin, "Upang matiyak na ang mga bagay ay palaging may wastong estado". Kapag gumamit ka ng mga constructor, ang lahat ng iyong mga variable ay tama ang pagsisimula. Ang iyong mga programa ay hindi magkakaroon ng anumang mga kotse na may bilis na 0 o anumang iba pang "di-wastong" mga bagay. Ang kanilang pangunahing benepisyo ay para sa programmer. Kung manu-mano mong sinisimulan ang mga field (pagkatapos gumawa ng isang bagay), may malaking panganib na may makaligtaan ka at magpakilala ng bug. Ngunit hindi ito mangyayari sa isang constructor: kung hindi mo maipasa ang lahat ng kinakailangang argumento o pumasa ka sa mga maling uri ng argumento, agad na magrerehistro ng error ang compiler. Dapat din nating hiwalay na sabihin na hindi mo dapat ilagay ang iyong programa' s logic sa loob ng isang constructor. Ito ay para sa mga pamamaraan. Ang mga pamamaraan ay kung saan dapat mong tukuyin ang lahat ng kinakailangang pag-andar. Tingnan natin kung bakit ang pagdaragdag ng lohika sa isang constructor ay isang masamang ideya:
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("Our car factory is called " + this.name);
   System.out.println("It was founded " + this.age + " years ago" );
   System.out.println("Since that time, it has produced " + this.carsCount +  " cars");
   System.out.println("On average, it produces " + (this.carsCount/this.age) + " cars per year");
}

   public static void main(String[] args) {

       CarFactory ford = new CarFactory("Ford", 115 , 50000000);
   }
}
Mayroon kaming klase ng CarFactory na naglalarawan sa pabrika ng kotse. Sa loob ng constructor, sinisimulan namin ang lahat ng mga field at may kasamang ilang logic: nagpapakita kami ng ilang impormasyon tungkol sa pabrika. Parang wala namang masama dito. Ang programa ay gumagana nang maayos. Output ng console: Ang pabrika ng aming kotse ay tinatawag na Ford Itinatag ito 115 taon na ang nakakaraan Simula noon, nakagawa na ito ng 50000000 na sasakyan Sa karaniwan, gumagawa ito ng 434782 na sasakyan kada taon Ngunit talagang naglagay kami ng minahan na naantala ng oras. At ang ganitong uri ng code ay napakadaling humantong sa mga error. Ipagpalagay na ngayon ay hindi namin pinag-uusapan ang tungkol sa Ford, ngunit tungkol sa isang bagong pabrika na tinatawag na "Amigo Motors", na umiral nang wala pang isang taon at nakagawa ng 1000 mga kotse:
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("Our car factor is called " + this.name);
   System.out.println("It was founded " + this.age + " years ago" );
   System.out.println("Since that time, it has produced " + this.carsCount +  " cars");
   System.out.println("On average, it produces " + (this.carsCount/this.age) + " cars per year");
}


   public static void main(String[] args) {

       CarFactory ford = new CarFactory("Amigo Motors", 0 , 1000);
   }
}
Output ng console: Ang aming pabrika ng kotse ay tinatawag na Amigo Motors Exception sa thread na "main" na java.lang.ArithmeticException: / by zero Itinatag ito 0 taon na ang nakakaraan Simula noon, nakagawa ito ng 1000 sasakyan sa CarFactory. (CarFactory.java:15) sa CarFactory.main(CarFactory.java:23) Natapos ang proseso sa exit code 1 Boom! Ang programa ay nagtatapos sa ilang uri ng hindi maintindihan na error. Subukan mo bang hulaan ang dahilan? Ang problema ay nasa logic na inilagay namin sa constructor. Mas partikular, ang linyang ito:
System.out.println("On average, it produces " + (this.carsCount/this.age) + " cars per year");
Dito ka nagsasagawa ng pagkalkula at paghahati sa bilang ng mga sasakyang ginawa ayon sa edad ng pabrika. At dahil ang aming pabrika ay bago (ibig sabihin, ito ay 0 taong gulang), hinahati namin sa 0, na hindi namin magagawa sa matematika. Dahil dito, ang programa ay nagtatapos sa isang error.

Ano ang dapat naming ginawa?

Ilagay ang lahat ng lohika sa isang hiwalay na pamamaraan. Tawagan natin itong printFactoryInfo() . Maaari kang magpasa ng object ng CarFactory dito bilang argumento. Maaari mong ilagay ang lahat ng lohika doon, at sabay-sabay na pangasiwaan ang mga potensyal na error (tulad ng sa amin na kinasasangkutan ng zero na taon). Sa kanya-kanyang sarili. Kinakailangan ang mga konstruktor upang magtakda ng wastong estado ng object. Mayroon kaming mga pamamaraan para sa lohika ng negosyo. Huwag ihalo ang isa sa isa. Upang palakasin ang iyong natutunan, iminumungkahi naming manood ka ng isang video lesson mula sa aming Java Course
Mga komento
  • Sikat
  • Bago
  • Luma
Dapat kang naka-sign in upang mag-iwan ng komento
Wala pang komento ang page na ito