2013-05-20 41 views
1

Java泛型我有相关的问题与ArrayList的

我有一个名为Container像下面父母类Java泛型:容器可以包含其他容器和Services。 Services类扩展Container,但只能包含也扩展Container的ServiceMembers

即使在Services类中,我重写父类的getElements()方法并返回也是Container类的子类的元素的ArrayList,但下面的代码不起作用。

任何想法,我怎么能得到这个工作,或者我只是用它错误的方式?

public class Container 
{ 
    protected ArrayList<Container> elements = new ArrayList<Container>(); 

    public ArrayList<Container> getElements() 
    { 
    } 
} 

public class Service extends Container 
{ 
    public ArrayList<ServiceMember> getElements() 
    { 
    } 
} 

回答

1

我认为你只需要修改Container类是这样的:

public class Container<T extends Container> { 
    protected List<T> elements = new ArrayList<T>(); 

    public List<T> getElements() { 
     return elements; 
    } 
} 

这将让你与所有Container类的子类(或自己)参数化它。

Service类是这样的:

public class Service extends Container<Service> { 

} 

在最后,你可以将这些类别实例的对象是这样的:

Service s = new Service(); 
ArrayList<Service> elements = s.getElements(); 

Container<Container> c = new Container<Container>(); 
ArrayList<Container> els = c.getElements(); 

//adding an element to each of the lists: 
c.getElements().add(new Container<Container>()); 
System.out.println(c.getElements().size()); 

s.getElements().add(new Service()); 
System.out.println(s.getElements().size()); 

无论如何,我会建议你仔细考虑在设计上,因为混合原始类与泛型是不安全和混乱的。

+0

请注意'Container'是'T extends Container'中的一个原始类型。 –

+0

嗨,谢谢你的回应,同时我尝试建议的解决方案..想知道你是否看到我的对象排列的方式基金缺陷..可以ü建议..谢谢 – Chandu

+0

也如何添加到元素列表?我试过你的建议,我能够返回列表的类型,但我看到问题添加元素 – Chandu

1

即使在服务类我覆盖了父母类的的getElements()方法,并返回这也是Container类的子类的元素的ArrayList下面的代码不工作。

这是不正确的。由于类型擦除ArrayList<ServiceMember>不考虑重写getElements()方法所需的协变式返回。

覆盖如下。你不会失去多态性,它仍然会发生,因为它取决于Object的类型(动态;在运行时),而不是它的引用类型(静态;在编译时)。

public class Service extends Container 
{ 
    public ArrayList<Container> getElements() 
    { 
    // declare superclass Container 
    ArrayList<Container> elements = new ArrayList<Container>(); 

    // but add subclass ServiceMember 
    elements.add(new ServiceMember()); 

    return elements; 
    } 
} 
+0

感谢您的答复。我确实检查了堆栈上的其他解释并理解了这个问题。但我尝试了一些解决方案以及其他帖子,但是我对Generic不是很熟悉,所以继续问问题,看看有人能够以正确的方式帮助我找到我正在做的事情的解决方案。有更好的方法来做到这一点 protected ArrayList <? extends Container> elements = new ArrayList (); – Chandu

-1

您需要Container,以表示对事物的类型包含:

public class Container<T extends Container<T>> { 
    private List<T> elements = new ArrayList<T>(); 

    public List<T> getElements() { 
     return elements; 
    } 
} 

public class Service extends Container<Service> { 
} 

注:

  • 类型T extends Container<T>似乎扩展其本身,但是这是你如何指定它这样,你避免生的容器类型
  • 名单是私人:子类应该通过吸气
  • 抽象类型List代替具体实施ArrayList良好做法简单地访问它,本着
+1

你能告诉我们你将如何实例化Container类吗? –