Как заставить подклассы автоматически вызывать методы суперкласса - PullRequest
1 голос
/ 16 мая 2019

Я новый разработчик c # и использую unity3d для разработки игры. Я разрабатываю интерфейс для реализации системы навыков в игре. Но я нахожу некоторые проблемы. Здесь много классов Skill, и я должен вручную вызвать метод show() внутри их apply.

interface ISkill
{
    void apply();
}

class Base
{
    protected string name { get; set; }
    protected void show()
    {
        Console.WriteLine("show:"+name);
    }
}

class Skill1 : Base, ISkill
{
    public Skill1()
    {
        name = "skill1";
    }
    public void apply()
    {
        show();
        Console.WriteLine("skill1 apply");
    }

}
class Skill2 : Base, ISkill
{
    public Skill2()
    {
        name = "skill2";
    }
    public void apply()
    {
        show();
        Console.WriteLine("skill2 apply");
    }

}
Skill3
Skill4
etc.. 

class Program
{
    public static void Main(string[] args)
    {
        ISkill skill = new Skill2();
        skill.apply();

    }
}

Как изменить мой код, чтобы все классы SkillX могли автоматически вызывать метод show() в методе apply()?

Ответы [ 2 ]

2 голосов
/ 16 мая 2019

Стандартным решением для этого является шаблонный метод .

Базовый класс реализует метод как «шаблон», который заставляет производные классы предоставлять определенный шаг (и) для этого метода. В вашем случае класс Base должен реализовывать метод Apply, который сначала вызывает Show, а затем делегирует остальное производным классам, вынуждая их предоставлять реализацию второй части через abstract void ApplyImplementation():

interface ISkill
{
    void Apply();
}

public abstract class Base
{
    protected string name { get; set; }
    protected Base(string name)
    {
       this.name = name;
    }

    protected void Show()
    {
        Console.WriteLine("show:"+name);
    }

    // "template" method. 
    public void Apply()
    {
        Show(); 
        ApplyImplementation();
    }

    // derived class must implement that method
    protected abstract void ApplyImplementation();
}

class Skill1 : Base, ISkill
{
    public Skill1()
    {
        name = "skill1";
    }
    protected override void ApplyImplementation()
    {
        Console.WriteLine("skill1 apply");
    }
}
0 голосов
/ 16 мая 2019

Нет общего решения, кроме как попытаться вывести общность разных классов на базу.

В вашем случае, поскольку единственное различие между apply(), по-видимому, заключается в названии навыка, и у вас уже есть его как свойство экземпляра, вы можете вытянуть apply до Base и получить одинаковая реализация для всех дочерних классов Base.

interface ISkill
{
    void apply();
}

class Base : ISkill
{
    protected string name { get; set; }
    protected Base(string name)
    {
        this.name = name;
    }
    public void apply()
    {
        show();
        Console.WriteLine(name + " apply");
    }

    private void show()
    {
        Console.WriteLine("show:"+name);
    }
}

class Skill1 : Base
{
    public Skill1(): base("skill1"){}    
}
class Skill2 : Base
{
    public Skill2(): base("skill2"){}    
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...