2010-07-07 2 views
2

Пусть у меня есть абстрактный класс А и абстрактный класс B, который наследуется от А, и я создаю объект класса А, как показано ниже:Java Абстрактный реализация класса

abstract class A { 
    void func1(); 
} 

abstract class B extends A { 
    void func2(); 
} 

A objectA = new A() { 
    func1(){ 
     //implementation 
    } 
}; 

Есть ли способ для меня, чтобы сделать что-то вроде это:

B objectB = new B(objectA) { 
    func2(){ 
     //implementation 
    } 
}; 

, так что объект B получает реализацию функций A от объекта A?

+1

Вы не можете создать экземпляр класса – Woot4Moo

+0

Ваш код не компилируется. В частности, новый A() недействителен, поскольку A является абстрактным. –

+3

@ Попробуйте, вы ошибаетесь. 'new A() {}' создает анонимный подкласс. –

ответ

2

Я понимаю, что вы хотите сделать. Такие вещи возможны, например, в Ruby. В Java это не возможно, что путь, потому что

new A() { 
    func1(){ } 
}; 

не тип A но анонимный подкласс A, который не суперкласса B. Компилятор генерирует для этого класс $1.

Но в целом попробуйте другой подход: «Оформите композицию над наследованием». Затем они могут комбинировать func1 и func2 где-то только с использованием двух классов Strategy. Так что, если B не использует никакого состояния A вы могли бы делегировать objectA (который должен быть final тогда):

B objectB = new B() { 
    func1(){ 
    objectA.func1() 
    } 
    func2(){ 
    //implementation 
    } 
}; 

Это похоже на ответ bashflyng, но более прямой.

+0

По этой причине вам необходимо объявить оба метода в подклассе anon B. Что, следует заметить, можно использовать везде, где требуется A, и поэтому, если они имеют одну и ту же реализацию, вы, вероятно, можете использовать это вместо этого. – zebediah49

+0

Проблема с этим решением заключается в том, что класс BImpl не может распространять как AImpl, так и B, которые мне нужны. Я, вероятно, поеду по композиции, потому что кажется, что у меня не может быть всего моего магического наследования ... – LinuxMercedes

+0

Если бы 'A' и' B' были бы интерфейсами, все было бы проще, потому что для интерфейсов было многократное наследование –

0

Абстрактный класс - класс, объявленный абстрактом - он может включать или не включать абстрактные методы. Поэтому, если вы знаете одну из (по умолчанию) конкретных реализаций, вы можете обеспечить реализацию func1(), и она может быть абстрактной. Не ответил на ваш вопрос, хотя (я думаю, что ответ НЕТ);

0

Нет. Ваше определение для A является анонимным классом, поэтому нет способа получить этот код. Вероятно, есть некоторые безумные шаги, чтобы заставить его работать, но не беспокойтесь об этом. Если вы хотите повторно использовать некоторое определение класса, сделайте его своим собственным классом.

3

Вы можете сделать это таким образом (с помощью композиции, так как вы не сможете наследовать от анонимного внутреннего класса Objecta):

abstract class A { 
    abstract void func1(); 
} 

abstract class B extends A { 
    A wrapped; 
    public B(A objectA) { 
     wrapped = objectA; 
    } 
    abstract void func2(); 
} 

A objectA = new A() { 
    void func1(){ 
     //implementation 
    } 
}; 

B objectB = new B(objectA) { 
    public void func1() { 
     wrapped.func1(); 
    } 
    public void func2() { 
     // impl 
    } 
}; 

AFAIK вы не можете определить новый конструктор в objectB, поэтому вы вынуждены объявить его в классе B.

+0

Если бы я мог выбрать два ответа, это было бы одним из них. – LinuxMercedes

Смежные вопросы