这应该是一个非常直截了当的问题。我只要求一个简单 易于理解的答案。不,我不想要教科书定义或文档链接,请尽可能简单地回答。
请考虑以下事项:
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对象。
Monster skeleton = new Skeleton();
我想知道使用怪物类型创建一个Skeleton对象与使用 Skeleton类型创建一个Skeleton对象之间的区别。
Skeleton skeleton = new Skeleton();
我不明白这两者之间是否存在差异,或者它是如何起作用的。任何和所有帮助表示赞赏!谢谢!
答案 0 :(得分:3)
当您想要在一个集合中保留多个怪物时,创建具有Skeleton
类型的Monster
对象的好处会变得更加明显。
例如,您可能有一个如下定义的列表:
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
方法进行攻击。
答案 1 :(得分:1)
要扩展已接受的答案,不同之处在于,如果使用基类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 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
被视为怪物,而不是骷髅。
答案 2 :(得分:0)
我们知道,派生类可以借助“ Base()”方法调用基类构造函数。 初始化基类成员 初始化子类的类成员
我们没有办法从错误的基类中调用派生的调用构造函数。