迭代来自同一基类的不同对象

时间:2014-02-02 21:40:26

标签: java android design-patterns

我有各种类来定义一段音乐的结构元素。层次结构为Song> Section> CompositeMusic> MusicTime,所有这些都继承自抽象的MusicComponent类。

MusicTime是底层,知道要播放哪个Chord以及有多少个四分音符,并且包含在CompositeMusic个对象的小节中。 Section依次保留CompositeMusics并允许进行速度和时间签名更改。

我需要能够递归遍历Sections中的所有Song,每个CompositeMusics中的所有Section,并在每个MusicTimes中播放所有CompositeMusic MusicTime。换句话说,遍历每种类型的所有子项,除非它是List<MusicComponent> getChildren(),在这种情况下播放它。

我天真地以为我能够在MusicComponent基类上放置一个抽象的List<Section>,所以我可以用同样的方式迭代任何后代。但是这是不允许的,因为例如它不会接受public abstract class MusicComponent { public MusicComponent() { } public abstract void play(); public abstract boolean addComponent(MusicComponent component); public abstract List<MusicComponent> getChildren(); }

所以我的问题是,递归迭代来自同一基类的不同对象的正确方法是什么?

修改

根据要求提供代码示例:

基类

public class Song extends MusicComponent {

    String songName;
    List<Section> sections;

    public Song(String songName, List<Section> sections) {

        this.songName = songName;
        this.sections = sections;
    }

子类的示例

Song

这就是我要对Section做的事情(以及CompositeMusic@Override public List<MusicComponent> getChildren() { return sections; } 的等效内容)

List<Section>

但它抛出了一个编译错误,因为它无法从List<MusicComponent>隐式转换为Section,即使MusicComponent来自{{1}},这就是我所说的希望能够做到

3 个答案:

答案 0 :(得分:3)

尝试使用List<? extends MusicComponent>作为返回类型

答案 1 :(得分:0)

从Java 1.5开始支持协变返回类型,因此如果基类方法被覆盖,getChildren()方法基本上可以返回MusicComponent子类的任何列表。您需要做的是在使用instanceof进行迭代检查之前,确保要迭代的列表变量的类型正确。

答案 2 :(得分:0)

请参阅维基百科中的访客设计模式。这是递归迭代复杂层次结构的经典方法。 设计模式是简单用例的开销,但如果您的模型将来会发展,它会有所帮助。