Как реализовать множественное наследование в Java - PullRequest
1 голос
/ 12 октября 2010

Я работаю с определенной библиотекой API в Java.Он имеет базовый класс A, а также B и C, которые оба расширяют A. B & C предоставляют схожую, но отличную функциональность, все три класса находятся в библиотеке.

public abstract class A
{
    virtual foo();
}

public class B extends A {}
public class C extends A {}

Как получить элементыA, B и C в моем классе?Если я использую интерфейсы для реализации классов, будет много дублирующегося кода, и внутренние классы не позволят мне переопределить существующие методы, чтобы сохранить вызывающие интерфейсы A, B и C.

Как реализовать множественное наследование в Java?

РЕДАКТИРОВАТЬ: Спасибо за редактирование. Джордж, теперь стало понятнее, забыл упомянуть одно критическое требование: мои классы должны иметь A в качестве основы, чтобыможет управляться с помощью API платформы.

Ответы [ 6 ]

14 голосов
/ 12 октября 2010

Подводя итог, у вас есть:

class A
{
    public void foo() {}
}

class B extends A
{
    public specificAMethod() {}
}

class C extends A
{
    public specificCMethod() {}
}

Вышеуказанные классы находятся в библиотеке, к которой вы не можете получить доступ или изменить. Вы хотите получить поведение B и C в третьем классе D, как если бы можно было написать:

class D extends B, C
{
}

правый

А как насчет использования B и C вместо наследования? Вам действительно нужно наследство? Вы хотите вызвать частные методы B и C?

class D
{

private B b;
private C c;
}
2 голосов
/ 12 октября 2010

Если вы воспользуетесь общим подходом «Предпочитать композицию, а не наследование», вы можете обнаружить, что один или оба класса на самом деле не должны быть «унаследованы».В обоих случаях, имеют ли классы строгие отношения "есть"?Если вы можете произнести вслух "Has-a", и это не звучит глупо, вы, вероятно, захотите композицию.

Например, если вы используете колоду карт, 3 пики - это-3и это - лопата, но вы также можете думать о ней как о - 3, и у нее - костюм (лопата).Так как вы можете думать об этом таким образом, вам, вероятно, следует отдать предпочтение интерпретации и использованию композиции.

Старайтесь держаться подальше от деревьев наследования более чем на несколько объектов - и, если вы когда-нибудь почувствуете желание использовать множественное наследование, попробуйте обойти его.Это один из случаев, когда Java вынуждает вас сделать свой код немного более читабельным, не предоставляя функции (но по общему признанию, когда вы действительно этого хотите, ее там нет, и это может повредить!хорошо).

0 голосов
/ 26 июня 2017

Начиная с Java 1.8 вы можете использовать интерфейсы с методами по умолчанию. Это очень удобно, и я часто использую его. Ковариантные типы возврата также поддерживаются. Существуют ограничения fiew (см. Ниже), но вам не нужно реализовывать наследование самостоятельно и позволить компилятору работать на вас.

public interface A {
    default A foo() {
        return this;
    }
}

public interface B extends A {
    @Override
    default B foo() {
        return this;
    }
}

public interface C extends A {
    @Override
    default C foo() {
        return this;
    }
}

public interface D extends B, C {
    @Override
    // if the return type does not implement B and C
    // the comiler will throw an error here
    default D foo() { 
        return this;
    }
}

Обратите внимание, что это, но обратите внимание, что вы не можете вызвать super.foo или определить поля или закрытые члены (до Java 9) , поскольку он все еще взаимодействует. Если вы согласитесь с этими ограничениями, это откроет вам новый уровень объектно-ориентированного программирования.

0 голосов
/ 13 октября 2010

В COM применяется совершенно другой подход: все объекты наследуются от IUnknown, у которого есть метод, который можно преобразовать в Java как:

Object queryInterface(Class<?> clazz)

Простейшая реализация этого метода может быть:

if(clazz.isAssignableFrom(this.getClass()))
    return this;
else
    return null;

Там, где одиночное наследование не будет работать, достаточно просто добавить:

else if(class == SomeClass.class) {
    return something;
} else ...

Таким образом, даже самые сложные случаи множественного наследования могут быть рассмотрены, и вы получите полный контроль над тем, что возвращается икогда, таким образом, вы избежите многих проблем с «классическим» множественным наследованием от языков, таких как C ++, таких как проблема fork-join.

0 голосов
/ 12 октября 2010

Множественное наследование классов в Java невозможно, однако вы можете использовать множественное наследование для интерфейсов. Используя Шаблон делегирования , вы можете объединить поведение нескольких других классов в один.

0 голосов
/ 12 октября 2010

Звучит так, будто вы хотите расширить A - назовите его D - переопределите его foo (), а затем добавьте новые подклассы E & F, которые расширяют D и добавляют свои собственные функции.

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

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