Общий вопрос о наследовании в .NET Framework - PullRequest
1 голос
/ 03 мая 2010

У меня общий вопрос о наследовании в .NET Framework. Допустим, у вас есть 2 класса, первый называется Parent, а второй - Child. Ребенок наследует от родителя.

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

Исходя из моего опыта, если я буду обрабатывать onLoad в родительском, а не в дочернем элементах, будет запускаться код onLoad для родителей, но если он обрабатывается в обоих классах, будет запускаться только дочерний код.

Это правильно? и если да, то как я могу обеспечить, чтобы код родителей всегда срабатывал для ребенка ...

Ответы [ 5 ]

7 голосов
/ 03 мая 2010

Вы обнаружили проблему хрупкого базового класса . Один из способов справиться с этим - это шаблон:

public class Parent
{
    public void OnLoad()
    {
        // Important load stuff goes here
        OnLoadInternal();
    }

    protected virtual void OnLoadInternal()
    {
        // No implmentation in parent; child can override if needed
    }
}

public class Child : Parent
{
    protected override void OnLoadInternal()
    {
        base.OnLoadInternal();

        // Important load stuff, but can't break parent by omitting base call
    }
}

Родитель гарантированно заставит свой метод OnLoad делать то, что должен, но дочернему элементу предоставляется способ добавить дополнительную обработку путем переопределения OnLoadInternal.

2 голосов
/ 03 мая 2010

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

public partial class Parent : Form
{
    public Parent()
    {
        InitializeComponent();
        Load += ParentLoad;
    }

    private void ParentLoad(object sender, EventArgs e)
    {
        throw new NotImplementedException();
    }
}
2 голосов
/ 03 мая 2010

В C # используйте base.methodNameHere() от дочернего элемента для вызова методов родительского класса.

В этом случае вызовите base.onLoad() из метода onLoad () вашего ребенка для выполнения кода родителя.

1 голос
/ 03 мая 2010

Два установленных шаблона в .NET SDK - это виртуальные функции и события.

Виртуальные функции

class Parent {
  virtual protected void OnLoad() {
    //code here
  } 
}

class Child {
  protected override void OnLoad() {
    base.OnLoad();
  }
}

В этом сценарии вы предоставляете дочернему классу возможность полностью переопределять поведение OnLoad, включая возможность не выполнять базовый класс OnLoad (что может быть вполне допустимым случаем).

Использование событий

В качестве альтернативы вы можете использовать события, которые позволяют дочернему классу выполнять дополнительную работу без возможности переопределения поведения базового класса:

class Parent {
  public event Load;
  public Parent() {
    this.Load+=OnLoad();
  }
  private void OnLoad() {
    //Parent code here
  } 
}

class Child {
  public Child() {
    this.Load+=OnLoad();
  }
  private void OnLoad() {
    //Child code here
  }
}

Это действительно дизайнерский выбор. Если вы хотите, чтобы инфраструктура помогла вам в принудительном выполнении родительского кода, перейдите к варианту 2.

1 голос
/ 03 мая 2010

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

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