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中创建继承类的对象#_C#_Oop - Fatal编程技术网

C# 在c中创建继承类的对象#

C# 在c中创建继承类的对象#,c#,oop,C#,Oop,这应该是一个相当直截了当的问题。我只要求一个简单易懂的答案。不,我不想要教科书的定义或文档的链接,如果可能的话,请尽可能简单地回答这个问题 考虑以下几点: class Monster { public int Hp { get; protected set; } public string Name { get; protected set; } public virtual void Attack() { Console.WriteLine("

这应该是一个相当直截了当的问题。我只要求一个简单易懂的答案。不,我不想要教科书的定义或文档的链接,如果可能的话,请尽可能简单地回答这个问题

考虑以下几点:

class Monster
{
    public int Hp { get; protected set; }
    public string Name { get; protected set; }

    public virtual void Attack()
    {
        Console.WriteLine("Monster attacking!");
    }
}

class Skeleton : Monster
{
    public Skeleton()
    {
        Hp = 20;
        Name = "Skeleton";
    }
    public override void Attack()
    {
        Console.WriteLine("Skeleton attacking!");
    }
}
Monster skeleton = new Skeleton();
Monster ogre = new Ogre();

EncounterMonsters.Add(skeleton);
EncounterMonsters.Add(ogre);
现在想象一下,我创建了一个新的骨架对象,其类型为Monster

 Monster skeleton = new Skeleton();
我想知道使用怪物类型创建骨骼对象与使用骨骼类型创建骨骼对象之间的区别

 Skeleton skeleton = new Skeleton();

我不明白这两者之间是否有区别,或者这到底是怎么回事。感谢您的帮助!谢谢大家!

当您想要在一个集合中保存多个怪物时,使用
怪物
类型创建
骨架
对象的好处变得更加明显

例如,您可能有一个定义如下的列表:

List<Monster> EncounterMonsters = new List<Monster>();
然后,您可以执行以下操作:

class Monster
{
    public int Hp { get; protected set; }
    public string Name { get; protected set; }

    public virtual void Attack()
    {
        Console.WriteLine("Monster attacking!");
    }
}

class Skeleton : Monster
{
    public Skeleton()
    {
        Hp = 20;
        Name = "Skeleton";
    }
    public override void Attack()
    {
        Console.WriteLine("Skeleton attacking!");
    }
}
Monster skeleton = new Skeleton();
Monster ogre = new Ogre();

EncounterMonsters.Add(skeleton);
EncounterMonsters.Add(ogre);

然后,这将允许您循环通过
遭遇nsters
集合,并对每个对象使用覆盖的
攻击
方法进行攻击。

当您有多个想要保存在一个容器中的怪物时,使用
怪物
类型创建
骨架
对象的好处变得更加明显单个集合

例如,您可能有一个定义如下的列表:

List<Monster> EncounterMonsters = new List<Monster>();
然后,您可以执行以下操作:

class Monster
{
    public int Hp { get; protected set; }
    public string Name { get; protected set; }

    public virtual void Attack()
    {
        Console.WriteLine("Monster attacking!");
    }
}

class Skeleton : Monster
{
    public Skeleton()
    {
        Hp = 20;
        Name = "Skeleton";
    }
    public override void Attack()
    {
        Console.WriteLine("Skeleton attacking!");
    }
}
Monster skeleton = new Skeleton();
Monster ogre = new Ogre();

EncounterMonsters.Add(skeleton);
EncounterMonsters.Add(ogre);

然后,这将允许您循环通过
遇到nsters
集合,并使用覆盖的
attack
方法对每个对象进行攻击。

要扩展接受的答案,区别在于如果您使用基类
Monster
实例化对象,只有
Monster
类公开的属性和方法可用

考虑这一点:

public class Monster
{
    public Monster(int hp, string name)
    {
        Hp = hp;
        Name = name;
    }
    public int Hp { get; protected set; }
    public string Name { get; protected set; }
}

public class Skeleton : Monster
{
   public string Loot { get; set; } // <- Note added property.
   public Skeleton(int hp, string name) : base(hp, name)
   {
       Loot = "Sword";
   }
}

public class Vampire : Monster
{
    //- some vampire specific properties

    public Vampire(int hp, string name) : base(hp, name)
    {
      // ...
    }
}
如果将其实例化为骨架

Skeleton skeleton = new Skeleton(100, "skully");
skeleton.Loot(); // Will return "Sword";
例如,当你有一个方法或服务可以作用于你的怪物的公共属性时,这是很有用的,比如说你有一个记录怪物统计数据的方法

public string LogMonsterStats(Monster monster)
{
    return $"{monster.Name} has {monster.Hp} health points";
}

///....

Skeleton skeleton = new Skeleton(100, "Bob");
LogMonsterStats(skeleton); // returns "Bob has 100 health points"

请注意,我们正在将一个骨架实例传递给一个需要Monster实例的方法。因此,在方法的范围内,
Bob
被视为怪物,而不是骨架。

为了扩展公认的答案,不同之处在于,如果使用基类
Monster
实例化对象,则只有
Monster
类公开的属性和方法可用

考虑这一点:

public class Monster
{
    public Monster(int hp, string name)
    {
        Hp = hp;
        Name = name;
    }
    public int Hp { get; protected set; }
    public string Name { get; protected set; }
}

public class Skeleton : Monster
{
   public string Loot { get; set; } // <- Note added property.
   public Skeleton(int hp, string name) : base(hp, name)
   {
       Loot = "Sword";
   }
}

public class Vampire : Monster
{
    //- some vampire specific properties

    public Vampire(int hp, string name) : base(hp, name)
    {
      // ...
    }
}
如果将其实例化为骨架

Skeleton skeleton = new Skeleton(100, "skully");
skeleton.Loot(); // Will return "Sword";
例如,当你有一个方法或服务可以作用于你的怪物的公共属性时,这是很有用的,比如说你有一个记录怪物统计数据的方法

public string LogMonsterStats(Monster monster)
{
    return $"{monster.Name} has {monster.Hp} health points";
}

///....

Skeleton skeleton = new Skeleton(100, "Bob");
LogMonsterStats(skeleton); // returns "Bob has 100 health points"

请注意,我们正在将一个骨架实例传递给一个需要Monster实例的方法。因此,在方法的范围内,Bob被视为怪物,而不是骨架。

正如我们所知,派生类可以借助“base()”方法调用基类构造函数。 初始化基类成员 初始化子类成员


我们没有从基类调用派生调用构造函数的工具,这是错误的方法

我们知道,派生类可以在“base()”方法的帮助下调用基类构造函数。 初始化基类成员 初始化子类成员


我们没有从基类调用派生调用构造函数的工具,这是错误的方法

骷髅是怪物,但怪物不需要是骷髅,想象一下,当你有一组具有多种类型的怪物,并且所有这些怪物同时攻击时(Phun有意)希望你不要将c#/oop视为怪物(oop=怪物,c#=骷髅):骷髅是怪物,但怪物不需要是骷髅,考虑一个案例,当你有一组多种类型的怪物,并且所有的怪物同时攻击(Phun意为)时,希望你不要将c#/oop视为怪物(oop=怪物,c#=骷髅):这当然是非常简单的,根据你的应用程序,你可能需要在每个怪物受到攻击时分别跟踪它们的生命,但它说明了这一点。我假设最好的做法是创建一个具有类型skeleton的skeleton对象,除非我有理由不更正?这取决于具体情况。如果您只对骨架感兴趣,或者只需要访问
Skeleton
类中的属性,请确定。如果你需要将它与其他类结合使用,那么这种方式很好。当然,这是非常简单的,根据你的应用程序,你可能需要在每个怪物受到攻击时分别跟踪它们的HP,但它说明了这一点。我假设最好的做法是创建一个具有类型skeleton的skeleton对象,除非我有理由不更正?这取决于具体情况。如果您只对骨架感兴趣,或者只需要访问
Skeleton
类中的属性,请确定。如果您需要将它与其他类结合使用,那么这种方式就可以了。