2015-06-16 4 views
0

Я хочу высмеять реализацию метода класса Test2 Parent, чтобы он возвращал дочернюю реализацию.Откажитесь от реализации метода родительского класса?

public class Program 
{ 
    static void Main(string[] args) 
    { 
     var child = new Child(); 
     child.print(); 
     Console.ReadLine(); 
    } 
} 
//Parent Class 
public class Parent 
{ 
    public void print() 
    { 
     Test1(); 
    } 
    protected void Test1() 
    { 
     Test2(); 
    } 

    protected void Test2() 
    { 
     Console.WriteLine("Parent Test2"); 
    } 
} 

//Child Class 
public class Child : Parent 
{ 
    protected void Test2() 
    { 
     Console.WriteLine("Child Test2"); 
    } 
} 

Выход: Родитель Test2

Но я хочу выход быть Child Test2. Есть ли способ сделать это без изменения кода в родительском классе.

+2

Почему это связано с Java? – mhlz

+0

Потому что его вопрос, связанный с ООП. Извините, если я этого не сделаю. – TBAG

+0

Включить теги, которые непосредственно касаются вашей проблемы. –

ответ

1

Test2 потребности быть отмеченными как virtual в Parent и override в Child иметь семантику вы хотите.

Невозможно использовать семантику без изменения класса Parent.

+0

Спасибо за ваш ответ. Но я не хотел менять код в классе родителей – TBAG

+0

@TBAG Тогда вам не повезло. Реализация «Родитель», которую вы предоставили, активно препятствует поведению, которое вы хотите. Он специально разработан, чтобы * предотвратить * любые дочерние классы от переопределения поведения его методов, делая их не виртуальными. – Servy

0

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

Посмотрите на эту статью: http://www.codeproject.com/Articles/37549/CLR-Injection-Runtime-Method-Replacer

Короче говоря, что вы должны сделать, чтобы получить дескриптор метода во время выполнения и заменить его на другой метод, который implementes вызов в том, как вам нравится. Затем вы можете использовать отражение для доступа к любому другому методу.

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

0

Если вы действительно хотите сделать это, не имея virtual в Parent, вы можете определить следующее Child:

public new void print() 
    { 
     Test2(); 
    } 

Затем измените определение Test2() также включать new ключевое слово. Однако я бы не рекомендовал это, просто объявив Test2()virtual, если вы можете ему помочь.

Простое определение обоих методов уже скроет реализацию в базовом классе, но добавление ключевого слова new делает его явным, что это то, что вы намереваетесь сделать. Без ключевого слова вы также получите предупреждение о компиляторе.

+0

Добавление 'нового 'здесь только для удаления предупреждения, ничего не изменит. В частности это означает, что * у него все еще нет желаемой семантики *, и его программа будет вызывать неправильную реализацию 'Test2'. – Servy

+0

@Servy Я уже сказал это в своем ответе. Вот почему он должен создать метод 'print()' в 'Child', чтобы скрыть реализацию в' Parent'. – Lunyx

Смежные вопросы