我试图解决这个问题,下面是我的代码的简略示例。我的问题是,当我从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();
}
答案 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();
}