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

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

Топта жарияланған
Сәлеметсіз бе! Бүгін біз an objectілерімізге қатысты өте маңызды тақырыпты қарастырамыз. Міне, артық айтпай-ақ, сіз бұл білімді күнделікті нақты жұмыста қолданасыз деп айта аламыз! Біз конструкторлар туралы сөйлесетін боламыз. Сіз бұл терминді бірінші рет естіп отырған шығарсыз, бірақ шын мәнінде конструкторларды пайдаланған шығарсыз, бірақ сіз оны өзіңіз байқамай қалдыңыз :) Мұны кейінірек көреміз.

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;

   }
}
Біз көлігімізді жасап, оның моделі мен максималды жылдамдығын орнаттық. Дегенмен, нақты жобада Автокөлік нысанында 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 нысанын жасадық . Бір мәселе: бізде 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 жылы null мырза сатып алды.
Көлік үшін 2 миллион доллар төлеген сатып алушыңызға «Нул мырза» деп аталу ұнамайтыны анық! Бірақ шындап айтқанда, ақыр соңында біздің бағдарлама дұрыс жасалмаған нысанмен аяқталды - жиегі ені 0 (яғни жиектері мүлде жоқ), жоқ жүксалғыш, белгісіз материалдан жасалған салон және тіпті белгісіз біреуге тиесілі автомобиль. . Бағдарлама жұмыс істеп тұрған кезде мұндай қатенің қалай болуы мүмкін екенін елестетуге болады! Мұндай жағдайлардан қалай да аулақ болуымыз керек. Бізге бағдарламамызда шектеу болуы керек: жаңа көлік нысанын жасағанда, мысалы, ол үшін үлгі мен максималды жылдамдық әрқашан көрсетілуі керек. Әйтпесе, нысан жасауға рұқсат бермеңіз. Конструктор функциялары бұл тапсырманы оңай жеңеді. Олар өз есімдерін бір себеппен алды. Конструктор класстың «қаңқасын» жасайды, оған сыныптың әрбір жаңа an objectісі сәйкес келуі керек. Ыңғайлы болу үшін екі өрісі бар Автокөлік класының қарапайым нұсқасына оралайық . Біздің талаптарымызды ескере отырып, Car класының конструкторы келесідей болады:
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);
}
Назар аударыңызконструктор қалай құрылған. Бұл әдеттегі әдіске ұқсас, бірақ оның қайтару түрі жоқ. Бұл жағдайда сынып атауы конструкторда бас әріппен де көрсетіледі. Біздің жағдайда - Автокөлік . Сонымен қатар, конструктор this . new-to-siz кілт сөзін пайдаланады . «осы» ағылшын тілінен аударғанда «осы, мынау» дегенді білдіреді. Бұл сөз белгілі бір 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
Конструктор қажетті мәндерді сәтті тағайындады. Сіз конструктордың әдеттегі әдіске өте ұқсас екенін байқаған боларсыз! Міне осылай: конструктор - бұл әдіс, аз ғана нақты :) Әдістегі сияқты, біз конструкторға параметрлерді бердік. Әдісті шақыру сияқты, конструкторды шақыру, егер сіз оларды көрсетпесеңіз жұмыс істемейді:
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");
   }

}
«Аты» және «жасы» параметрлері бар бастапқы конструкторға біз тек атымен тағы біреуін қостық. Біз алдыңғы сабақтарда дәл осылай әдістерді шамадан тыс жүктедік. Енді біз мысықтардың екі нұсқасын да сәтті жасай аламыз :) Конструкторлар не үшін қажет?  - 2Дәрістің басында сіз конструкторларды қолданып қойғансыз, бірақ оны байқамай қалдыңыз деп айтқанымыз есіңізде ме? Дәл солай. Өйткені Java-дағы әрбір сыныпта әдепкі конструктор деп аталатын бар. Оның ешқандай дәлелдері жоқ, бірақ ол кез келген сыныптың кез келген нысаны жасалған сайын іске қосылады.
public class Cat {

   public static void main(String[] args) {

       Cat barsik = new Cat(); //this is where the default constructor worked
   }
}
Бір қарағанда бұл байқалмайды. Ал, біз 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
   }
}
Консоль шығысы:
Олар мысық жасады!
Міне, растау! Әдепкі конструктор әрқашан сіздің сыныптарыңызда көрінбейді. Бірақ оның тағы бір ерекшелігін білу керек. Аргументтері бар кейбір конструктор жасаған кезде әдепкі конструктор сыныптан жоғалады. Оның дәлелі, шын мәнінде, біз жоғарыда көрдік. Міне, осы 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 нысаны жасалған кезде оған сан мен жолды сол ретпен беру керектігін анық айтады. Сондықтан біздің 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 жылдамдығы бар автомобильдер немесе басқа «дұрыс емес» нысандар болмайды. Оларды қолдану, ең алдымен, программисттің өзіне өте тиімді. Өрістерді өзіңіз инициализацияласаңыз, бірдеңені жіберіп алу және қателесу қаупі жоғары. Бірақ бұл конструктормен болмайды: егер сіз оған барлық қажетті аргументтерді бермесеңіз немесе олардың түрлерін араластырсаңыз, компилятор бірден қате жібереді. Бағдарламаның логикасын конструктор ішіне қоймау керек екенін бөлек атап өткен жөн. Мұны істеу үшін сізге қажет барлық функцияларды сипаттауға болатын әдістер бар. Конструктор логикасы неге жаман идея екенін қарастырайық:
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 класы бар. Конструктордың ішінде біз барлық өрістерді инициализациялаймыз және логиканы осында орналастырамыз: консольге зауыт туралы кейбір ақпаратты көрсетеміз. Бұл жерде ештеңе жоқ сияқты, бағдарлама тамаша жұмыс істеді. Консоль шығысы:
Біздің автозауыт Форд деп аталады.Оның негізі қаланғанына 115 жыл болды.Осы уақыт ішінде 50000000 автокөлік шығарылды.Орташа есеппен жылына 434782 автомобиль шығарады.
Бірақ іс жүзінде біз сағаттық бомба орнаттық. Және мұндай code өте оңай қателерге әкелуі мүмкін. Елестетіп көрейікші, қазір біз Форд туралы емес, бір жылдан аз уақыт жұмыс істеп, 1000 автокөлік шығарған жаңа «Amigo Motors» зауыты туралы айтып отырмыз:
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);
   }
}
Консоль шығысы:
Біздің автомобиль зауыты "main" java.lang.ArithmeticException ағынында Amigo Motors Exception деп аталады: / нөлге дейін Ол 0 жыл бұрын құрылған. Осы уақыт ішінде ол CarFactory-да 1000 автомобиль шығарды.<init>(CarFactory.java:15) CarFactory.main(CarFactory.java:23) Процесс 1</init>шығу codeымен аяқталды
Біз келдік! Бағдарлама біртүрлі қатемен аяқталды. Мұның себебі неде екенін білуге ​​тырысасыз ба? Себебі, біз конструкторға орналастырған логика. Атап айтқанда, осы жолда:
System.out.println("On average she produces" + (this.carsCount/this.age) + "cars per year");
Мұнда біз есептеуді жүргіземіз және шығарылған автомобильдер санын зауыттың жасына бөлеміз. Ал біздің фабрика жаңа болғандықтан (яғни 0 жаста), нәтиже математикада тыйым салынған 0-ге бөлу. Нәтижесінде бағдарлама қатемен аяқталады. Біз не істеуіміз керек еді? Барлық логиканы бөлек әдіске жылжытыңыз және оны шақырыңыз, мысалы, printFactoryInfo() . Сіз оны параметр ретінде CarFactory нысанын бере аласыз . Сондай-ақ, сіз барлық логиканы сонда орналастыра аласыз және сонымен бірге - нөлдік жылдардағы сияқты ықтимал қателерді өңдеуге болады. Әркімге өзінікі. Конструкторлар an objectінің күйін дұрыс орнату үшін қажет. Бизнес логикасы үшін бізде әдістер бар. Біреуін екіншісімен араластырмау керек.
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION