0

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!

Daniel Ormeño
2,7882 gold badges27 silver badges30 bronze badges
asked Feb 20, 2017 at 1:38
2
  • 1
    A skeleton is a monster, but a monster doesn't need to be a skeleton, thinking of a case when you have a group of monsters with many types, and all of them attacks at the same time Commented Feb 20, 2017 at 1:53
  • (Phun intended) hope u r not thinking of c#/oop as monsters (oop=monster, c#=skeleton) :D Commented Feb 20, 2017 at 2:14

3 Answers 3

4

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.

answered Feb 20, 2017 at 2:01

3 Comments

This is quite simplistic of course, depending on your application you would likely need to track each monster's HP separately when they get attacked, but it illustrates the point.
I'm assuming best practice would be to create a skeleton object with the type skeleton unless I had a reason not to correct?
It depends on the situation. If you're only interested in Skeletons, or you needed to access properties only in the Skeleton class, then sure. If you need to use it in conjunction with other classes, then this way is fine.
2

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.

answered Feb 20, 2017 at 3:55

Comments

0

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.

answered Jul 2, 2019 at 2:18

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.