C# Наследование, не удаётся привести экземпляр производного класса к типу базового класса (Декоратор)
Решил ознакомится с паттерном декоратор, накидал пример, и тут-же получил ошибку в неожиданном месте, при котором наследник оторван от базового типа. Не могу понять в чём конкретно проблема, и как именно нарушены правила наследования.
public abstract class Character
{
public string ClassName { get; protected set; }
public string PlayerName { get; protected set; }
public Character(string ClassName, string PlayerName)
{
this.ClassName = ClassName;
this.PlayerName = PlayerName;
}
public abstract int DealDamage();
public abstract int Heal();
public string Attack() => $"{PlayerName} ({ClassName}) наносит {DealDamage()} единиц урона";
public string HealMe() => $"{PlayerName} ({ClassName}) исцеляет {Heal()} единиц здоровья";
}
public class Paladin : Character
{
public Paladin(string PlayerName) : base("Paladin", PlayerName)
{ }
public override int DealDamage() => 10;
public override int Heal() => 10;
}
public class Mage : Character
{
public Mage(string PlayerName) : base("Mage", PlayerName)
{ }
public override int DealDamage() => 20;
public override int Heal() => 0; //маги не лечат
}
public class Druid : Character
{
public Druid(string PlayerName) : base("Druid", PlayerName)
{ }
public override int DealDamage() => 5;
public override int Heal() => 15;
}
public abstract class Item
{
public string ItemName { get; protected set; }
public int DamageModifier { get; protected set; }
public int HealMultipler { get; protected set; }
public Item(string ItemName, int DamageModifier, int HealMultipler)
{
this.ItemName = ItemName;
this.DamageModifier = DamageModifier;
this.HealMultipler = HealMultipler;
}
}
public class Sword : Item
{
public Sword() : base("Sword", 10, 0) { }
}
public class Staff : Item
{
public Staff() : base("Staff", 5, 5) { }
}
public abstract class Specialization : Character
{
protected Character Character;
protected Item Item;
public Specialization(string Specialization, Character Character, Item Item) : base(Specialization, Character.PlayerName)
{
this.Character = Character;
this.Item = Item;
}
}
public class Damager : Specialization
{
public Damager(Character Character) : base("Damager " + Character.ClassName, Character, new Sword())
{ }
public override int DealDamage() => Character.DealDamage() + Item.DamageModifier;
public override int Heal() => Character.Heal() * Item.HealMultipler;
}
public class Healer : Specialization
{
public Healer(Character Character) : base("Healer " + Character.ClassName, Character, new Staff())
{ }
public override int DealDamage() => Character.DealDamage() + Item.DamageModifier;
public override int Heal() => Character.Heal() * Item.HealMultipler;
}
//
Paladin paladin = new Paladin("Babladin");
paladin = new Damager(paladin);
(1,11): error CS0029: Не удается неявно преобразовать тип "Damager" в "Paladin".
Всё, уже разобрался в чём проблема, нужно было сделать так:
Character paladin = new Paladin("Babladin");
paladin = new Damager(paladin);
Но до конца не понятно, почему нет приведения в конструкторе Damager, пожалуйста, объясните кто-нибудь.
Ответы (2 шт):
Дело в том, что и у Paladin и у Damager могут быть какие-то свои дополнительные поля и методы (даже если у вас в реализации их и нет, это не важно - ведь они могут быть), не смотря на то, что они унаследованы от одного базового класса. Поэтому использовать их оба как базовый класс Character - можно, они оба реализуют поля и методы этого класса, проблем не будет. А вот использовать одного наследника в качестве другого - нельзя, потому что у них могут отличаться поля и методы.
Ваше преобразование называют преобразование типов статей и объяснений много.
Но до конца не понятно, почему нет приведения в конструкторе Damager, пожалуйста, объясните кто-нибудь.
Конструкторы это специальные методы которые не возращяют тип. Посмотрите по внимательнее. Это специальный метод(ы) для инициализации объекта (экземпляра класса). Преобразовать в нем можно что угодно, вот только вернуть не получится. Возращяет он всегда ссылку на созданный экземпляр класса (this)