187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|
1 | |
Можно ли сделать обязательным вызов конструктора базового класса?18.08.2013, 21:31. Показов 5629. Ответов 19
Метки нет (Все метки)
Собственно, вопрос в названии. Хотелось бы, чтобы в конструктор наследника выдавал ошибку, если не вызван какой-либо из конструкторов базового класса.
0
|
18.08.2013, 21:31 | |
Ответы с готовыми решениями:
19
Вызов конструктора базового класса Вызов конструктора абстрактного базового класса Вызов конструктора базового класса из порожденного Вызов конструктора базового класса из класса-наследника |
38 / 38 / 10
Регистрация: 04.02.2013
Сообщений: 106
|
|
18.08.2013, 21:37 | 2 |
Если меня память не подводит, то вызов конструктора базового класса происходит всегда при создании класса-наследника. Причем в случае, если явно не указан вызов конструктора базового класса с помощью super(), вызывается конструктор базового класса без аргументов. Если же такого конструктора в базовом классе нет - получаем ошибку.
1
|
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
|
|
18.08.2013, 21:46 | 3 |
По умолчанию вызывается дефолтный конструктор базового класса. Если такого нету то нужно определить явно конструктор в дочернем классе , который будет инициализировать поля базового объекта.
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
|
18.08.2013, 21:59 [ТС] | 4 |
Divizal, Care, а если я не создаю конструктор по умолчанию класса наследника, могу ли я быть уверен, что вызовуться созданные компилятором дефолтные конструкторы и, таким образом, поля, которые я указывал как: public int x = 10 или public myClass a = new myClass() приобретут указанные значения?
0
|
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
|
|
18.08.2013, 22:14 | 5 |
Если ты инициализируешь поля в не конструктора,то компилятор автоматически перенесет эту инициализацию в конструктор.
то есть такая инициализация как у вас будет произведена в конструкторе.
1
|
187 / 180 / 25
Регистрация: 27.01.2012
Сообщений: 1,335
|
||||||
18.08.2013, 22:37 [ТС] | 6 | |||||
Care, во всех конструкторах, кроме тех, где я это явно прописываю?
Или тут будет дважды выделена память?
0
|
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
|
|
18.08.2013, 22:52 | 7 |
Тут вы просто два раза инициализируете объект. Сначало public OtherMyClass x = OtherMyClass(10); затем x = new OtherMyClass(number);
0
|
18.08.2013, 23:33 | 8 | |||||
вы меня поражаете своими постами )
запустите ка вот этот код
1
|
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
|
|
18.08.2013, 23:39 | 9 |
0
|
18.08.2013, 23:47 | 10 |
Если уж помогать, хорошо бы для начала самому разобраться.
Не по теме: Обычно я благодарен когда мне указывают на мою ошибку, это облегчает мне жизнь в будущем.
1
|
77 / 33 / 9
Регистрация: 04.06.2013
Сообщений: 295
|
|
19.08.2013, 00:05 | 11 |
0
|
38 / 38 / 10
Регистрация: 04.02.2013
Сообщений: 106
|
||||||||||||||||
19.08.2013, 00:21 | 12 | |||||||||||||||
nexen, если вы переживаете по поводу того, что у объекта будут не инициализированные переменные, то советую внимательно прочитать вот эту статью: http://www.quizful.net/post/ja... ialization Прочитав ее вы будете лучше разбираться в порядке инициализации, в частности:
1. Child() вызовет super() //<- даже если это слово явно не указано в конструкторе, оно все-равно присутствует в самом начале! 2. Parent() вызовет super() 3. Object() //<- так как все объекты наследуются от этого класса. Таким образом, у вас при создании любого объекта выполняется подобного вида цепочка вызовов. Единственное тут стоит учесть вот что: пусть у вас есть класс:
2
|
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
|
|
19.08.2013, 12:47 | 13 |
Поля приобретут значения вне зависимости от вызова констркутора. Инициализация происходит ДО вызова конструктора. Другое дело, что как только Вы объявили хоть один конструктор - никаких конструкторов по умолчанию компилятор уже не создает. И если Вы где-то в наследниках на это полагаетесь - Вы получите ошибку компиляции. Конструктор с параметрами придется указывать в явном виде - super(...)
1
|
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
|
||||||
19.08.2013, 20:20 | 14 | |||||
Что выведет код?
0
|
19.08.2013, 20:34 | 15 | |||||
Сообщение было отмечено как решение
Решение
выведет 0 - обьясняю почему,
вы создаёте обьект класса А, значит и проперти х будет его, но перед созданием вы вызываете конструктор парент класса а у того есть метод в конструкторе выводящий проперти х, но так как конструктор парента ещё не завершился, то наше локальное х пока ещё инициализированно по дефолту нулём как примитив. вот когда парент завершился, вот тогда будет инициализировано проперти х и станет 2 слегка модифицируем класс А и всё становится понятно
в JVM есть приоритет запуска методов, так вот вызов парент конструктора это invokespecial (максимальный приоритет), для того чтобы произвести инициализацию иерархии наследования, а уже потом повалят invokestatic и invokevirtual, ваш вопрос не опровергает Skipy, так как вы использовали чит наследования, в общих случаях инициализация поля именно ДО конструктора )
3
|
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
|
|
20.08.2013, 11:33 | 16 |
Я не сомневался что Skipy ответит правильно, но всеже инициализация работает не ДО вызова конструктора а после вызова родительского конструктора (если считать что вызов родительского конструктора идет внутри конструктора потомка, как например в вашем примере конструктора класса А).
0
|
2000 / 1427 / 92
Регистрация: 25.11.2010
Сообщений: 3,611
|
|
20.08.2013, 12:33 | 17 |
Инициализация полей класса идет ДО вызова конструктора ЭТОГО класса. Так понятнее? Соответственно, при иерархии Object -> A -> B имеем последовательность: поля Object, конструктор Object, поля А, конструктор А, поля В, конструктор В.
1
|
20.08.2013, 12:39 | 18 | |||||
я же вроде написал приоритетность разных типов вызовов, ок видимо непонятно, попробуем по другому.
итак как же происходит инициализация: 1. конструктор неявно или явно вызывает super() (в том числе и с параметрами) - этот вызов выполняется как invokespecial так как он нужен для того чтобы пройти по иерархии наследования и выполнить линковку текущего класса с методами парентов и абстрактов находящихся над ним. 2. эта линковка продолжается до класса Object и при спуске вниз выполняется оверрид методов и перелинковка 3. для того чтобы начать спуск вниз должно быть выполнено одно условие - должен завершиться парент конструктор. 4. в случае если в иерархии внутри конструктора производится вызов какого либо метода он будет выполнен 5. проперти с одинаковыми именами затеняют паренты если не указывать модификатор super.propertyName 6. любой метод из парента пытающийся получить значение затенённого проперти - получит значение заттеняющего из самого нижнего. 7. до момента завершения конструктора парента собственные проперти инициализированы дефолтным значением в случае примитивов и null в случае объектов. 8. после завершения конструирования иерархии и линковки класс инициализирует собственные проперти 9. выполняются инструкции в конструкторе и конструктор завершается 10. класс находится в консистент стейте и готов к работе Для более глубокого понимания приколов связанных с приоритетами рекомендую почитать про утечки this в конструкторе, типа такого:
1
|
0 / 0 / 0
Регистрация: 19.08.2013
Сообщений: 3
|
|
20.08.2013, 12:54 | 19 |
А не порекомендуете что почитать про то что происходит внутри jvm, про всякие invoke* и тд?
0
|
20.08.2013, 13:01 | |
20.08.2013, 13:01 | |
Помогаю со студенческими работами здесь
20
Вызов базового конструктора с параметрами из дочернего класса Знакомство с наследованием. Вызов конструктора базового класса Вызов базового конструктора Вызвать конструктор производного класса без конструктора базового класса Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |