JavaRush /Java блогу /Random-KY /Javaдагы конструкторлор

Javaдагы конструкторлор

Группада жарыяланган
Салам! Бүгүн биз an objectилерибизге тиешелүү абдан маанилүү теманы карап чыгабыз. Бул жерде, апыртпастан, бул бorмди сиз күн сайын чыныгы жумушта колдоносуз деп айта алабыз! Биз конструкторлор жөнүндө сүйлөшөбүз. Сиз бул терминди биринчи жолу угуп жаткандырсыз, бирок чындыгында конструкторлорду колдонсоңуз керек, бирок сиз аны өзүңүз байкаган жоксуз :) Муну кийинчерээк көрөбүз.

Javaдагы конструктор деген эмне жана ал эмне үчүн керек?

Келгиле, эки мисалды карап көрөлү.
public class Car {

   String model;
   int maxSpeed;

   public static void main(String[] args) {

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

   }
}
Биз өзүбүздүн унаабызды жасап, анын моделин жана максималдуу ылдамдыгын койдук. Бирок, реалдуу долбоордо Car an objectисинде 2ден ашык талаа болот. Жэне, мысалы, 16 кен!
public class Car {

   String model;//model
   int maxSpeed;//max speed
   int wheels;// disk width
   double engineVolume;//engine capacity
   String color;//color
   int yearOfIssue;//year of issue
   String ownerFirstName;//Owner's name
   String ownerLastName;//owner's last name
   long price;//price
   boolean isNew;//new or not
   int placesInTheSalon;//number of seats in the cabin
   String salonMaterial;// interior material
   boolean insurance;//is it insured
   String manufacturerCountry;//manufacturer country
   int trunkVolume;// trunk volume
   int accelerationTo100km;//acceleration 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.yearOfIssue = 2016;
       bugatti.insurance = true;
       bugatti.price = 2000000;
       bugatti.isNew = false;
       bugatti.placesInTheSalon = 2;
       bugatti.maxSpeed = 407;
       bugatti.model = "Bugatti Veyron";

   }

}
Биз жаңы Car an objectин түздүк . Бир көйгөй: бизде 16 талаа бар, бирок биз 12 гана инициализация кылдык ! Биз унутуп калгандарды табуу үчүн codeду колдонуп көрүңүз! Анчалык оңой эмес, туурабы? Мындай кырдаалда программист оңой эле ката кетирип, кандайдыр бир талаанын инициализациясын өткөрүп жибериши мүмкүн. Натыйжада, программанын жүрүм-туруму ката болуп калат:
public class Car {

   String model;//model
   int maxSpeed;//max speed
   int wheels;// disk width
   double engineVolume;//engine capacity
   String color;//color
   int yearOfIssue;//year of issue
   String ownerFirstName;//Owner's name
   String ownerLastName;//owner's last name
   long price;//price
   boolean isNew;//new or not
   int placesInTheSalon;//number of seats in the cabin
   String salonMaterial;// interior material
   boolean insurance;//is it insured
   String manufacturerCountry;//manufacturer country
   int trunkVolume;// trunk volume
   int accelerationTo100km;//acceleration 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.yearOfIssue = 2016;
       bugatti.insurance = true;
       bugatti.price = 2000000;
       bugatti.isNew = false;
       bugatti.placesInTheSalon = 2;
       bugatti.maxSpeed = 407;
       bugatti.model = "Bugatti Veyron";

       System.out.println("Model Bugatti Veyron. Engine size - " + bugatti.engineVolume + ", trunk - " + bugatti.trunkVolume + ", salon is made of" + bugatti.salonMaterial +
       ", disc width - " + bugatti.wheels + ". Was acquired in 2018 by Mr. " + bugatti.ownerLastName);

   }

}
Консолдук чыгаруу:
Bugatti Veyron модели. Мотордун көлөмү - 6,3, магистралдык - 0, салону нөлдөн жасалган, жээктин туурасы - 0. 2018-жылы Mr null сатып алган
Унаа үчүн 2 миллион доллар төлөгөн сатып алуучуңузга “Нул мырза” деген ат такыр жакпайт! Бирок, олуттуу түрдө, аягында биздин программа туура эмес түзүлгөн an object менен аяктады - жээктин туурасы 0 болгон унаа (башкача айтканда, такыр алHowтары жок), жок жүк салгыч, белгисиз материалдан жасалган салон, ал тургай белгисиз бирөөлөргө таандык. . Программа иштеп жатканда мындай ката кантип пайда болорун элестете алабыз! Мындай жагдайлардан кандайдыр бир жол менен качышыбыз керек. Биздин программада чектөө болушу керек: мисалы, жаңы унаа an objectин түзүп жатканда, ал үчүн модел жана максималдуу ылдамдык дайыма көрсөтүлүшү керек. Болбосо, an object түзүүгө жол бербеңиз. Конструктор функциялары бул милдетти оңой эле чечет. Алардын атын бир себеп менен алышкан. Конструктор класстын кандайдыр бир “скелетин” түзөт, ага класстын ар бир жаңы an objectиси дал келиши керек. Ыңгайлуу болуу үчүн, эки талаалуу Car классынын жөнөкөй versionсына кайрылып көрөлү . Биздин талаптарды эске алуу менен, Car классынын конструктору төмөнкүдөй болот:
public Car(String model, int maxSpeed) {
   this.model = model;
   this.maxSpeed = maxSpeed;
}
Ал эми an object түзүү азыр мындай көрүнөт:
public static void main(String[] args) {
   Car bugatti = new Car("Bugatti Veyron", 407);
}
Көңүл бурууконструктор кантип түзүлгөн. Бул кадимки ыкмага окшош, бирок анын кайтаруу түрү жок. Бул учурда класстын аталышы конструктордо баш тамга менен да көрсөтүлөт. Биздин учурда - Машина . Мындан тышкары, конструктор this . new-to-size ачкыч сөзүн колдонот . "бул" англис тorнен которгондо "бул, бул" дегенди билдирет. Бул сөз белгилүү бир an objectти билдирет. Конструктордогу code:
public Car(String model, int maxSpeed) {
   this.model = model;
   this.maxSpeed = maxSpeed;
}
дээрлик түзмө-түз которууга болот: " бул машинанын модели (биз азыр түзүп жатабыз) = конструктордо көрсөтүлгөн модель аргументи . Бул машина үчүн maxSpeed ​​(биз түзүп жаткан) = maxSpeed ​​аргументи , кайсы конструктордо көрсөтүлгөн." Бул эмне болду:
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", 407);
       System.out.println(bugatti.model);
       System.out.println(bugatti.maxSpeed);
   }

}
Консолдук чыгаруу:
Bugatti Veyron 407
Конструктор керектүү маанилерди ийгorктүү дайындады. Сиз конструктор кадимки ыкмага абдан окшош экенин байкаган чыгарсыз! Мына ушундай: конструктор бул метод, бир аз гана конкреттүү :) Методдогудай эле, биз конструкторубузга параметрлерди өткөрүп бердик. Методду чакыргандай эле, конструкторду чакыруу да иштебейт, эгерде сиз аларды көрсөтпөсөңүз:
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!
   }

}
Көрдүңүзбү, дизайнер биз жетишүүгө аракет кылган нерсени жасады. Эми ылдамдыгы жок же модели жок машина жасай албайсыз! Конструкторлор менен методдордун окшоштуктары муну менен эле бүтпөйт. Методдор сыяктуу эле, конструкторлор да ашыкча жүктөлүшү мүмкүн. Үйүңүздө 2 мышык бар деп элестетиңиз. Алардын бирин котёнок кылып алдың, экинчисин чоң болуп көчөдөн үйгө алып келдиң жана анын канча жашта экенин так билбейсиң. Бул биздин программа эки типтеги мышыктарды түзө алышы керек дегенди билдирет - биринчи мышыктын аты жана жашы менен, экинчи мышыктын аты менен гана. Бул үчүн, биз конструкторду ашыкча жүктөйбүз:
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 barsik = new Cat("Barsik", 5);
       Cat streetCatNamedBob = new Cat("Bob");
   }

}
"Аты" жана "жаш" параметрлери бар түпнуска конструкторго биз дагы бир ысымды коштук. Мурунку сабактарда да ушундай эле ыкмаларды ашыкча жүктөгөнбүз. Эми биз мышыктардын эки versionсын тең ийгorктүү түзө алабыз :) Эмне үчүн конструкторлор керек?  - 2Эсиңдеби, лекциянын башында сиз буга чейин конструкторлорду колдонгон экенсиз, бирок аны байкабай калгансызбы? Бул чыныгы. Чындыгында Javaдагы ар бир класста демейки конструктор деп аталган нерсе бар. Анын эч кандай аргументтери жок, бирок ал каалаган класстын an objectи түзүлгөн сайын күйөт.
public class Cat {

   public static void main(String[] args) {

       Cat barsik = new Cat(); //this is where the default constructor worked
   }
}
Бир караганда бул байкалbyte. Ооба, биз an objectти түзүп, аны жараттык, дизайнердин иши кайда? Муну көрүү үчүн, келгиле, Cat классы үчүн өз колубуз менен бош конструктор жазып алалы жана анын ичинде биз консолго кандайдыр бир фразаны басып чыгарабыз. Эгерде ал көрсөтүлсө, анда конструктор иштеген.
public class Cat {

   public Cat() {
       System.out.println("Created a cat!");
   }

   public static void main(String[] args) {

       Cat barsik = new Cat(); //this is where the default constructor worked
   }
}
Консолдук чыгаруу:
Алар мышык жаратты!
Мына тастыктоо! Демейки конструктор сиздин класстарыңызда дайыма көрүнбөй турат. Бирок анын дагы бир өзгөчөлүгүн билүү керек. Аргументтер менен конструктор түзгөндө демейки конструктор класстан жок болот. Мунун далor, чындыгында, биз жогоруда көрдүк. Бул codeдо:
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 barsik = new Cat(); //error!
   }
}
Биз мышыкты аты жана жашы жок түзө алган жокпуз, анткени биз Cat : string + number үчүн конструкторду аныктадык . Демейки конструктор мындан кийин дароо класстан жок болду. Ошондуктан, унутпаңыз: классыңызда бир нече конструктор керек болсо, анын ичинде бош конструктор болсо, аны өзүнчө түзүшүңүз керек. Мисалы, биз ветеринардык клиникага программа түзүп жатабыз. Биздин клиника жакшы иштерди жасап, аты-жөнүн, жашын билбеген үй-жайсыз мышыктарга жардам берүүнү каалайт. Анда биздин code төмөнкүдөй болушу керек:
public class Cat {

   String name;
   int age;

   //for domestic cats
   public Cat(String name, int age) {
       this.name = name;
       this.age = age;
   }

   //for street cats
   public Cat() {
   }

   public static void main(String[] args) {

       Cat barsik = new Cat("Barsik", 5);
       Cat streetCat = new Cat();
   }
}
Эми биз ачык түрдө демейки конструкторду жазгандан кийин, биз эки типтеги мышыктарды түзө алабыз :) Конструктор үчүн (кандайдыр бир ыкма сыяктуу), аргументтердин тартиби абдан маанилүү. Келгиле, конструкторубуздагы ат менен жаш аргументтерин алмаштыралы.
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 barsik = new Cat("Barsik", 10); //error!
   }
}
Ката! Конструктор Cat an objectи түзүлгөндө, ага санды жана сапты ошол тартипте өткөрүп берүү керек экенин ачык айтат. Ошондуктан биздин code иштебейт. Муну унутпаңыз жана өзүңүздүн класстарыңызды түзүүдө муну эстен чыгарбаңыз:
public Cat(String name, int age) {
   this.name = name;
   this.age = age;
}

public Cat(int age, String name) {
   this.age = age;
   this.name = name;
}
Бул эки башка дизайнерлер! «Бизге конструктор эмне үчүн керек?» деген суроого жоопту бир сүйлөм менен айтсак, мындай деп айта алабыз: an objectтер дайыма туура абалда болуш үчүн. Конструкторлорду колдонгондо, бардык өзгөрмөлөрүңүз туура инициализацияланат жана программада ылдамдыгы 0 болгон унаалар же башка "туура эмес" an objectтер болбойт. Аларды колдонуу, биринчи кезекте, программист өзү үчүн абдан пайдалуу. Эгер сиз талааларды өзүңүз баштасаңыз, анда бир нерсени өткөрүп жиберүү жана ката кетирүү коркунучу жогору. Бирок конструктор менен мындай болбойт: эгерде сиз ага бардык керектүү аргументтерди бербесеңиз же алардын түрлөрүн аралаштырсаңыз, компилятор дароо ката кетирет. Программаңыздын логикасын конструктордун ичине киргизбешиңизди өзүнчө белгилеп кетүү керек. Бул үчүн, сизде керектүү бардык функцияларды сүрөттөй турган ыкмаларыңыз бар. Келгиле, конструктор логикасы эмне үчүн жаман идея экенин карап көрөлү:
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("She was founded" + this.age + " years ago" );
   System.out.println("During this time it was produced" + this.carsCount +  "cars");
   System.out.println("On average she produces" + (this.carsCount/this.age) + "cars per year");
}

   public static void main(String[] args) {

       CarFactory ford = new CarFactory("Ford", 115 , 50000000);
   }
}
Бизде унааларды чыгаруучу заводду сүрөттөгөн CarFactory классы бар. Конструктордун ичинде биз бардык талааларды инициализациялайбыз жана бул жерде логиканы жайгаштырабыз: консолго завод жөнүндө кээ бир маалыматтарды көрсөтөбүз. Бул жерде эч кандай ката жок окшойт, программа кемчorксиз иштеген. Консолдук чыгаруу:
Биздин автозавод Форд деп аталат.Ал 115 жыл мурун негизделген.Бул убакыттын ичинде 50000000 машина чыгарды.Жылына орто эсеп менен 434782 машина чыгарат.
Бирок чындыгында биз сааттык бомбаны орноттук. Жана мындай code абдан оңой каталарга алып келиши мүмкүн. Эми сөз Форд жөнүндө эмес, бир жылга жетпеген убакыттан бери иштеп, 1000 автоунаа чыгарган жаңы завод "Амиго Моторс" жөнүндө болуп жатканын элестетип көрөлү:
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("She was founded" + this.age + " years ago" );
   System.out.println("During this time it was produced" + this.carsCount +  "cars");
   System.out.println("On average she produces" + (this.carsCount/this.age) + "cars per year");
}


   public static void main(String[] args) {

       CarFactory ford = new CarFactory("Amigo Motors", 0 , 1000);
   }
}
Консолдук чыгаруу:
Биздин унаа заводубуз Amigo Motors Exception деп аталат "main" java.lang.ArithmeticException: / by нөл Бул 0 жыл мурун негизделген Бул убакыттын ичинде ал CarFactoryде 1000 унаа чыгарган.<init>(CarFactory.java:15) at CarFactory.main(CarFactory.java:23) Процесс 1 чыгуу codeу менен аяктады</init>
Биз келдик! Программа кандайдыр бир кызыктай ката менен аяктады. Мунун себеби эмнеде экенин билүүгө аракет кыласызбы? Себеби, биз конструкторго жайгаштырган логика. Тактап айтканда, бул сапта:
System.out.println("On average she produces" + (this.carsCount/this.age) + "cars per year");
Бул жерде биз эсептеп чыгып, заводдун жашына жараша чыгарылган машиналардын санын бөлөбүз. Ал эми биздин завод жаңы болгондуктан (башкача айтканда, 0 жыл мурун) математикада тыюу салынган 0гө бөлүнөт. Натыйжада, программа ката менен аяктайт. Эмне кылышыбыз керек эле? Бардык логиканы өзүнчө ыкмага жылдырыңыз жана аны чакырыңыз, мисалы, printFactoryInfo() . Сиз аны CarFactory an objectисин параметр катары өткөрө аласыз . Сиз ошондой эле бардык логиканы ошол жерге кое аласыз, ошол эле учурда - нөл жыл менен биздики сыяктуу мүмкүн болгон каталарды иштетүү. Ар кимге өзүнүкү. Конструкторлор an objectтин абалын туура орнотуу үчүн керек. Бизнес логикасы үчүн бизде ыкмалар бар. Бирин экинчисине аралаштырбоо керек.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION