调用父方法时调用子方法

本文关键字:调用 子方法 方法 | 更新日期: 2023-09-27 18:37:19

我有一个类,它有一个方法:

public class A{
    public virtual void doChanges (String message, object[] args){
    }
}

一些类在"A"中使用"doChange"方法:

public class MethodClaller{
    A a = new A();
    public void caller(){
        a.doChanges ("Test",null);
    }
}

所有子类都应该覆盖doChanges:

public class B:A{
    public override void doChanges(String message, object[] args){
    }
}

问题是:我想在几个程序(如组件)中使用 A 和类 MethodCaller,在每个程序中,方法 doChange 应该自动调用 A 的所有子项,只要 doChange 调用 A

new MethodCaller.call();

应该在 B 的所有实例中调用 doChanges

这听起来像是事件处理。但我不知道该怎么做。如果 AB 不是相对的,作为解决方案中的父项和子项并不重要。我只是觉得这是正确的结构。

调用父方法时调用子方法

您正在使用模式顺序的继承。

与其BA继承(这只是两个类之间的静态依赖项),不如注册B实例,以便A的实例可以委托。查找委派模式以了解此句子。

这样做是概念上的第一步,但稍后你可能会(没有人能肯定地说)最终会得到更大的东西,即复合模式。

要在复合中自动注册实例,您将使用创建工厂模式。

它将是这样的:

  • A将允许其实例是复合的;
  • B将是一个可以附加到A的组件;
  • 您将喜欢B上的工厂方法来实例化需要A实例的B元素:

    A a; // get the instance "a" from somewhere
    B.Create(a); // will create an instance of B and attach it to a
    

要强制使用此用法,您需要像往常一样private B的构造函数(请参阅工厂模式)。

Create()将是这样的:

private B() // prevent direct instance creation
{
    // ...
}
public static void Create(A a)
{
    B b;
    b = new B();
    a.Register(b);
}

所以你确定所有的B都符合一个A(类比你的要求,所有B必须扩展A)。

A Register()将是:

private List<B> _bs = new List<B>();
public void Register(B b)
{
    _bs.Add(b);
}

A Do()将是:

public void Do(object args)
{
    // pre-procedure of A
    foreach (B b in _bs)
    {
        b.Do(args);
    }
    // post-procedure of A
}

现在,为了确保B在不使用类之间的静态依赖关系的情况下实现Do()方法,通过定义组件接口来利用复合模式:

interface AComponent
{
    void Do(object args);
}

从中得出B

class B implements AComponent
{
    ...

最后引用接口(而不是B)来自A

private List<AComponent> _components = new List<AComponent>();
public void Register(AComponent component)
{
    _components.Add(component);
}
public void Do(object args)
{
    // pre-procedure of A
    foreach (AComponent component in _components)
    {
        component.Do(args);
    }
    // post-procedure of A
}

最后一步是使用复合接口将B与创建方法中的A分离:

interface AComposite
{
    void Register(AComponent component);
}

从中得出A

class A implements AComposite
{
    ...

使用创建方法中的接口:

public static void Create(AComposite composite)
{
    composite.Register(new B());
}

现在,您已经松散地耦合了AB但必须在A实例上注册B实例,以便在Do()触发时,B的所有实例也会触发其Do()方法。

作为一个好处,您可以实现与B完全不同的AComponent(根据继承),并且仍然让它们触发其Do()方法。你甚至可以混淆不同AComponent实现的实例,就像多态性允许通过虚拟方法一样。

这对你有什么意义吗?