Во время одного из моих интервью меня спросили: «Можем ли мы создать экземпляр абстрактного класса?»
Мой ответ был «Нет, мы не можем». Но интервьюер сказал мне: «Неправильно, мы можем».
Я немного поспорил об этом. Затем он сказал мне попробовать это дома.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Здесь я создаю экземпляр своего класса и вызываю метод абстрактного класса. Может ли кто-нибудь объяснить это мне? Был ли я действительно неправ во время моего интервью?
B
от абстрактногоA
, в течение части строительства вB
случае, заключающийся работаетA
конструктор «s, тип выполнения объекта на самом делеA
. Только временный однако.Ответы:
Нет, вы не создаете экземпляр своего абстрактного класса здесь. Скорее вы создаете экземпляр анонимного подкласса вашего абстрактного класса. И затем вы вызываете метод из вашей ссылки на абстрактный класс, указывающий на объект подкласса .
Это поведение четко указано в JLS - Раздел № 15.9.1 : -
Акцент мой.
Также в JLS - Раздел № 12.5 вы можете прочитать о процессе создания объекта . Я приведу одно утверждение из этого здесь: -
Вы можете прочитать о полной процедуре по ссылке, которую я предоставил.
Чтобы практически увидеть, что создаваемый класс является анонимным подклассом , вам просто нужно скомпилировать оба ваших класса. Предположим, вы поместили эти классы в два разных файла:
My.java:
Poly.java:
Теперь скомпилируйте оба ваших исходных файла:
Теперь в каталоге, где вы скомпилировали исходный код, вы увидите следующие файлы классов:
Посмотри на этот класс
Poly$1.class
. Это файл класса, созданный компилятором, соответствующий анонимному подклассу, который вы создали, используя следующий код:Итак, ясно, что создается другой класс. Просто этот класс получает имя только после компиляции компилятором.
В общем, все анонимные подклассы в вашем классе будут названы так:
Эти числа обозначают порядок, в котором эти анонимные классы появляются во включающем классе.
источник
instance of
иinstantiating
. Вы создаете экземпляр только одного класса, а созданный вами объект может быть экземпляром нескольких классов из-за наследования.Вышеприведенный пример создает анонимный внутренний класс, который является подклассом
my
абстрактного класса. Это не совсем эквивалентно созданию самого абстрактного класса. OTOH, каждый экземпляр подкласса является экземпляром всех его суперклассов и интерфейсов, поэтому большинство абстрактных классов действительно создаются путем создания экземпляров одного из их конкретных подклассов.Если интервьюер просто сказал "неправильно!" не объясняя и привел этот пример как уникальный контрпример, я думаю, что он, тем не менее, не знает, о чем говорит.
источник
subclassInstance instanceof SuperClass
возвращает true, поэтому объект является экземпляром суперкласса, что означает, что суперкласс был создан. Но это просто семантические придирки.= my() {};
означает , что есть анонимная реализация, а не просто создание экземпляр объекта, который должен были быть := my()
. Вы никогда не можете создать экземпляр абстрактного класса.источник
Просто наблюдения, которые вы могли бы сделать:
poly
расширяетсяmy
? Это бесполезно ...my.class
,poly.class
иpoly$1.class
Можем ли мы создать экземпляр абстрактного класса?
Нет, мы не можем. Мы можем создать анонимный класс (это третий файл) и создать его экземпляр.
А как насчет создания суперкласса?
Абстрактный суперкласс создается не нами, а Java.
РЕДАКТИРОВАТЬ: Попросите его проверить это
вывод:
источник
Serializable s = new Serializable() {};
(что довольно бесполезно), и если тег на вашем коде дастclass my$3
(или любой другой класс и число)Вы можете просто ответить, в одну строку
Но, интервьюер все еще не согласен, тогда вы можете сказать ему / ей
И, согласно классу Anonymous, класс объявлен и создан в одном месте / строке
Так что, возможно, интервьюеру было бы интересно проверить уровень вашей достоверности и то, сколько вы знаете об ООП.
источник
Техническая часть была хорошо освещена в других ответах, и в основном она заканчивается:
«Он не прав, он ничего не знает, попросите его присоединиться к SO и очистить все :)»
Я хотел бы остановиться на том факте (о котором упоминалось в других ответах), что это может быть стресс-вопрос и важный инструмент для многих интервьюеров, чтобы узнать о вас больше и как вы реагируете на сложные и необычные ситуации. Давая вам неправильные коды, он, вероятно, хотел увидеть, если вы спорили в ответ. Чтобы узнать, есть ли у вас уверенность, чтобы противостоять своим старшим в ситуациях, подобных этой.
PS: я не знаю почему, но у меня есть ощущение, что интервьюер прочитал этот пост.
источник
Абстрактные классы не могут быть созданы, но они могут быть разделены на подклассы. Смотрите эту ссылку
Лучший пример
Хотя класс Calender имеет абстрактный метод getInstance () , но когда вы говорите,
Calendar calc=Calendar.getInstance();
calc ссылается на экземпляр класса GregorianCalendar как «GregorianCalendar расширяет календарь »
Infact annonymous внутренний тип позволяет создать не имя подкласс абстрактного класса и экземпляр этого.
источник
Технический ответ
Абстрактные классы не могут быть созданы - это по определению и замыслу.
Из JLS, Глава 8. Классы:
Из JSE 6 Java-документ для Classes.newInstance ():
Конечно, вы можете создать конкретный подкласс абстрактного класса (включая анонимный подкласс), а также выполнить тип-ссылку на ссылку на объект абстрактного типа.
Под другим углом зрения - командная игра и социальный интеллект:
Такое техническое недоразумение часто случается в реальном мире, когда мы имеем дело со сложными технологиями и юридическими спецификациями.
«Навыки людей» здесь могут быть важнее, чем «Технические навыки». Если конкурентно и агрессивно пытаетесь доказать свою сторону аргумента, то теоретически вы можете быть правы, но вы также можете нанести больший урон, имея в бою / нанося урон «лицу» / создавая врага, чем оно того стоит. Быть примиренным и понимающим в разрешении своих разногласий. Кто знает - может быть, вы "оба правы", но отрабатываете немного другое значение для терминов ??
Кто знает - хотя это маловероятно, возможно, что интервьюер сознательно представил небольшой конфликт / недоразумение, чтобы поставить вас в сложную ситуацию и увидеть, как вы ведете себя эмоционально и социально. Будьте доброжелательны и конструктивны с коллегами, следуйте советам пожилых людей и следите за ними после собеседования, чтобы разрешить любую проблему / недоразумение - по электронной почте или по телефону. Показывает, что вы мотивированы и ориентированы на детали.
источник
Это общепризнанный факт, который не
abstract class
может быть создан, как все ответили.Когда программа определяет анонимный класс, компилятор фактически создает новый класс с другим именем (имеет шаблон,
EnclosedClassName$n
гдеn
находится номер анонимного класса)Так что если вы декомпилируете этот класс Java, вы найдете код, как показано ниже:
мои занятия
poly $ 1.class (сгенерированный класс «анонимного класса»)
ploly.cass
источник
Нет, вы не можете мгновенно создать абстрактный класс. Мы создаем экземпляр только анонимного класса. В абстрактном классе мы объявляем абстрактные методы и определяем только конкретные методы.
источник
Об абстрактных классах
Цель абстрактного класса - вести себя как база. В иерархии наследования вы увидите абстрактные классы вверх.
источник
Вы можете сказать:
мы не можем создать экземпляр абстрактного класса, но мы можем использовать
new
ключевое слово для создания экземпляра анонимного класса, просто добавив{}
тело реализации в конце абстрактного класса.источник
Расширение класса не означает, что вы создаете экземпляр класса. На самом деле, в вашем случае вы создаете экземпляр подкласса.
Я почти уверен, что абстрактные классы не позволяют инициировать. Итак, я бы сказал нет: вы не можете создать экземпляр абстрактного класса. Но вы можете расширить / унаследовать это.
Вы не можете напрямую создать экземпляр абстрактного класса. Но это не значит, что вы не можете получить экземпляр класса (а не экземпляр оригинального абстрактного класса) косвенно. Я имею в виду, что вы не можете создать экземпляр оригинального абстрактного класса, но вы можете:
Таким образом, вы получаете доступ ко всем методам и свойствам в абстрактном классе через экземпляр производного класса.
источник
Невозможно создать экземпляр абстрактного класса. Что вы действительно можете сделать, так это реализовать некоторые распространенные методы в абстрактном классе и позволить другим не реализоваться (объявив их абстрактными) и позволить конкретному потомку реализовать их в зависимости от их потребностей. Затем вы можете создать фабрику, которая возвращает экземпляр этого абстрактного класса (на самом деле его реализатор). Затем на фабрике вы решаете, какой исполнитель выбрать. Это известно как шаблон проектирования фабрики:
Конкретному исполнителю нужно только реализовать методы, объявленные как абстрактные, но он будет иметь доступ к логике, реализованной в тех классах в абстрактном классе, которые не объявлены абстрактными:
Тогда наконец фабрика выглядит примерно так:
Получатель AbstractGridManager будет вызывать методы для него и получать логику, реализованную в конкретном потомке (и частично в методах абстрактного класса), не зная, какую конкретную реализацию он получил. Это также известно как инверсия управления или внедрение зависимости.
источник
Нет, мы не можем создать объект абстрактного класса, но создаем ссылочную переменную абстрактного класса. Ссылочная переменная используется для ссылки на объекты производных классов (подклассы абстрактного класса)
Вот пример, который иллюстрирует эту концепцию
Здесь мы видим, что мы не можем создать объект типа Figure, но мы можем создать ссылочную переменную типа Figure. Здесь мы создали ссылочную переменную типа Figure, а ссылочная переменная класса Class используется для ссылки на объекты класса Rectangle и Triangle.
источник
На самом деле мы не можем создать объект абстрактного класса напрямую. Мы создаем ссылочную переменную абстрактного вызова. Ссылочная переменная используется для ссылки на объект класса, который наследует абстрактный класс, то есть подкласс абстрактного класса.
источник