Можно ли реализовать интерфейс в производном классе в Java? - PullRequest
2 голосов
/ 15 октября 2008

Давайте иметь следующую иерархию классов:

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?

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

Ответы [ 9 ]

18 голосов
/ 15 октября 2008

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

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

interface SomeInterface {}
abstract class AbstractParentClass {}
class ParentClass extends AbstractParentClass implements SomeInterface {}
class ChildClass extends AbstractParentClass {}
7 голосов
/ 15 октября 2008

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

3 голосов
/ 19 октября 2008

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

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

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

Другие модели наследования ОО (в частности, язык программирования Майера Эйфеля) поддерживают функцию «Изменение доступности или типа» (CAT), которую вы ищете.

2 голосов
/ 15 октября 2008

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

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

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

2 голосов
/ 15 октября 2008

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

1 голос
/ 19 октября 2008

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

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

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

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

Если вам нужна такая ситуация, запрограммируйте на "C". Не связывайтесь с притворством писать код ООП, используя возможности языка ООП. Просто используйте struct для хранения ваших данных. Положите союзы везде. Используйте typecast с готовностью.

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

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

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

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

0 голосов
/ 15 октября 2008

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

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

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

0 голосов
/ 15 октября 2008

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

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

0 голосов
/ 15 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...