繁体   English   中英

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

[英]Creating an object of an inherited class in c#

这应该是一个非常简单的问题。 我只要求一个简单 易懂的答案。 不,我不希望有教科书定义或文档链接,请尽可能简单地回答。

考虑以下:

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!");
    }
}

现在想象一下,我这样创建了一个新的Skeleton对象,其类型为Monster。

 Monster skeleton = new Skeleton();

我想知道创建与怪物类型 VS创建与骨架类型 skeleton对象骷髅对象之间的差异。

 Skeleton skeleton = new Skeleton();

我不知道两者之间是否有区别,或者实际上是如何区别的。 任何和所有帮助表示赞赏! 谢谢!

当要在单个集合中保存多个怪物时,创建带有Monster类型的Skeleton对象的好处就更加明显。

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

List<Monster> EncounterMonsters = new List<Monster>();

Skeleton对象声明为Monster允许您将其与创建的任何其他Monster类一起添加到此列表中。

因此,您可能还有另一个怪物类:

class Ogre : Monster
{
    public Ogre()
    {
        Hp = 50;
        Name = "Ogre";
    }

    public override void Attack()
    {
        Console.WriteLine("Ogre attacking!");
    }
}

然后,您可以执行以下操作:

Monster skeleton = new Skeleton();
Monster ogre = new Ogre();

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

然后,这将允许您遍历EncounterMonsters集合并使用每个对象的重写Attack方法对每个对象进行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)
    {
      // ...
    }
}

现在,如果您将骨骼实例化为怪物。

Monster skeleton = new Skeleton(100, "skully");
skeleton.Loot(); //- Will throw a compile time error.

如果您将其实例化为骨骼;

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"

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

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

我们没有办法从错误的基类中调用派生的调用构造函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM