Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果从父类中创建子类,则会再次创建父类_C#_Oop - Fatal编程技术网

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

C# 如果从父类中创建子类,则会再次创建父类,c#,oop,C#,Oop,我在试图解决这个问题时迷失了方向,下面是我代码的一个节略示例。我的问题是,当我从Bar对象实例化一个Note对象时,Bar构造函数再次被调用,,然后创建另一个Note对象,依此类推,直到出现堆栈溢出错误 这种递归有什么原因吗?我怎样才能正确地创建子类的实例来防止它 编辑:我试图实现一个父类栏实例和多个子类实例。这样,每次我创建父类栏时,它都会创建自己的注释集。是否必须对编写时没有任何继承关系的类(仅一个单独的Bar和Note类)执行此操作? 我需要在子类中有一个函数(由于其他原因,我无法将此函数

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

这种递归有什么原因吗?我怎样才能正确地创建子类的实例来防止它

编辑:我试图实现一个父类栏实例和多个子类实例。这样,每次我创建父类栏时,它都会创建自己的注释集。是否必须对编写时没有任何继承关系的类(仅一个单独的Bar和Note类)执行此操作? 我需要在子类中有一个函数(由于其他原因,我无法将此函数移到父类中)调用父类中的函数,这将破坏具有base.RemoveNote的子类实例(此); 是否有更好的方法来执行此操作,或者是否有方法从子类的同一实例中销毁子类的实例

代码:

类栏
{
私人名单说明;
公共酒吧()
{
注释=新列表(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();
}