如果我从父类中创建子类,则会再次创建父类

时间:2014-03-05 02:18:33

标签: c# oop

我试图解决这个问题,下面是我的代码的简略示例。我的问题是,当我从Bar对象实例化一个Note对象时,Bar构造函数再次被调用 ,然后创建另一个Note对象,依此类推,直到出现堆栈溢出错误。

是否有这种递归的原因,如何正确创建子类的实例以防止它?

编辑:我正在尝试使用多个子类实例注意来实现父类 Bar 的一个实例。这样每次我创建父类Bar时,它都会创建自己的Notes集。这是否必须在没有任何继承关系的情况下编写的类(只是一个单独的Bar和Note类)? 我需要在子类中有一个函数(由于其他原因我无法将此函数移动到父类)在父类中调用一个函数,该函数将使用 base.RemoveNote(this)销毁子类的实例; 有没有更好的方法来执行此操作,还是有办法在子类的同一个实例中销毁子类的实例?

代码:

class Bar
{
    private List<Note> notes; 

    public Bar()
    {
        notes = new List<Note>(0);
        notes.Add(new Note())
    }

    public void removeNote(Note note)
    {
        notes.Remove(note);
    }
}

class Note : Bar
{        
    public Note()
    {
        //do stuff
        base.RemoveNote(this);
    }
}

public MainWindow()
{
    private Bar newBar = new Bar();
}

3 个答案:

答案 0 :(得分:1)

假设这是在谈论音乐概念,Note可能不应该从Bar 继承。相反,Bar Note个实例。如果两者之间存在共同的行为,您可能需要一个公共基类或接口,如下所示:

public interface IPlayable
{
    void Play();
}

class Bar : IPlayable
{
    private IList<Note> notes = new List<Note> { new Note() }; 

    public void Play() 
    {
        foreach (var note in notes)
        {
            note.Play();
        }
    }
}

class Note : IPlayable
{        
    public Note()
    {
        //do stuff
    }

    public void Play() { /* ... */ }
}

基本上不要将父/子关系与继承关系混淆。仅当两个类具有共同数据或行为时才使用继承。

答案 1 :(得分:0)

您总是可以有条件地在基类中实例化。

public void Main()
{
    Bar newBar = new Bar(true);
}

// Define other methods and classes here
class Bar
{
    List<Note> notes; 

    public Bar(bool instantiate)
    {
        if(instantiate) {
            notes = new List<Note>(0);
            notes.Add(new Note());
        }
    }
}

class Note : Bar
{        
    public Note() : base(false)
    {
        //do stuff
    }
}

否则,您的代码会出现问题。基类构造函数在派生类构造函数之前调用,因此在每次调用Note()构造函数的代码中,首先调用Bar()构造函数,调用Note()ect ...

通过有条件地实例化基类并让派生类使用Bar(false)构造函数调用基类,您将在第一次迭代之后停止循环。

这对我来说似乎是一个奇怪的设计决定。我觉得你不太确定类派生的目的是什么,以及派生类如何继承基类的属性和方法。

答案 2 :(得分:0)

这就是我解决问题的方法

不确定这是否是代表的正确用法,但它对我有用

delegate void RemoveNoteDelegate(Note note);

class Bar
{
    private List<Note> notes; 

    public Bar()
    {
        notes = new List<Note>(0);
        notes.Add(new Note(removeNote))
    }

    public void removeNote(Note note)
    {
        notes.Remove(note);
    }
}

class Note
{   
    public RemoveNoteDelegate remove_Note;

    public Note(RemoveNoteDelegate remove_Note)
    {
        //do stuff
        remove_Note(this);
    }
}

public MainWindow()
{
    private Bar newBar = new Bar();
}