Перегруженный конструктор java. Использование аргументов командной строки. Конструкторы, параметризированные примитивами

Дело в том, что:

1. Если Вы создаете класс и в нем определяете конструктор с аргументами (класс AClass, у которого только один конструктор, который принимает int i), то компилятор уже не создаст конструктор по умолчанию. Потому что это нарушило бы контракт класса AClass, который не может быть инициализирован без аргументов. Если Вы хотите еще иметь и конструктор по умолчанию, задавайте теперь его явно.

Иначе нельзя было бы запретить создание конструктора по умолчанию, что было бы плохо.

2. При создании конструкторов класса BClass, который наследуется от другого класса, компилятор требует, чтобы первой строкой конструктора был вызов другого конструктора (унаследованного или в этом классе).

Почему? Потому что раз Вы наследуетесь от какого-то класса, Вы хотите повторно использовать его логику. Конструктор приводит экземпляр класса в какое-то начальное целостное состояние. В Вашем случае для инициализации AClass требует аргумент, без которого JVM не знает, как инициализировать экземпляр класса.

Если у класса не определены конструкторы, то он пытается создать конструктор по умолчанию, т.е. без аргументов:

Public class AClass1 { }

Поскольку здесь явно конструкторы не определены И класс не наследуется от других классов, компилятор создает конструктор по умолчанию.

Это эквивалентно такому определению:

Public class AClass1 { public AClass1() { } }

Теперь посмотрим на BClass1:

Public class BClass1 extends AClass1 { }

Здесь тоже явно конструкторы не определены, и компилятор пытается создать конструктор по умолчанию. Поскольку в классе AClass1 есть конструктор по умолчанию, он создаст конструктор по умолчанию, который будет вызывать конструктор AClass1. Этот код эквивалентен такому:

Public class BClass1 extends AClass1 { public BClass1() { super(); } }

В Вашем случае создается класс БЕЗ конструктора по умолчанию:

Public AClass { public AClass(int i) { } }

Поскольку тут описан (хотя бы один) конструктор, конструктор по умолчанию уже не создается. Т. е. такой код уже не будет компилироваться:

AClass a = new AClass(); // не работает

нужно что-то вроде

AClass a = new AClass(1);

Соответственно, любой конструктор BClass будет требовать вызова какого-либо конструктора AClass или BClass. При таком описании компилятор будет ругаться:

Public BClass extends AClass { }

Потому что будет попытка вызова конструкора по умолчанию класса AClass, который не определен:

Public BClass extends AClass { public BClass() { super(); // ошибка; в классе AClass нет такого конструктора } }

Тем не менее, можно создать класс BClass с конструктором по умолчанию, задав какое-то значение для конструктора AClass:

Public class BClass extends AClass { public BClass() { super(1); } }

Это будет компилироваться.

1. Понятие конструктора по умолчанию

Конструктор по умолчанию (default constructor) – это конструктор, который не имеет параметров. Конструктор по умолчанию может объявляться в классе явным образом или генерироваться автоматически.

В наиболее общем случае, для класса ClassName , конструктор по умолчанию имеет следующий вид:

class ClassName { ... // объявление конструктора ClassName() { // тело конструктора // ... } ... }
2. В каких случаях конструктор по умолчанию генерируется в классе автоматически а в каких нет? Пример

Если в классе не объявить ни одного конструктора, то, будет генерироваться конструктор по умолчанию. То есть, конструктор по умолчанию генерируется в классе автоматически только в том случае, если класс не содержит реализации других конструкторов. Если класс содержит реализацию хотя бы одного конструктора с параметрами, то, чтобы объявить конструктор по умолчанию, его нужно объявлять в классе явным образом.

Например. В следующем объявлении класса конструктор по умолчанию генерируется автоматически

class CMyClass { int d ; int GetD() { return d ; } void SetD(int nd) { d = nd; } }

Вышеприведенный код означает, что можно объявлять объект класса с использованием конструктора по умолчанию:

// работает, так как в классе больше не реализовано ни одного конструктора CMyClass mc = new CMyClass();

Если в тело класса CMyClass добавить хотя бы один другой конструктор (например, конструктор с одним параметром), то конструктор по умолчанию автоматически генерироваться не будет

class CMyClass { int d ; // конструктор по умолчанию уже не генерируется автоматически CMyClass(int nd) { d = nd; } int GetD() { return d ; } void Set(int nd) { d = nd; } }

После вышеприведенной реализации объявить объект с использованием конструктора по умолчанию не удастся. Однако, можно объявить объект с использованием конструктора с одним параметром

// ошибка компиляции, так как в классе уже объявлен другой конструктор // CMyClass mc = new CMyClass(); CMyClass mc2 = new CMyClass(7); // а этот код работает

В результате выполнения вышеприведенной строки будет выдана ошибка компиляции:

The constructor CMyClass() is undefined

Для того, чтобы иметь реализацию конструктора по умолчанию и объявлять объект класса с использованием конструктора по умолчанию, его нужно задавать явно. Это может быть, например, следующим образом

class CMyClass { int d ; // явное объявление конструктора по умолчанию CMyClass() { d = 0; } // объявление конструктора с 1 параметром, CMyClass(int nd) { d = nd; } int GetD() { return d ; } void Set(int nd) { d = nd; } }

После такой реализации можно создавать экземпляр класса с использованием двух конструкторов, например

CMyClass mc = new CMyClass(); // вызывается конструктор по умолчанию mc.d = 25; CMyClass mc2 = new CMyClass(5); // вызывается конструктор с 1 параметром

3. Вызов конструкторов из других конструкторов. Пример

Язык программирования Java позволяет осуществлять вызов конструкторов класса из другого конструктора этого же класса. Для этого используется ключевое слово this , которое есть ссылкой на текущий класс.

Пример. В примере демонстрируется использование класса CPixel , который реализует пиксел на экране монитора.

// Класс, который реализует пиксел на экране монитора public class CPixel { // внутренние переменные класса private int x , y ; // координаты пиксела private int color ; // цвет пиксела // конструктор без параметров (конструктор по умолчанию) CPixel() { x = y = color = 0; } // конструктор с 2 параметрами, которые инициализируют только координаты CPixel(int _x, int _y) { x = _x; y = _y; color = 0; } // конструктор с 1 параметром, который инициализирует только цвет CPixel(int _color) { color = _color; x = y = 0; } // конструктор с 3 параметрами, который вызывает конструктор с 2 параметрами CPixel (int _x, int _y, int _color) { // вызов конструктора с 2 параметрами: обязательно первая операция и только один раз this (_x, _y); //this(_color); // повторный вызов конструктора запрещен this .color = _color; // так можно } // методы доступа int GetX() { return x ; } int GetY() { return y ; } int GetColor() { return color ; } }

Использование класса CPixel в другом программном коде (методе)

CPixel cp1 = new CPixel(2,8); // вызов конструктора с 2 параметрами CPixel cp2 = new CPixel(3,5,8); // вызов конструктора, который вызовет другой конструктор int d; d = cp1.GetX(); // d = 2 d = cp2.GetColor(); // d = 8 d = cp2.GetY(); // d = 5 ...

4. Какие ограничения (требования) накладываются на вызов других конструкторов из конструктора класса?

Чтобы корректно вызвать другие конструкторы из конструктора класса, нужно придерживаться следующих требований (ограничений):

  • вызвать можно только один другой конструктор класса. Вызвать два и больше других конструктора этого класса запрещено. Это вытекает из логики, что конструктор класса предназначен для создания объекта класса только один раз (а не два и больше раза);
  • вызов другого конструктора должен быть первой операцией в вызывающем конструкторе. Если в вызывающем конструкторе вызов другого конструктора реализовать второй (третьей и т.д.) операцией, то компилятор выдаст ошибку.

Привет! Сегодня мы разберем очень важную тему, которая касается наших объектов. Тут без преувеличения можно сказать, что этими знаниями ты будешь пользоваться каждый день в реальной работе! Мы поговорим о конструкторах .

Ты, возможно, слышишь этот термин впервые, но на самом деле наверняка пользовался конструкторами, только сам не замечал этого:) Мы убедимся в этом позже.

Что такое конструкторы и зачем они нужны?

Рассмотрим два примера. 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 явно будет не 2 поля. А, например, 16 полей! public class Car { String model; //модель int maxSpeed; //максимальная скорость //объем двигателя //фамилия владельца //число мест в салоне String salonMaterial; //материал салона boolean insurance; //застрахована ли //страна-производитель int trunkVolume; //объем багажника int accelerationTo100km; 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 ! Попробуй сейчас по коду найти те, которые мы забыли! Не так-то просто, да? В такой ситуации программист может легко ошибиться и пропустить инициализацию какого-то поля. В итоге поведение программы станет ошибочным: public class Car { String model; //модель int maxSpeed; //максимальная скорость int wheels; //ширина дисков double engineVolume; //объем двигателя String color; //цвет int yearOfIssue; //год выпуска String ownerFirstName; //имя владельца String ownerLastName; //фамилия владельца long price; //цена boolean isNew; //новая или нет int placesInTheSalon; //число мест в салоне String salonMaterial; //материал салона boolean insurance; //застрахована ли String manufacturerCountry; //страна-производитель int trunkVolume; //объем багажника int accelerationTo100km; //разгон до 100 км/час в секундах 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 ("Модель Bugatti Veyron. Объем двигателя - " + bugatti. engineVolume + ", багажника - " + bugatti. trunkVolume + ", салон сделан из " + bugatti. salonMaterial + ", ширина дисков - " + bugatti. wheels + ". Была приоберетена в 2018 году господином " + bugatti. ownerLastName) ; } } Вывод в консоль: Модель Bugatti Veyron. Объем двигателя - 6.3, багажника - 0, салон сделан из null, ширина дисков - 0. Была приобретена в 2018 году господином null Вашему покупателю, отдавшему 2 миллиона долларов за машину, явно не понравится, что его назвали “господином null ”! А если серьезно, в итоге в нашей программе оказался некорректно созданный объект - машина с шириной дисков 0 (то есть вообще без дисков), отсутствующим багажником, салоном, сделанным из неизвестного материала, да еще и принадлежащая непонятно кому. Можно только представить, как такая ошибка может “выстрелить” при работе программы! Нам нужно как-то избежать подобных ситуаций. Надо, чтобы в нашей программе было ограничение: при создании нового объекта машины для него всегда должны быть указаны, например, модель и максимальная скорость. Иначе - не позволять создание объекта. С этой задачей легко справляются функции-конструкторы . Они получили свое название не просто так. Конструктор создает своеобразный “каркас” класса, которому каждый новый объект класса должен соответствовать. Давай для удобства вернемся к более простому варианту класса Car с двумя полями. С учетом наших требований, конструктор для класса 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 ) ; } Обрати внимание, как создается конструктор . Он похож на обычный метод, но у него нет типа возвращаемого значения. При этом в конструкторе указывается название класса, тоже с большой буквы. В нашем случае - Car . Кроме того, в конструкторе используется новое для тебя ключевое слово this . "this" по-английски - "этот, этого". Это слово указывает на конкретный предмет. Код в конструкторе: public Car (String model, int maxSpeed) { this . model = model; this . maxSpeed = maxSpeed; } можно перевести почти дословно: " model для этой машины (которую мы сейчас создаем) = аргументу model , который указан в конструкторе. 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 () ; //ошибка! } } Видишь, конструктор сделал то, чего мы пытались добиться. Теперь нельзя создать машину без скорости или без модели! На этом сходство конструкторов и методов не заканчивается. Так же, как и методы, конструкторы можно перегружать . Представь, что у тебя дома живут 2 кота. Одного из них ты взял еще котенком, а второго ты принес домой с улицы уже взрослым и не знаешь точно, сколько ему лет. Значит, наша программа должна уметь создавать котов двух видов - с именем и возрастом для первого кота, и только с именем - для второго кота. Для этого мы перегрузим конструктор: public class Cat { String name; int age; //для первого кота //для второго кота public Cat (String name) { this . name = name; } public static void main (String args) { Cat barsik = new Cat ("Barsik" , 5 ) ; Cat streetCatNamedBob = new Cat ("Bob" ) ; } } К изначальному конструктору с параметрами “имя” и “возраст” мы добавили еще один, только с именем. Точно так же мы перегружали методы в прошлых уроках. Теперь мы успешно можем создать оба варианта котов:)

Помнишь, в начале лекции мы говорили, что ты уже пользовался конструкторами, только сам не замечал этого? Так и есть. Дело в том, что у каждого класса в Java есть так называемый конструктор по умолчанию . У него нет никаких аргументов, но он срабатывает каждый раз при создании любого объекта любого класса. public class Cat { public static void main (String args) { Cat barsik = new Cat () ; } } На первый взгляд это незаметно. Ну создали объект и создали, где тут работа конструктора? Чтобы это увидеть, давай прямо руками напишем для класса Cat пустой конструктор, а внутри него выведем какую-нибудь фразу в консоль. Если она выведется, значит конструктор отработал. public class Cat { public Cat () { System. out. println ("Создали кота!" ) ; } public static void main (String args) { Cat barsik = new Cat () ; //вот здесь сработал конструктор по умолчанию } } Вывод в консоль: Создали кота! Вот и подтверждение! Конструктор по умолчанию всегда незримо присутствует в твоих классах. Но тебе нужно знать еще одну его особенность. Дефолтный конструктор исчезает из класса, когда ты создаешь какой-то конструктор с аргументами. Доказательство этого, на самом деле, мы уже видели выше. Вот в этом коде: 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 () ; //ошибка! } } Мы не смогли создать кота без имени и возраста, потому что определили конструктор для Cat: строка + число . Дефолтный конструктор сразу после этого исчез из класса. Поэтому обязательно запомни: если тебе в твоем классе нужно несколько конструкторов, включая пустой, его нужно создать отдельно . Например, мы создаем программу для ветеринарной клиники. Наша клиника хочет делать добрые дела и помогать бездомным котикам, про которых мы не знаем ни имени, ни возраста. Тогда наш код должен выглядеть так: public class Cat { String name; int age; //для домашних котов public Cat (String name, int age) { this . name = name; this . age = age; } //для уличных котов 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 ("Барсик" , 10 ) ; //ошибка! } } Ошибка! Конструктор четко описывает: при создании объекта Cat ему должны быть переданы число и строка, именно в таком порядке . Поэтому наш код не срабатывает. Обязательно запомни это и учитывай при создании своих собственных классов: public Cat (String name, int age) { this . name = name; this . age = age; } public Cat (int age, String name) { this . age = age; this . name = name; } Это два абсолютно разных конструктора! Если выразить в одном предложении ответ на вопрос “Зачем нужен конструктор?” , можно сказать: для того, чтобы объекты всегда находились в правильном состоянии . Когда ты используешь конструкторы, все твои переменные будут корректно проинициализированы, и в программе не будет машин со скоростью 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 ( "Она была основана " "В среднем она производит " + (this . carsCount/ this . age) + " машин в год" ) ; } public static void main (String args) { CarFactory ford = new CarFactory ("Ford" , 115 , 50000000 ) ; } } У нас есть класс CarFactory , описывающий фабрику по производству автомобилей. Внутри конструктора мы инициализируем все поля, и сюда же помещаем логику: выводим в консоль некоторую информацию о фабрике. Казалось бы - ничего плохого в этом нет, программа прекрасно отработала. Вывод в консоль: Наша автомобильная фабрика называется Ford Она была основана 115 лет назад За это время на ней было произведено 50000000 автомобилей В среднем она производит 434782 машин в год Но на самом деле мы заложили мину замедленного действия. И подобный код может очень легко привести к ошибкам. Представим себе, что теперь мы говорим что не о Ford, а о новой фабрике "Amigo Motors", которая существует меньше года и произвела 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 ("Наша автомобильная фабрика называется " + this . name) ; System. out. println ("Она была основана " + this . age + " лет назад" ) ; System. out. println ("За это время на ней было произведено " + this . carsCount + " автомобилей" ) ; System. out. println ("В среднем она производит " + (this . carsCount/ this . age) + " машин в год" ) ; } public static void main (String args) { CarFactory ford = new CarFactory ("Amigo Motors" , 0 , 1000 ) ; } } Вывод в консоль: Наша автомобильная фабрика называется Amigo Motors Exception in thread "main" java.lang.ArithmeticException: / by zero Она была основана 0 лет назад За это время на ней было произведено 1000 автомобилей at CarFactory. (CarFactory.java:15) at CarFactory.main(CarFactory.java:23) Process finished with exit code 1 Приехали! Программа завершилась с какой-то непонятной ошибкой. Попробуешь догадаться, в чем причина? Причина - в логике, которую мы поместили в конструктор. А конкретно - вот в этой строке: System. out. println ("В среднем она производит " + (this . carsCount/ this . age) + " машин в год" ) ; Здесь мы выполняем вычисление и делим количество произведенных машин на возраст фабрики. А поскольку наша фабрика новая (то есть ей 0 лет) - в результате получается деление на 0, которое в математике запрещено. В результате программа завершается с ошибкой. Как же нам стоило поступить? Вынести всю логику в отдельный метод и назвать его, например, printFactoryInfo() . В качестве параметра ему можно передать объект CarFactory . Туда же можно поместить всю логику, и заодно - обработку возможных ошибок, наподобие нашей с нулем лет. Каждому свое. Конструкторы нужны для корректного задания состояния объекта. Для бизнес-логики у нас есть методы. Не стоит смешивать одно с другим. Вот несколько полезных ссылок, где ты можешь дополнительно почитать о конструкторах:

Как известно, объект является экземпляром определенного класса. Для его создания используется ключевое слово new, например:
Person student = new Person(“Mike”)
Этим кодом создается новый объект Person и указывается его имя – Mike . Строка «Mike » передается аргументом соответствующему конструктору Person :

Person(String name) { this.name = name; }

Этот конструктор позволяет указать имя человека при создании объекта.

Конструктор всегда вызывается, когда создается новый экземпляр класса. Другими словами, конструкторы используются для инициализации состояния объекта при создании объекта. Конструкторы выглядят как обычные методы, но это далеко не так:

  • Конструкторы имеют то же имя, что и имя класса.
  • Конструкторы, как и методы, имеют список принимаемых параметров, но не имеют возвращаемый тип (даже void).

Ниже представлен набор из 7 основных правил работы с конструкторами , позволяющие полностью разобраться в их работе.

  1. Конструкторы можно перегружать :

Это означает, что класс может иметь множество различных конструкторов, если их списки параметров различны. Например:

Class Rectangle { int width; int height; Rectangle() { width = 1; height = 1; } Rectangle(int width) { this. width = width; this. height = width; } Rectangle(int width, int height) { this. width = width; this. height = height; } }

Имея три различных конструктора Rectangle можно создавать новый объект тремя различными способами:

Rectangle rect1 = new Rectangle(); Rectangle rect2 = new Rectangle(10); Rectangle rect3 = new Rectangle(10,20);

  1. Конструктор по умолчанию :

Объявление конструкторов вовсе не обязательно. В случае если не определен ни один из конструкторов, то компилятор Java автоматически генерирует конструктор по умолчанию, который пуст и не имеет параметров.

Например, если мы напишем класс Rectangle следующим образом:

Class Rectangle { int widh, height; int area() { } int perimeter() { } }

То компилятор автоматически вставляет конструктор по умолчанию: ectangle() { }

  1. Компилятор не будет генерировать конструктор по умолчанию, если в классе уже есть конструктор:

Рассмотрим следующий пример:

Class Rectangle { int width; int height; Rectangle(int width) { this. width = width; this. height = width; } Rectangle(int width, int height) { this. width = width; this. height = height; } }

При попытке создать новый объект: Rectangle rect1 = new Rectangle(); Компилятор выдаст ошибку, потому что не может найти конструктор без аргументов.

  1. Конструкторы не наследуются:

В отличие от методов, конструкторы не наследуются. Пример:

Class Rectangle { Rectangle(int width, int height) { } } class Square extends Rectangle { }

Нельзя сделать что-то вроде этого: Square box = new Square(10, 10);

  1. Конструкторы могут быть приватными!

Можно сделать конструктор приватным, чтобы не дать внешнему коду создать новый экземпляр класса. В чем же может быть преимущество приватного конструктора?

В шаблоне проектирования, называемом Singleton , приватный конструктор используется, чтобы гарантировать, что всегда существует только один экземпляр класса. Класс Singleton предоставляет статический метод для получения этого уникального экземпляра.

  1. Конструктор по умолчанию имеет тот же модификатор доступа, что и класс:

При написании следующего класса: public class Person { }

Компилятор при вставке конструктора по умолчанию, укажет и необходимый модификатор доступа: public Preson();

  1. Первой строкой любого конструктора должен вызываться либо перегруженный конструктор того же класса или конструктор его суперкласса:

Если это не так, то компилятор автоматически допишет вызов конструктора суперкласса без аргументов super(); Это может привести к ошибке, поскольку такого конструктора может не быть в суперклассе. Пример:

Class Parent { Parent(int number) { } } class Child extends Parent { Child() { } }

Приведет к ошибке, потому что компилятор вставляет вызов super () в конструкторе класса Child :

Child() { super();// дописал компилятор }

Однако компилятор не будет вставлять конструктор по умолчанию для класса Parent , т.к. уже есть другие конструкторы.

Конструктор – это метод, который автоматически вызывается при создании объекта класса и выполняет действия по инициализации объекта. Конструктор имеет то же имя, что и класс; вызывается не по имени, а только вместе с ключевым словом new при создании экземпляра класса. Конструктор не возвращает значение, но может иметь параметры и быть перегружаемым.

Деструкторы в языке Java не используются, объекты уничтожаются сборщиком мусора после прекращения их использования (потери ссылки). Аналогом деструктора является метод finalize() . Исполняющая среда языка Java будет вызывать его каждый раз, когда сборщик мусора будет уничтожать объект класса, которому не соответствует ни одна ссылка.

/* пример # 2: перегрузка конструктора: Quest .java */

package chapt03;

public class Quest {

private int id;

private String text;

// конструктор без параметров (по умолчанию)

public Quest() {

super ();/* если класс будет объявлен без конструктора, то

компилятор предоставит его именно в таком виде*/

// конструктор с параметрами

public Quest(int idc, String txt) {

super ();/ *вызов конструктора суперкласса явным образом

необязателен, компилятор вставит его автоматически*/

Объект класса Quest может быть создан двумя способами, вызывающими один из конструкторов:

Quest a = new Quest (); //инициализация полей значениями по умолчанию

Quest b = new Quest (71, "Сколько бит занимает boolean ?");

Оператор new вызывает конструктор, поэтому в круглых скобках могут стоять аргументы, передаваемые конструктору.

Если конструктор в классе не определен, Java предоставляет конструктор по умолчанию без параметров, который инициализирует поля класса значениями по умолчанию, например: 0 , false , null . Если же конструктор с параметрами определен, то конструктор по умолчанию становится недоступным и для его вызова необходимо явное объявление такого конструктора. Конструктор подкласса всегда вызывает конструктор суперкласса. Этот вызов может быть явным или неявным и всегда располагается в первой строке кода конструктора. Если конструктору суперкласса нужно передать параметры, то необходим явный вызов:

super (параметры);

В следующем примере объявлен класс Point c двумя полями (атрибутами), конструктором и методами для инициализации и извлечения значений атрибутов.

/* пример # 3: вычисление расстояния между точками: Point .java: Loca te Logic .java: Runner .java */

package chapt03;

public class Point {

/* объект инициализируется при создании и не изменяется */

private final double x;

private final double y;

public Point(final double xx, final double yy) {

super ();

public double getX() {

return x;

public double getY() {

return y;

package chapt03;

public class LocateLogic {

public double calculateDistance(

Point t1, Point t2) {

/* вычисление расстояния */

double dx = t1.getX() – t2.getX();

double dy = t1.getY() – t2.getY();

return Math.hypot (dx, dy);

package chapt03;

public class Runner {

public static void main(String args) {

// локальные переменные не являются членами класса

Point t1 = new Point(5, 10);

Point t2 = new Point(2, 6);

System.out .print("расстояние равно: "

+ new LocateLogic().calculateDistance(t1, t2));

В результате будет выведено:

расстояние равно: 5.0

Конструктор объявляется со спецификатором public , чтобы была возможность вызывать его при создании объекта в любом пакете приложения. Спецификатор private не позволяет создавать объекты вне класса, а спецификатор «по умолчанию» – вне пакета. Спецификатор protected позволяет создавать объекты в текущем пакете и для подклассов в других пакетах.

  • Сергей Савенков

    какой то “куцый” обзор… как будто спешили куда то