Как создать класс, который «расширяет» два существующих конкретных класса - PullRequest
3 голосов
/ 29 августа 2011

Я очень хорошо знаю, что это можно сделать с помощью интерфейсов, и я делал это много раз. Но на этот раз моя ситуация совершенно другая. У меня есть class A, class B, и мне нужно создать еще один class C, который расширяет как A, так и B, потому что C должен иметь обе функции, а также отметить, что A и B не связаны между собой, поэтому даже я не могу сказать, что A может расширяться class B.

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

Добавление дополнительных сведений: - Class B - это стандартный API, а class A - это общий класс исключений, который должен наследоваться всеми классами исключений.

Похожие вопросы:

Ответы [ 8 ]

11 голосов
/ 29 августа 2011

Обычно это решается с помощью композиции объектов .

. Это также рекомендуется в Effective Java, пункт 16: Композиция Favor over the Наследование .

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


class A {
    void doAStuff() {
        System.out.println("A-method");
    }
}

class B {
    void doBStuff() {
        System.out.println("B-method");
    }
}

// Wraps an A and a B object.
class C {
    A aObj;
    B bObj;

    void doAStuff() {
        aObj.doAStuff();
    }

    void doBStuff() {
        bObj.doBStuff();
    }
}

(В качестве альтернативы вы могли быиметь class C extends A и создавать только методы-оболочки для B, но имейте в виду, что имеет смысл сказать, что C - это A .)


У меня есть шаблон проектирования, которому нужно следовать, и для этого его необходимо расширить

Это, как вы, наверное, знаете, совершенно невозможно.Однако вы можете создать прокси-классы для A и B, которые делегируют функциональность экземпляру C.Например, добавив эти два метода к классу C выше:

class C {

    // ...

    public A asAObject() {
        return new A() {
            @Override
            void doAStuff() {
                C.this.doAStuff();
            }
        };
    }

    public B asBObject() {
        return new B() {
            @Override
            void doBStuff() {
                C.this.doBStuff();
            }
        };
    }
}
5 голосов
/ 05 ноября 2012

http://en.wikipedia.org/wiki/Adapter_pattern

Ваша проблема решена с помощью шаблона адаптера. Я вернулся, чтобы проверить документ вики, просто чтобы быть уверенным:)

3 голосов
/ 29 августа 2011

Невозможно расширить два класса и, таким образом, наследовать функциональность от обоих в Java. Ваша самая простая альтернатива - это «завернуть» хотя бы один из двух классов. Таким образом, вместо расширения B вы можете создать экземпляр B внутри C, объявить каждый из методов B на C и передать их через. C не будет «B», но звучит так, будто вы просто хотите наследовать функциональность. И если это верно и для А, тогда, ну, вы должны использовать этот шаблон как для А, так и для В, а также не расширять.

1 голос
/ 29 августа 2011

Измените способ мышления.Думай в интерфейсах.Это означает, что класс A на самом деле является реализацией интерфейса A ', а класс B является реализацией интерфейса B'.И вы на самом деле хотите класс C, который реализует оба интерфейса A 'и B'.Классу C не нужно ничего расширять или использовать какой-либо конкретный шаблон или что-либо еще.Он может расширять A и делегировать некоторые методы B, или он может расширять B и делегировать некоторые методы A. Или он может делегировать все методы A и B - реализация является вашим решением.

1 голос
/ 29 августа 2011

Может быть, вы можете создать новый класс D, и оба класса A и B наследуются от D?

1 голос
/ 29 августа 2011

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

1 голос
/ 29 августа 2011

Вы можете попробовать создать class C, который будет содержать один экземпляр class A и один из class B и их методы (создавать методы с такими же именами, которые будут просто вызывать методы из A и B), это Композиция называется - еще один метод, противоположный наследованию. Конечно, это в том случае, если вам не нужен instanceof для работы с этим C классом.

1 голос
/ 29 августа 2011

Используйте композицию.Класс C будет содержать экземпляр каждого из классов A и B.

...