Reputation: 351
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.
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.
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!
Upvotes: 0
Views: 5354
Reputation: 301
As we know that derive class can call base class constructor with help of "Base()" method. 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.
Upvotes: 0
Reputation: 2778
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.
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. So within the scope of the method Bob
is treated as a Monster, not as a Skeleton.
Upvotes: 2
Reputation: 9551
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.
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.
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.
Upvotes: 4