2014-08-29 3 views
-1

Я просто немного поиграю с наследованием и/или полиморфизмом на C#, и так как мои навыки ООП очень, очень простые, мне интересно, возможно ли это :C#: переопределить унаследованный метод, но не для всего класса

у меня есть класс, который наследует метод из базового класса:

class BaseClass { 
    public void Init() { 
     // Do basic stuff. 
    } 
} 

class LoginTest : BaseClass { 
    public void StraightMethod() { 
     // Do stuff based on the actions in the inherited Init() method from BaseClass. 
    } 

    public void ExceptionMethod() { 
     // Do stuff where I don't want to do the actions in the inherited method. 
     // That is, skip or override the Init() method in the BaseClass class. 
    } 
} 

Я знаю, что могу переопределить метод Init() для всего класса, но можно изменить его, либо код в он, только для метода ExceptionMethod()? Эти методы запускаются исключительно, так что, например, одна инициализация класса LoginTest будет работать только с LoginClass.ExceptionMethod(), а другая может работать LoginClass.StraightMethod().

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

Обратите внимание, что эти классы и методы являются методами UnitTest, поэтому метод Init() является методом [TestInitialize]. Следовательно, он вызывается автоматически, когда LoginTest наследует от BaseClass.

+0

Вы можете только переопределить абстрактный или виртуальный метод. Что вы подразумеваете под переопределением внутри метода? – Habib

+0

Я думаю, вы запутаны. «Init» - это всего лишь метод, вы не «переопределяете его» только для одного другого метода. В какой момент вы все равно называете «Init»? Если вам нужно, чтобы он вызывался иногда, но не другие, тогда вы должны явно называть его, когда это необходимо, и иначе вызывать другой метод. Это не имеет особого отношения к полиморфизму. – Mashton

+1

Это логически невозможно; вы вызываете 'Init()' прежде, чем вы узнаете, какая функция будет вызвана. – SLaks

ответ

0

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

3

Нет, вы не можете выборочно переопределить метод Init, но, сделав Init виртуальный метод, вы можете указать, какую версию методы вы хотите позвонить с base и this ключевыми словами:

class BaseClass 
{ 
    // This method must become virtual 
    public virtual void Init() 
    { 
     // Do basic stuff. 
    } 
} 

class LoginTest : BaseClass 
{ 
    public override void Init() 
    { 
     // Other stuff 
    } 

    public void StraightMethod() 
    { 
     // Do stuff based on the actions in the inherited Init() method from BaseClass. 
     base.Init(); 
    } 

    public void ExceptionMethod() 
    { 
     // Do stuff where I don't want to do the actions in the inherited method. 
     // That is, skip or override the Init() method in the BaseClass class. 
     this.Init(); 
    } 
} 
0

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

class BaseClass { 
    public virtual void Init() { 
     // Do basic stuff. 
    } 

} 

class LoginTest : Baseclass { 

    public override void Init() { 
     //do overridden stuff 
    } 
    public void StraightMehthod() { 
     this.Init(); // Call the overridden 
    } 

    public void ExceptionMethod() { 
     base.Init(); // Call the base specifically 
    } 
} 

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

-1

У вас также есть возможность сделать это.

class BaseClass 
{ 
    public void Init() 
    { 
     // Do basic stuff. 
     Console.WriteLine("BaseClass.Init"); 
    } 
} 

class LoginTest : BaseClass 
{ 
    public void StraightMehthod() 
    { 
     // Do stuff based on the actions in the inherited Init() method from BaseClass. 
     base.Init(); 
    } 

    public void ExceptionMethod() 
    { 
     // Do stuff where I don't want to do the actions in the inherited method. 
     this.Init(); 
     // That is, skip or override the Init() method in the BaseClass class. 
    } 

    private new void Init() 
    { 
     Console.WriteLine("LoginTest.Init"); 
    } 
} 
+0

На этом этапе вы можете просто дать методу другое имя. Это было бы функционально идентично и заметно яснее. – Servy

+0

Я просто хотел, чтобы все знали о новом ключевом слове, поскольку никто не прокомментировал это, и многие говорили, что это невозможно. – John

+0

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

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