Можно ли не реализовать интерфейс в производном классе в Java?

У нас будет следующая иерархия классов:

public class ParentClass implements SomeInterface {
}

public class ChildClass extends ParentClass {
}

Тогда давайте возьмем эти два экземпляра:

ParentClass parent;
ChildClass child;

Тогда у нас есть следующие ИСТИННЫЕ утверждения

(parent instanceof SomeInterface) == true
(child instanceof SomeInterface) == true

Можно ли не реализовать SomeInterface в ChildClass, чтобы при проверке с помощью оператора instanceof он возвращал false?

Если это невозможно, есть ли обходной путь?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
0
1 092
9
Перейти к ответу Данный вопрос помечен как решенный

Ответы 9

Это невозможно, и это нарушит подразумеваемые отношения IS-A между ChildClass и ParentClass. почему ты хочешь сделать это?

Возможно, у вас есть конкретный случай, когда можно было бы придумать лучшее решение, но для общего случая вам понадобится черная магия. В конце концов, Javassist можно было бы использовать для «взлома» ваших объектов, но я в этом не уверен.

Я не думаю, что вы можете «не реализовать» его, но вы можете проверить, является ли он экземпляром родительского класса. Интерфейс твой? Если это так, вы можете расширить его, включив метод «IsObjectDerived» с семантикой, которая возвращает истину, если класс только является производным от объекта. Поскольку вы пишете класс, все, что вам нужно сделать, это реализовать его в родительском элементе и вернуть true, если объект имеет класс Parent, и false в противном случае.

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

[РЕДАКТИРОВАТЬ] В целом я согласен с тем, что это кажется ненужным при разумном дизайне, но это можно сделать.

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

Как насчет повторного факторинга ParentClass, чтобы у вас была реализация SomeInterface отдельно от той, которая вам нужна в ChildClass. Возможно, вам нужен общий базовый класс для ParentClass и ChildClass.

Ответ принят как подходящий

Нет, это невозможно, и ваше намерение сделать это является хорошим намеком на то, что в вашей иерархии классов есть изъян.

Обходной путь: измените иерархию классов, например. нравится:

interface SomeInterface {}
abstract class AbstractParentClass {}
class ParentClass extends AbstractParentClass implements SomeInterface {}
class ChildClass extends AbstractParentClass {}

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

Я не понимаю, насколько это будет разумной практикой, но вы мог изменяете класс динамически, используя отличный пакет Javassist, созданный Шигеру Чиба и др. Используя это, вы можете добавлять и удалять компоненты из классов, а затем использовать экземпляры этих классов без сохранения в виде файлов классов.

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

(Я считаю, что ASM работает аналогичным образом, но я пока не пробовал его. Кажется, он очень популярен среди создателей не-java языков, работающих над JVM, так что, вероятно, это хорошо.)

Я согласен с другими ответами, что это невозможно в Java.

Другие ответы также предполагают, что это указывает на недостаток вашего дизайна.

Хотя я согласен с ними, будет справедливо отметить, что некоторые видные эксперты по объектно-ориентированному проектированию (в частности, Бертран Мейер) не согласны с нами и считают, что такой дизайн должен быть разрешен.

Другие модели объектно-ориентированного наследования (в частности, язык программирования Meyer Eiffel) действительно поддерживают функцию «Изменение доступности или типа» (CAT), которую вы ищете.

Поскольку наследование, основа полиморфизма ООП, обозначает отношения «есть-А», ваш вопрос, похоже, требует способа переопределить отношения «есть», чтобы быть «не есть».

Это не сработает.

Вернитесь к некоторым вводным объектно-ориентированным текстам или онлайн-материалам и изучите, что означает объектно-ориентированный подход: полиморфизм, инкапсуляция и идентичность.

  1. Удалите идентификационные данные, и у вас будет COM / ActiveX и украденные учетные данные.
  2. Снимите инкапсуляцию, и никто не будет в безопасности.
  3. Отбросьте правила типов полифизма, и у вас в основном не будет ничего, что обязательно было бы тем, о чем говорилось.

Если вы хотите такую ​​ситуацию, то запрограммируйте на «С». Не балуйтесь, делая вид, что пишете ООП-код с использованием языковых функций ООП. Просто используйте структуру для хранения ваших данных. Ставьте профсоюзы везде. С энтузиазмом используйте приведение типов.

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

В динамическом языке программирования, таком как SmalTalk или Python, вы можете оторвать крылья у бабочки во время выполнения. Но только изменением / повреждением типа объекта.

Это ничего вам не даст. Существуют методы кодирования / проектирования и шаблоны проектирования, которые позволяют достичь любого «хорошего» результата, который может быть у вас после этого, аналогично этому.

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

Другие вопросы по теме