2016-02-23 2 views
2

У меня есть три класса A, B, C.Java Design: Polymorphic List

А аннотация, B и C расширяет A.

Моя цель состоит в том, чтобы дать пользователю возможность сделать Список Кассиопеяне или B (а не иметь и в том же списке), я хочу провести в жизнь пользователь должен сделать это с помощью умного дизайна.

Моя идея состояла в том, чтобы иметь абстрактный класс ALIST с функцией:

void add (A a) 

и два класса:

Blist расширения ALIST с функцией ничтожной оных (B б) переопределяя надстройку креном в.

CList расширение AList с функцией void add (C c) переопределение добавления AList.

но это не сработало, поскольку вы не можете изменить аргументы функции (если быть более конкретными) при переопределении.

+0

Вы имеете в виду * not *, чтобы иметь оба в том же списке? –

ответ

3

Если вы хотите обеспечить только List<B> или в List<C>, то способ сделать это просто использовать фабричные методы:

class AList<T extends A> { 
    private AList() {...} // users outside the class can't invoke the constructor 

    public static AList<B> createBList() { 
    return new AList<B>(); 
    } 

    public static AList<C> createCList() { 
    return new AList<C>(); 
    } 
} 

Это вынуждает пользователей за пределами вашего класса, чтобы использовать один из фабричных методов, и фабричные методы будут создавать списки только B s или C s, а не A s.

Это не ясно, что вы на самом деле пытаетесь сделать. Нет ничего, что можно было бы сделать, чтобы кто-то не создал ArrayList<A> и вложил в него как B s, так и C, и также непонятно, почему вы хотите изобрести колесо и создать свой собственный тип списка.

+0

Вам не нужно общее после статики? –

+1

@YassinHajaj Нет, это победит точку. Вы активно _must not_ имеете общее после статики. Вы не хотите новую переменную типа, вы хотите ссылаться на определенный именованный класс. –

+0

О да, спасибо. Короче говоря, меня смущало. –

1

Хотя мне нравится решение @LouisWassermans, почему бы вам просто не использовать общие для решения проблемы?

public abstract class AList<T extends A>{ 

    public abstract void add(T a); 

    ... 

} 

public class BList extends AList<B>{ 

    @Override 
    public void add(B b){ 
    ... 
    } 
} 

public class CList extends AList<C>{ 

    @Override 
    public void add(C c){ 
    ... 
    } 
}