Вызывать один и тот же переопределенный метод один за другим в нескольких классах - PullRequest
1 голос
/ 01 июля 2019

У меня есть один базовый класс C1, который обеспечивает реализацию по умолчанию пары методов как C2 и множество пользовательских реализаций Cx (+20), которые выглядят так:

abstract class C1
{
    public abstract void M1();
}

abstract class C2 : C1
{
    // other overridden members ...

    // M1(); has no default implementation yet.
}

class Cx : C2
{
    public override void M1()
    {
        // ...
    }
}

Теперь я бы хотел связать C2.M1 и Cx.M1, потому что мне нужно добавить новую общую функциональность. Обычно я создаю новый абстрактный метод и вызываю его вторым base классом, подобным этому:

abstract class C1
{
    public abstract void M1();
}

abstract class C2 : C1
{   
    // M1 should get a default implementation 
    // and then M1 in the next derived class should be called
    public override void M1()
    {
        // ...
        M1Internal();
    }

    protected abstract void M1Internal();
}

class Cx : C2
{
    protected override void M1Internal()
    {
        // ...
    }
}

Тем не менее, у меня более 20 таких классов, и их обновление - большая работа, поэтому мне было интересно, есть ли другой способ, который позволил бы мне переопределить M1 в C2 и Cx и вызвать их в этом порядке C1.M1() затем Cx.M1() без создания нового вспомогательного метода промежуточный . Есть ли лучший образец для таких случаев?

Ответы [ 2 ]

3 голосов
/ 01 июля 2019

Я думаю, что лучше использовать шаблон декоратора в этом случае.Используйте композицию, а не наследование, если это возможно.

abstract class C1
{
    public abstract void M1();
}

class Cx : C1
{
    public override void M1()
    {
        // ...
    }
}

class CxWithCommonBehavior : C1
{
    C1 realObject;

    public CxWithCommonBehavior(C1 realObject)
    {
        this.realObject = realObject;
    }

    public override void M1()
    {
        // common behavior
        realObject.M1();
    }
}

Обратите внимание, что вам нужен только один класс CxWithCommonBehavior для всех производных классов Cx - вы передаете декорированный экземпляр в конструкторе.

Таким образом, вы можетедобавить больше поведений, связать их всеми возможными способами и даже добавить или удалить их во время выполнения

1 голос
/ 01 июля 2019

А как насчет простого вызова base.M1 на Cx.M1?

class Cx : C2
{
    protected override void M1()
    {
        base.M1();//i.e. C2.M1()
        //Cx.M1 internal logic
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...