С Новым годом! Форум программистов, компьютерный форум, киберфорум
Java
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/30: Рейтинг темы: голосов - 30, средняя оценка - 4.83
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335

Можно ли сделать обязательным вызов конструктора базового класса?

18.08.2013, 21:31. Показов 6009. Ответов 19
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Собственно, вопрос в названии. Хотелось бы, чтобы в конструктор наследника выдавал ошибку, если не вызван какой-либо из конструкторов базового класса.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
18.08.2013, 21:31
Ответы с готовыми решениями:

Вызов конструктора базового класса
Здравствуйте! Я вот начал изучать C# и немножечко освежил ООП. Но вот у меня вопрос. Я точно помню, что класс-наследник (конструкторы не...

Вызов конструктора абстрактного базового класса
Здравствуйте, в классе вызываю с помощью super() конструктор абстрактного базового класса -...

Вызов конструктора базового класса из порожденного
Есть Базовый класс студент: имеет поля: фамилия, адрес, тел., возраст. Порожденный класс группа: имя группы, кол-во студентов в...

19
38 / 38 / 10
Регистрация: 04.02.2013
Сообщений: 106
18.08.2013, 21:37
Цитата Сообщение от nexen Посмотреть сообщение
Собственно, вопрос в названии. Хотелось бы, чтобы в конструктор наследника выдавал ошибку, если не вызван какой-либо из конструкторов базового класса.
Если меня память не подводит, то вызов конструктора базового класса происходит всегда при создании класса-наследника. Причем в случае, если явно не указан вызов конструктора базового класса с помощью super(), вызывается конструктор базового класса без аргументов. Если же такого конструктора в базовом классе нет - получаем ошибку.
1
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
18.08.2013, 21:46
Цитата Сообщение от nexen Посмотреть сообщение
Собственно, вопрос в названии. Хотелось бы, чтобы в конструктор наследника выдавал ошибку, если не вызван какой-либо из конструкторов базового класса.
По умолчанию вызывается дефолтный конструктор базового класса. Если такого нету то нужно определить явно конструктор в дочернем классе , который будет инициализировать поля базового объекта.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
18.08.2013, 21:59  [ТС]
Divizal, Care, а если я не создаю конструктор по умолчанию класса наследника, могу ли я быть уверен, что вызовуться созданные компилятором дефолтные конструкторы и, таким образом, поля, которые я указывал как: public int x = 10 или public myClass a = new myClass() приобретут указанные значения?
0
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
18.08.2013, 22:14
Цитата Сообщение от nexen Посмотреть сообщение
public int x = 10 или public myClass a = new myClass()
Если ты инициализируешь поля в не конструктора,то компилятор автоматически перенесет эту инициализацию в конструктор.
то есть такая инициализация как у вас будет произведена в конструкторе.
1
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
18.08.2013, 22:37  [ТС]
Care, во всех конструкторах, кроме тех, где я это явно прописываю?
Или тут будет дважды выделена память?
Java
1
2
3
4
5
6
7
8
9
public class MyClass
{
public OtherMyClass x = OtherMyClass(10);
 
public MyClass(int number)
{
x = new OtherMyClass(number);
}
}
0
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
18.08.2013, 22:52
Цитата Сообщение от nexen Посмотреть сообщение
Care, во всех конструкторах, кроме тех, где я это явно прописываю?
Или тут будет дважды выделена память?
Java
1
2
3
4
5
6
7
8
9
public class MyClass
{
public OtherMyClass x = OtherMyClass(10);
 
public MyClass(int number)
{
x = new OtherMyClass(number);
}
}
Тут вы просто два раза инициализируете объект. Сначало public OtherMyClass x = OtherMyClass(10); затем x = new OtherMyClass(number);
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
18.08.2013, 23:33
Цитата Сообщение от Care Посмотреть сообщение
Если ты инициализируешь поля в не конструктора,то компилятор автоматически перенесет эту инициализацию в конструктор.
то есть такая инициализация как у вас будет произведена в конструкторе.
вы меня поражаете своими постами )
запустите ка вот этот код
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @author mutagen
 */
public class InitSequence {
 
    int a = 1;
 
    public InitSequence() {
        System.out.println(a);
        a = 2;
        System.out.println(a);
    }
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new InitSequence();
    }
}
1
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
18.08.2013, 23:39
Цитата Сообщение от mutagen Посмотреть сообщение
вы меня поражаете своими постами )
запустите ка вот этот код
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
 * @author mutagen
 */
public class InitSequence {
 
    int a = 1;
 
    public InitSequence() {
        System.out.println(a);
        a = 2;
        System.out.println(a);
    }
 
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        new InitSequence();
    }
}
да.... забыл ошибся и тд. Молодец )
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
18.08.2013, 23:47
Цитата Сообщение от Care Посмотреть сообщение
Молодец )
Если уж помогать, хорошо бы для начала самому разобраться.

Не по теме:

Обычно я благодарен когда мне указывают на мою ошибку, это облегчает мне жизнь в будущем.
Вот тут есть яркий пример форумчанина - Севак, человек на моих глазах за год из новичка путём проб и ошибок стал прилично разбираться в java. Почитайте его посты на досуге, если конечно вас волнует результат.

1
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
19.08.2013, 00:05
Цитата Сообщение от mutagen Посмотреть сообщение
Если уж помогать, хорошо бы для начала самому разобраться.

Не по теме:

Обычно я благодарен когда мне указывают на мою ошибку, это облегчает мне жизнь в будущем.
Вот тут есть яркий пример форумчанина - Севак, человек на моих глазах за год из новичка путём проб и ошибок стал прилично разбираться в java. Почитайте его посты на досуге, если конечно вас волнует результат.

Вот вы интриган емаё))
0
38 / 38 / 10
Регистрация: 04.02.2013
Сообщений: 106
19.08.2013, 00:21
nexen, если вы переживаете по поводу того, что у объекта будут не инициализированные переменные, то советую внимательно прочитать вот эту статью: http://www.quizful.net/post/ja... ialization Прочитав ее вы будете лучше разбираться в порядке инициализации, в частности:

  1. инициализация полей в месте объявления и в инициализационном блоке происходит до инициализации в конструкторе
  2. инициализации полей в месте объявления и в инициализационных блоках выполняются в порядке их объявления в классе
  3. инициализация полей базового класса происходит полностью до инициализации производного класса, т.е. сначала выполняются все инициализаторы базового класса, а потом все инициализаторы производного класса.
Что касается вызовов конструкторов базового класса. Пусть у нас есть два класса:
Java
1
2
3
4
5
6
7
public class Parent {
   Parent(){}
}
 
class Child extends Parent {
   Child(){}
}
Так вот, когда мы напишем:
Java
1
Child child = new Child();
то в стеке будет такая вот картина:

1. Child() вызовет super() //<- даже если это слово явно не указано в конструкторе, оно все-равно присутствует в самом начале!
2. Parent() вызовет super()
3. Object() //<- так как все объекты наследуются от этого класса.

Таким образом, у вас при создании любого объекта выполняется подобного вида цепочка вызовов. Единственное тут стоит учесть вот что: пусть у вас есть класс:
Java
1
2
3
public class Parent {
   Parent (int x) {}
}
Так вот - у этого класса нет конструктора без параметров. И поэтому в конструкторе класса-наследника необходимо явно вызывать super (5), например. Без этого получите ошибку компиляции, если не ошибаюсь (тут поправьте мну если я не прав).
2
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
19.08.2013, 12:47
Цитата Сообщение от nexen Посмотреть сообщение
Divizal, Care, а если я не создаю конструктор по умолчанию класса наследника, могу ли я быть уверен, что вызовуться созданные компилятором дефолтные конструкторы и, таким образом, поля, которые я указывал как: public int x = 10 или public myClass a = new myClass() приобретут указанные значения?
Поля приобретут значения вне зависимости от вызова констркутора. Инициализация происходит ДО вызова конструктора. Другое дело, что как только Вы объявили хоть один конструктор - никаких конструкторов по умолчанию компилятор уже не создает. И если Вы где-то в наследниках на это полагаетесь - Вы получите ошибку компиляции. Конструктор с параметрами придется указывать в явном виде - super(...)
1
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
19.08.2013, 20:20
Цитата Сообщение от Skipy Посмотреть сообщение
Инициализация происходит ДО вызова конструктора.
Что выведет код?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class B {
    int x = 1;
 
    public B() {
        printx();
    }
 
    void printx(){
        System.out.print(x);
    }
}
 
public class A extends B {
    int x = 2;
 
    void printx(){
        System.out.print(x);
    }
 
    public static void main(String[] ars){
        new A();
    }
}
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
19.08.2013, 20:34
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от efwe Посмотреть сообщение
Что выведет код?
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class B {
    int x = 1;
 
    public B() {
        printx();
    }
 
    void printx(){
        System.out.print(x);
    }
}
 
public class A extends B {
    int x = 2;
 
    void printx(){
        System.out.print(x);
    }
 
    public static void main(String[] ars){
        new A();
    }
}
выведет 0 - обьясняю почему,

вы создаёте обьект класса А, значит и проперти х будет его, но перед созданием вы вызываете конструктор парент класса а у того есть метод в конструкторе выводящий проперти х, но так как конструктор парента ещё не завершился, то наше локальное х пока ещё инициализированно по дефолту нулём как примитив. вот когда парент завершился, вот тогда будет инициализировано проперти х и станет 2
слегка модифицируем класс А и всё становится понятно
Java
1
2
3
4
public A() {
            super();
            printx();
        }
и завершится инициализация 2-кой ДО окончания конструктора А

в JVM есть приоритет запуска методов, так вот вызов парент конструктора это invokespecial (максимальный приоритет), для того чтобы произвести инициализацию иерархии наследования, а уже потом повалят invokestatic и invokevirtual, ваш вопрос не опровергает Skipy, так как вы использовали чит наследования, в общих случаях инициализация поля именно ДО конструктора )
3
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
20.08.2013, 11:33
Я не сомневался что Skipy ответит правильно, но всеже инициализация работает не ДО вызова конструктора а после вызова родительского конструктора (если считать что вызов родительского конструктора идет внутри конструктора потомка, как например в вашем примере конструктора класса А).
0
 Аватар для Skipy
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
20.08.2013, 12:33
Цитата Сообщение от efwe Посмотреть сообщение
Я не сомневался что Skipy ответит правильно, но всеже инициализация работает не ДО вызова конструктора а после вызова родительского конструктора
Инициализация полей класса идет ДО вызова конструктора ЭТОГО класса. Так понятнее? Соответственно, при иерархии Object -> A -> B имеем последовательность: поля Object, конструктор Object, поля А, конструктор А, поля В, конструктор В.

(если считать что вызов родительского конструктора идет внутри конструктора потомка, как например в вашем примере конструктора класса А).
Он не может идти никак иначе. Вызов родительского конструктора осуществляется только в дочерних конструкторах и всегда первой инструкцией.
1
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
20.08.2013, 12:39
Цитата Сообщение от efwe Посмотреть сообщение
но всеже инициализация работает не ДО вызова конструктора а после вызова родительского конструктора (если считать что вызов родительского конструктора идет внутри конструктора потомка, как например в вашем примере конструктора класса А).
я же вроде написал приоритетность разных типов вызовов, ок видимо непонятно, попробуем по другому.

итак как же происходит инициализация:
1. конструктор неявно или явно вызывает super() (в том числе и с параметрами) - этот вызов выполняется как invokespecial так как он нужен для того чтобы пройти по иерархии наследования и выполнить линковку текущего класса с методами парентов и абстрактов находящихся над ним.
2. эта линковка продолжается до класса Object и при спуске вниз выполняется оверрид методов и перелинковка
3. для того чтобы начать спуск вниз должно быть выполнено одно условие - должен завершиться парент конструктор.
4. в случае если в иерархии внутри конструктора производится вызов какого либо метода он будет выполнен
5. проперти с одинаковыми именами затеняют паренты если не указывать модификатор super.propertyName
6. любой метод из парента пытающийся получить значение затенённого проперти - получит значение заттеняющего из самого нижнего.
7. до момента завершения конструктора парента собственные проперти инициализированы дефолтным значением в случае примитивов и null в случае объектов.
8. после завершения конструирования иерархии и линковки класс инициализирует собственные проперти
9. выполняются инструкции в конструкторе и конструктор завершается
10. класс находится в консистент стейте и готов к работе

Для более глубокого понимания приколов связанных с приоритетами рекомендую почитать про утечки this в конструкторе, типа такого:
Java
1
2
3
4
Object o = new Object();
public A() {
   super(this.o.toString());
}
1
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
20.08.2013, 12:54
Цитата Сообщение от mutagen Посмотреть сообщение
Для более глубокого понимания приколов связанных с приоритетами рекомендую почитать про утечки this в конструкторе
А не порекомендуете что почитать про то что происходит внутри jvm, про всякие invoke* и тд?
0
 Аватар для mutagen
2587 / 2260 / 257
Регистрация: 14.09.2011
Сообщений: 5,185
Записей в блоге: 18
20.08.2013, 13:01
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от efwe Посмотреть сообщение
А не порекомендуете что почитать про то что происходит внутри jvm, про всякие invoke* и тд?
http://zeroturnaround.com/rebe... ethods/#!/
http://docs.oracle.com/javase/... e.doc.html
http://www.javaworld.com/colum... index.html
http://www.artima.com/underthehood/
http://www.oracle.com/technetw... anceTuning
http://www.oracle.com/technetw... 40523.html
http://www.ibm.com/developerwo... ory-linux/
3
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.08.2013, 13:01
Помогаю со студенческими работами здесь

Вызов конструктора базового класса из класса-наследника
Можно ли вне списка инициализации вызвать конструктор базового класса ? class A { int a; public: A(int c):a(c){} ...

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

Знакомство с наследованием. Вызов конструктора базового класса
В инете немного почиатл про наследование и решил сразу перейти к практике Есть два класа point и apoint вот хидер #ifndef...

Вызов базового конструктора
Такая вот ситуация. Думаю, проблема в объявлении и инициализации массива m. Я бы инициализировал уже в конструкторе, но сначала вызовет...

Вызвать конструктор производного класса без конструктора базового класса
Здравствуйте! У меня есть базовый класс треугольник и производный класс равносторонний треугольник.В конструкторе треугольника вводятся...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит токи на L и напряжения на C в установ. режимах до и. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru