Можем ли мы изменить определения методов класса прародителя? - PullRequest
0 голосов
/ 06 июля 2018

Я работал над определенной проблемой и обнаружил внутри интересную проблему.

Позвольте мне объяснить на примере (код C #)

public class A: IA
{
    protected abstract void Append(LoggingEvent loggingEvent)
    { 
          //Some definition
    }
}


public class B: A
{
    protected override void Append(LoggingEvent loggingEvent)
    { 
          //override definition
    }
}



public class MyClass: B
{
    //Here I want to change the definition of Append method.
}

Классы A и B принадлежат к определенной библиотеке, и я не могу изменить эти классы.

Ответы [ 2 ]

0 голосов
/ 06 июля 2018

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

  1. Добавлен пустой интерфейс IA, поскольку класс A не реализует какой-либо публичный метод.
  2. Определен класс A как абстрактный, так как любой неабстрактный класс не может определить абстрактный метод.
  3. Удалено тело для метода Append внутри класса A, так как абстрактный метод не может иметь тело.

    public interface IA
    {
    
    }
    
    public abstract class A : IA
    {
        protected abstract void Append();
    
    }
    
    public class B : A
    {
        protected override void Append()
        {
            //override definition
        }
    }
    
    public class MyClass : B
    {
        //Here I want to change the definition of Append method.
    
        //You can do is hide the method by creating a new method with the same name
        public new void Append() { }
    }
    

Ответ: Вы не можете переопределить не виртуальный метод. Самое близкое, что вы можете сделать, это скрыть метод, создав новый метод с тем же именем, но это не рекомендуется, поскольку оно нарушает принципы хорошего дизайна. Но даже сокрытие метода не даст вам времени выполнения полиморфной отправки вызовов метода, как истинный вызов виртуального метода.

0 голосов
/ 06 июля 2018

Поскольку ни один из методов в иерархии здесь не является sealed, вы можете просто переопределить метод самостоятельно:

public class MyClass: B
{
    protected override void Append(LoggingEvent loggingEvent)
    { 
          // New logic goes here...
    }
}
...