C# 如果从父类中创建子类,则会再次创建父类
我在试图解决这个问题时迷失了方向,下面是我代码的一个节略示例。我的问题是,当我从Bar对象实例化一个Note对象时,Bar构造函数再次被调用,,然后创建另一个Note对象,依此类推,直到出现堆栈溢出错误 这种递归有什么原因吗?我怎样才能正确地创建子类的实例来防止它 编辑:我试图实现一个父类栏实例和多个子类实例。这样,每次我创建父类栏时,它都会创建自己的注释集。是否必须对编写时没有任何继承关系的类(仅一个单独的Bar和Note类)执行此操作? 我需要在子类中有一个函数(由于其他原因,我无法将此函数移到父类中)调用父类中的函数,这将破坏具有base.RemoveNote的子类实例(此); 是否有更好的方法来执行此操作,或者是否有方法从子类的同一实例中销毁子类的实例 代码:C# 如果从父类中创建子类,则会再次创建父类,c#,oop,C#,Oop,我在试图解决这个问题时迷失了方向,下面是我代码的一个节略示例。我的问题是,当我从Bar对象实例化一个Note对象时,Bar构造函数再次被调用,,然后创建另一个Note对象,依此类推,直到出现堆栈溢出错误 这种递归有什么原因吗?我怎样才能正确地创建子类的实例来防止它 编辑:我试图实现一个父类栏实例和多个子类实例。这样,每次我创建父类栏时,它都会创建自己的注释集。是否必须对编写时没有任何继承关系的类(仅一个单独的Bar和Note类)执行此操作? 我需要在子类中有一个函数(由于其他原因,我无法将此函数
类栏
{
私人名单说明;
公共酒吧()
{
注释=新列表(0);
添加(新注释())
}
公共无效删除通知(注)
{
注释。删除(注释);
}
}
课堂笔记:酒吧
{
公共说明()
{
//做事
基底。移除(本);
}
}
公共主窗口()
{
私人酒吧newBar=新酒吧();
}
您始终可以有条件地在基类中实例化
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
}
}
public void Main()
{
Bar newBar=新的Bar(真);
}
//在此处定义其他方法和类
分类栏
{
清单说明;
公共酒吧(bool实例化)
{
if(实例化){
注释=新列表(0);
添加(新注释());
}
}
}
课堂笔记:酒吧
{
公共注释():基(假)
{
//做事
}
}
否则,您的代码将出现问题。基类构造函数在派生类构造函数之前被调用,因此在代码中,每次调用Note()构造函数时,都是先调用Bar()构造函数,后者调用Note()etc
通过有条件地实例化基类并让派生类使用Bar(false)构造函数调用基类,您将在通过的第一次迭代后停止循环
对我来说,这似乎是一个奇怪的设计决定。我感觉您不太清楚类派生的目的是什么,以及派生类如何继承基的属性和方法。假设这是在谈论音乐概念,
注意
可能不应该继承自Bar
。相反,条
具有注释
实例。如果两者之间存在共同行为,您可能需要一个共同的基类或接口,如下所示:
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() { /* ... */ }
}
公共接口可安装
{
无效播放();
}
分类栏:我可以放
{
私有IList notes=新列表{new Note()};
公共游戏
{
foreach(附注中的var附注)
{
注:Play();
}
}
}
课堂笔记:我可以放
{
公共说明()
{
//做事
}
public void Play(){/*…*/}
}
基本上不要混淆父/子关系和继承关系。只有当两个类有共同的数据或行为时才使用继承。这就是我解决问题的方法 不确定这是否是代理的正确用法,但它对我有效
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();
}
delegate void RemoveNoteDelegate(注);
分类栏
{
私人名单说明;
公共酒吧()
{
注释=新列表(0);
注释.添加(新注释(删除注释))
}
公共无效删除通知(注)
{
注释。删除(注释);
}
}
课堂笔记
{
公共RemoveNoteDelegate删除注释;
公共便笺(RemoveNoteDelegate remove_便笺)
{
//做事
删除注释(本);
}
}
公共主窗口()
{
私人酒吧newBar=新酒吧();
}
当然会。这就是继承的工作原理。。。当您具有子/父关系时,所有子类都将从父类调用/初始化。将调用默认构造函数。您的代码似乎也不正确。为什么子类要创建父类的实例?(这里的父类是注释)。我到处都能看到这是子类注释的定义(注释:Bar)我应该如何从父类创建子类,我希望子类是注释。谢谢,你确定便条扩展了吗?@user2056201-颠倒你的代码。让Bar从Note派生看起来Bar和Note之间的关系应该是“Has”而不是“Is”看看这里的一些答案:很抱歉没有澄清我的问题,我想做的是实例化父类的一个实例和子类的多个实例。这样,每次我创建一个Bar对象时,我都希望它创建多个Note对象。这可能与派生关系有关吗?或者我需要使这两个类完全独立。派生用于表示从一般到特定的对象层次结构。如果你有一类动物,也有一类哺乳动物:动物,哺乳动物在这里被视为是一种更特殊的动物类型。它有一些与动物相同的功能和属性(吃、睡、身高体重),但它有一些基类没有的功能和属性(头发)。它还可能覆盖基本功能和属性的实现方式,同时仍然为这些内容公开相同的名称。这种关系对你的笔记和酒吧有意义吗?其中一个是另一个的更具体版本吗?您的代表没有做任何事情。从代码和构造函数中删除委托,Bar newBar=new Bar()将具有
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();
}