简体   繁体   English

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

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

This should be a pretty straight-forward question. 这应该是一个非常简单的问题。 I only ask for a simple easy to understand answer. 我只要求一个简单 易懂的答案。 No, I don't want a textbook definition or a link to documentation, please, if possible answer this as simply as possible. 不,我不希望有教科书定义或文档链接,请尽可能简单地回答。

Consider the following: 考虑以下:

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

Now imagine I create a new Skeleton object with the type Monster as so. 现在想象一下,我这样创建了一个新的Skeleton对象,其类型为Monster。

 Monster skeleton = new Skeleton();

I would like to know the difference between creating a Skeleton object with a Monster Type vs creating a Skeleton Object with a Skeleton type . 我想知道创建与怪物类型 VS创建与骨架类型 skeleton对象骷髅对象之间的差异。

 Skeleton skeleton = new Skeleton();

I don't understand if there's a difference between the two or really how this works. 我不知道两者之间是否有区别,或者实际上是如何区别的。 Any and all help appreciated! 任何和所有帮助表示赞赏! Thank you! 谢谢!

The benefits to creating a Skeleton object with a Monster type becomes more apparent when you have multiple monsters that you want to hold in a single collection. 当要在单个集合中保存多个怪物时,创建带有Monster类型的Skeleton对象的好处就更加明显。

For example, you might have a list defined as follows: 例如,您可能具有如下定义的列表:

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

Declaring your Skeleton object as Monster allows you to add it to this list, along with any other Monster classes you create. Skeleton对象声明为Monster允许您将其与创建的任何其他Monster类一起添加到此列表中。

So, you might have another monster class: 因此,您可能还有另一个怪物类:

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

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

You could then do the following: 然后,您可以执行以下操作:

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

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

This would then allow you to loop through the EncounterMonsters collection and attack with each using the overridden Attack method for each. 然后,这将允许您遍历EncounterMonsters集合并使用每个对象的重写Attack方法对每个对象进行Attack

To Expand on the accepted answer, the difference is that if you instantiate your object using the base class Monster , only the properties and methods exposed by the Monster class are available. 为了扩展接受的答案,不同之处在于,如果使用基类Monster实例化对象,则只有Monster类公开的属性和方法可用。

Consider this: 考虑一下:

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)
    {
      // ...
    }
}

Now, if you instantiate your skeleton as a Monster. 现在,如果您将骨骼实例化为怪物。

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

If you instantiate it as a Skeleton; 如果您将其实例化为骨骼;

Skeleton skeleton = new Skeleton(100, "skully");
skeleton.Loot(); // Will return "Sword";

This is useful when you, for example, have a method or service that will act on common properties of your monsters, say you have a method that logs the stats of a monster. 例如,当您拥有将对怪物的公共属性起作用的方法或服务时,例如说您有记录怪物统计信息的方法时,这很有用。

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"

Notice that we are passing a Skeleton instance to a method that expects a Monster instance. 注意,我们正在将Skeleton实例传递给需要Monster实例的方法。 So within the scope of the method Bob is treated as a Monster, not as a Skeleton. 因此,在方法的范围内, Bob被视为怪物,而不是骨骼。

As we know that derive class can call base class constructor with help of "Base()" method. 众所周知,派生类可以在“ Base()”方法的帮助下调用基类构造函数。 initialize base class member initialize subclass class member 初始化基类成员初始化子类类成员

We don't have facility to call derived call constructor from base class that is wrong approach. 我们没有办法从错误的基类中调用派生的调用构造函数。

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

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