Вызов метода из базового класса в класс с тем же именем, что и у метода - PullRequest
0 голосов
/ 25 марта 2019

Сводка: B Получает вызов от A и автоматически запускает метод запуска

Допустим, у нас есть класс A: A имеет функцию с именем Start, эта начальная функция первоначально вызывается из другого класса (давайте обозначим этот класс как C), и, как только она будет вызвана, она должна вызывать каждый метод из всех классов, используя Start ( и используя его базовый класс), с тем же методом.

И у нас есть B: класс, использующий A в качестве базового класса, его задача - получить метод Start от A, (первоначально вызываемый C). Теперь я мог бы просто сделать это, вызвав метод B напрямую из A, но в этом случае B мог бы быть назван как угодно, так как несколько классов наследовали один и тот же метод.

Это полезно, потому что я не хочу назначать все мои переменные одной стартовой функции. Вместо этого можно создать функцию, которая позволяет вызывать одно и то же имя функции.

Например: вот то, что я думал, это будет выглядеть

class A
{
    public void Start()
    {
        // Call B's Start here...
    }
}

class B : A
{
    public void Start()
    {
        // Receive A's call ... and do stuff here
    }
}


// This time, we also need to access this start method.
// But this class could be named anything
class anotherClass : A
{
    public void Start()
    {
        // Receive A's call
    }
}

class C
{
    static void Main(string[] args)
    {
        A a = new A();

        // Maybe somehow call all start methods here
        a.Start();
    }
}

Но, как вы можете видеть, Start в классе A будет вызываться, но никогда не будет вызывать start в классе B.

В лучшем контексте мне нужен способ вызова всех методов Start из каждого класса.

Ответы [ 3 ]

1 голос
/ 25 марта 2019

Просто используйте ссылку на базовый класс:

// or maybe you want to override??
public new void Start()
{
  base.Start();
}

Используйте его в каждом Start классе вниз в иерархии классов

0 голосов
/ 25 марта 2019

Вы не можете вызывать методы неинициализированных классов.Таким образом, вызов A.Start() не сможет вызвать B.Start(), пока экземпляр B не будет инициализирован.Кроме того, B должен уведомить A о своем существовании.(Если вы не используете отражение, но я не думаю, что это то, что вы хотите)

Вы можете подключить B к событию с пользовательским делегатом:

class Program
{
    static void Main(string[] args) 
    {
        var a = new A();
        var b = new B();
        a.StartHandler += b.Start;
        a.Start();

        // Output:
        // A.Start() starting.
        // B.Start() called.
        // A.Start() ending.
    }
}

class A
{
    public delegate void StartMethod();
    public event StartMethod StartHandler;

    public virtual void Start()
    {
        Console.WriteLine("A.Start() starting.");
        if (this.StartHandler != null)
        {
            this.StartHandler();
        }
        Console.WriteLine("A.Start() ending.");
    }
}

class B : A
{
    public override void Start()
    {
        Console.WriteLine("B.Start() called.");
    }
}

Другим более простым вариантом может быть (в зависимости от того, что вы хотите), сделать это другим способом, с простым наследованием.Если вы создаете экземпляр B, вы можете обращаться с ним как с экземпляром A. Поэтому вам не нужно знать, что вы на самом деле используете тип B под капотом:

class A
{
    public virtual void Start() => Console.WriteLine("A.Start()");
}

class B : A
{
    public override void Start()
    {
        Console.WriteLine("B.Start()");
        base.Start();
    }
}

// usage:
A a = new B();
a.Start();

// Output:
// B.Start()
// A.Start();
0 голосов
/ 25 марта 2019

Вы никогда не создавали объект B или anotherClass.Поэтому их Start метод не может быть вызван.

Наследование работает наоборот.Производный класс может вызывать членов своего базового класса, потому что он знает своего предка и наследует все его члены (поля, свойства, методы).Базовый класс (A) на другой стороне не знает своих потомков.

Вы должны использовать virtual методы, которые вы можете override в производных классах.Пример:

class A
{
    public virtual void Start()
    {
        Console.WriteLine("Starting A");
    }
}

class B : A
{
    public override void Start()
    {
        base.Start();
        Console.WriteLine("Starting B");
    }
}

Теперь вы можете создать B объект и вызвать его Start метод

var b = new B();
b.Start();

Это выдаст:

Starting A
Starting B

Спроизводные типы совместимы по присваиванию с их базовыми типами, вы также можете сделать что-то вроде этого

var list = new List<A> { new B(), new A() };
foreach (A a in list) {
    a.Start();
}
Starting A
Starting B
Starting A

, где две первые строки от B.Start() и последняя от A.Start().


Но это работает только для классов в прямой линии.Вы не можете вызывать методы от братьев и сестер.Зачем?Давайте создадим пример:

class C : A
{
    private string s = "hello";

    public override void Start()
    {
        base.Start();
        Console.WriteLine("Starting C: " + s);
    }
}

Предполагая, что вы можете сделать что-то подобное в B:

sibling(C).Start();

Откуда берется значение "hello" из s?Ни A, ни B не имеют такого поля, а объект C никогда не создавался.Поэтому ваше требование вызывать каждый метод из всех классов не может быть выполнено.Но если бы было задействовано поле A, это сработало бы, так как B наследует это поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...