Урок 6
Извикване на конструктора this ()
Пример 6.6 Претоварване на конструктора
Пример 6-7 показва използването на конструктора this (), който ви позволява да внедрите локално свързване на конструктори в клас по време на екземпляра. Първите два конструктора на редове (1) и (2) от Пример 6.6 са пренаписани, като се използва извикването на конструктора this (). Конструкторът this () може да се счита за локално претоварен, тъй като параметрите му (а оттам и подписът) могат да варират, както е показано в тялото на конструкторите в редове (1) и (2). Извикването на this () стартира конструктора със съответния списък с параметри. В метода main () от (4) се извиква специфичен конструктор в зависимост от аргументите, които се дават, когато стартира, когато е създаден всеки от трите обекта Light. Извикването на конструктора по подразбиране за създаване на обект Light води до изпълнение и на втория и третия конструктор. Това се потвърждава от изхода на програмата. В нашия случай изходът показва, че третият конструктор се изпълнява първо, последван от втория и накрая конструкторът по подразбиране, наречен first. Имайки предвид конструкторските дефиниции, имайте предвид, че те се изпълняват в обратен ред; тези. извикването на конструктора по подразбиране незабавно води до извикване на втория конструктор поради това (0, false), като извикването му незабавно предизвиква незабавно извикване на третия поради това (watt, ind, "X"), т.е. изпълнението се извършва по реда на обратното повикване. По същия начин, извикването на втория конструктор, за да се създаде екземпляр на класа Light, води до изпълнение на третия конструктор по същия начин.
Java изисква от вас да се уверите, че всяко извикване на this () е първият израз в конструктор. Всеки важен код може да последва повикването към this (). Това ограничение е въведено, защото Java обработва извикването на конструктора на суперклас по време на създаването на обекта на подкласа. Този механизъм е обяснен в следващия подраздел.
Пример 6.7. Извикване на конструктора this ()
Super () има същите ограничения като this (): ако се използва, тогава super () трябва да бъде първият оператор в конструктор и може да се използва само в конструктор. Това води до това, че извикванията на this () и super () не могат да се появяват в един и същ конструктор. Конструкцията this () се използва за свързване на конструктори в същия клас и най-последният конструктор в тази последователност може да извика конструктора на суперклас с помощта на super (). И така, конструкцията this () води до образуването на верига от конструктори в същия клас, а super () води до обвързването на конструкторите на подкласа с конструкторите на суперкласа. Chaining гарантира, че всички конструктори на суперкласа ще бъдат извикани, като се започне с конструктора на класа, обектът на който се генерира, и по-нататък до върха на йерархията на наследяването, т.е. винаги преди клас Object. Имайте предвид, че телата на конструктора се изпълняват в обратния ред на тяхното извикване, тъй като super () може да бъде само първият израз в конструктор. Това гарантира, че първо се изпълнява конструкторът от клас Object, последван от конструкторите на други класове надолу по йерархията на наследяване до класа, от който е получен обектът. Това се нарича конструкторска верига (подклас е суперклас). Резултатът от пример 6.8 ясно демонстрира това поведение, когато се създава обект от класа TubeLight. .
Ако конструкторът в края на последователността, образувана от this () (може изобщо да няма последователност, ако this () не бъде извикан), не съдържа изрично извикване на super (), тогава извикване на super () ( без параметри) ще бъде добавено неявно за извикване на конструктора по подразбиране на суперкласа. С други думи, ако конструктор не съдържа нито this (), нито super () на първия си ред, тогава ще бъде добавено извикване на super (), което задейства конструктора по подразбиране на суперкласа. Код:
в който конструкторите по подразбиране се добавят към кода, който извиква конструктора по подразбиране на суперкласа.
Ако клас няма конструктор по подразбиране (т.е. само конструктори с параметри), тогава неговите подкласове не могат да разчитат на имплицитно извикване на super (). Това ще хвърли грешка по време на компилация. В такъв случай подкласът трябва изрично да извика конструктора на суперклас, използвайки конструкцията super () с правилните аргументи.
Предишното описание на подкласа NeonLight декларира конструктор на линия (1). Обаждането по линия (2) към конструктора на суперклас TubeLight не може да бъде пропуснато. Ако го пропуснете, добавянето на извикване super () (без параметри) към този конструктор няма да съответства на конструктора по подразбиране на суперкласа TubeLight, тъй като в суперкласа няма такъв конструктор. Суперкласът TubeLight съдържа само конструктори, които не са по подразбиране. Класът NeonLight няма да се компилира, докато извикването на super () не бъде изрично вмъкнато в ред (2) (с валидни параметри).
Ако суперкласът съдържа само конструктори, които не са по подразбиране (т.е. няма конструктор по подразбиране), това може да има нежелани последици за класа. Подклас, който очаква имплицитно да добави конструктор по подразбиране, няма да се компилира, защото се прави опит да се извика несъществуващият конструктор по подразбиране на суперкласа. Всеки конструктор по подразбиране на подклас трябва изрично да извика super (), с подходящи параметри, за да извика предварително дефиниран конструктор на суперклас, тъй като конструктор в подклас не може да разчита на неявно извикване на super (), което води до извикване на конструктора по подразбиране на суперкласа.
Извикване на конструктора super ()
Конструктът super () се използва в конструктора на подклас за извикване на конструктора на непосредствения суперклас. Това позволява на подкласа, когато неговият обект е създаден, да повлияе на инициализацията на наследственото му състояние. Извикването на super () в конструктор на подклас ще изпълни необходимия конструктор на суперклас въз основа на подпис на повикване. Тъй като името на суперкласа е известно в подкласа, извиканият конструктор на суперклас се определя от списъка с параметри на сигнатурата.
Конструктор в подклас може да се отнася директно към наследствени членове (т.е. с техните прости имена). Ключовата дума super може да се използва и в конструктора на подклас за достъп до наследени членове чрез неговия суперклас. Може да искате да използвате ключовата дума super в конструктора за инициализиране на наследени полета. Super () обаче предлага по-добро решение - използвайте конструктори на суперклас за инициализиране на наследствено състояние.
В пример 6.8 конструкторът, който не е по подразбиране от ред (3) на класа Light, извиква super () (без параметри) на линия (4). Въпреки че конструкторът не е строго необходим, тъй като компилаторът ще го добави, както е обяснено по-долу, той е включен за демонстрационни цели. Конструкторът, който не е по подразбиране от ред (6) на класа TubeLight, съдържа извикване на super () (с три параметъра) в (7). Такова повикване към super () съответства на повикване към конструктора, който не е по подразбиране на суперкласа Light от (3). Това е очевидно от резултата на програмата.