2017-02-20 2 views
0

Это должен быть довольно прямой вопрос. Я только прошу простойлегко понять ответ. Нет, я не хочу определения учебника или ссылки на документацию, пожалуйста, если возможно, ответьте на это как можно проще.Создание объекта унаследованного класса в 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 skeleton = new Skeleton(); 

Я хотел бы знать разницу между созданием объекта скелет с монстр типа против создания объекта Скелет с типом Скелет.

Skeleton skeleton = new Skeleton(); 

Я не понимаю, существует ли разница между двумя или действительно, как это работает. Любая помощь приветствуется! Спасибо!

+1

Скелет * - монстр, но монстр * не должен быть * скелетом, думающим о случае, когда у вас есть группа монстров с ** многими типами, и все они атакуют на одном и том же время ** –

+0

(Предполагалось, что Phun) надеется, что ур не думает о C#/oop как о монстрах (oop = monster, C# = skeleton): D –

ответ

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 для каждого.

+0

Абсолютно идеальный ответ, большое спасибо. – Tony

+0

Это, конечно, довольно упрощенно, в зависимости от вашего приложения вам, вероятно, потребуется отслеживать HP каждого монстра, когда на него нападают, но это иллюстрирует точку. – Steve

+0

Я предполагаю, что наилучшей практикой было бы создание скелетного объекта с скелетом типа, если бы у меня не было причины не исправлять? – Tony

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

Теперь, если вы создать экземпляр скелет в качестве монстра.

Если вы создаете экземпляр в виде скелета;

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 рассматривается как монстр, а не как скелет.