2013-12-16 2 views
2

ключевого слова виртуальных/переопределить только увидеть эту программуЧто касается C# OOPS использования

class A 
     { 
       public void Foo() { Console.WriteLine("A::Foo()"); } 
     } 

     class B : A 
     { 
       public void Foo() { Console.WriteLine("B::Foo()"); } 
     } 

     class Test 
     { 
      static void Main(string[] args) 
      { 
       A a; 
       B b; 

       a = new A(); 
       b = new B(); 
       a.Foo(); // output --> "A::Foo()" 
       b.Foo(); // output --> "B::Foo()" 

       a = new B(); 
       a.Foo(); // output --> "A::Foo()" 
      } 
     } 

1) как класс может иметь функцию, имеющую такие же имя. класс A имеет функцию foo(), а класс b имеет функцию foo(), когда класс b влечет A., когда класс b продляет a, то по классу наследования b получает функцию foo(). почему приведенный выше код работает без ошибок?

2)

 a = new B(); 
     a.Foo(); // output --> "A::Foo()" 

, что значение а = новый B()?

Мы создаем экземпляр B, если да, тогда, когда мы пишем a.Foo(), тогда функция foo() класса b должна вызывать, но функция foo() класса a вызывается почему ??

При добавлении ключевого слова virtual/override функция foo() класса b вызывается.

class A 
     { 
      public virtual void Foo() { Console.WriteLine("A::Foo()"); } 
     } 

     class B : A 
     { 
      public override void Foo() { Console.WriteLine("B::Foo()"); } 
     } 

     class Test 
     { 
      static void Main(string[] args) 
      { 
       A a; 
       B b; 

       a = new A(); 
       b = new B(); 
       a.Foo(); // output --> "A::Foo()" 
       b.Foo(); // output --> "B::Foo()" 

       a = new B(); 
       a.Foo(); // output --> "B::Foo()" 
      } 
     } 

поэтому, пожалуйста, объясните, что происходит за сценой. спасибо

ответ

0

В вашем втором примере B.FooпереопределяетA.Foo, что означает, что логика метода является быть заменен.

В вашем первом примере, однако, B.Foo is hidingA.Foo Реализация. Наследования нет. Итак, если переменная типа A содержит экземпляр типа B (т. Е. A a = new B();), вместо этого будет использоваться реализация A.


мы можем непосредственно создать экземпляр б и вызвать Foo(), но почему люди написать такой код Аа = новый B(), а затем вызвать a.foo()? какой вид цели можно достичь, написав такой код. благодаря

Вместо того, чтобы спрашивать, почему бы вы написать A a=new B(), спросите себя: почему вы хотели бы использовать метод new?

Одной из причин может быть преодоление того факта, что вы не можете переопределить A.Foo, поскольку он не был помечен как виртуальный. Предположим, вам предоставлен класс A, реализованный на сторонней сборке, которую вы не можете изменить. Если продлить этот класс с собственным классом B, то вы скрыть его реализация с помощью метода new и написать B b = new B(); b.Foo();

+0

, мы можем напрямую создать экземпляр b и вызвать foo(), но почему люди пишут такой код A a = new B(), а затем вызывают a.foo()? какая цель может быть достигнута при написании такого кода. спасибо – Thomas

+0

@Thomas см. мой обновленный ответ. – dcastro

2

, когда класс b продлевает a, то по классу наследования b получает функцию foo(). почему приведенный выше код работает без ошибок?

Поскольку член в B просто скрывается член, на A.

В чем смысл a = new B()?

С B реализует A, вы создаете экземпляр B и введя его в качестве A, когда вы используете его везде. Вот почему функция в классе A вызывается вместо B.

При добавлении ключевого слова virtual/override функция foo() класса b получает вызов.

Причина B становится здесь называют, потому что это на самом деле переопределяя функциональность A.

+0

u сказал: Потому что член в B просто скрывает член в A. Я предполагаю, что мы используем новое ключевое слово для скрытия, но в том, что выше ключевое слово никогда не используется. так как программа выполняется правильно? – Thomas

+1

@Thomas, ключевое слово 'new' не * необходимо * для скрытия. Это просто делает его явным. * –

+0

мы можем напрямую создать экземпляр b и вызвать foo(), но почему люди пишут такой код A a = new B(), а затем вызывают a.foo()? какая цель может быть достигнута при написании такого кода. спасибо – Thomas

1

Когда вы объявляете метод с тем же именем, он скрывает метод.

Если вы хотите, чтобы вызвать унаследованный метод, вы можете сделать это:

var b = new B(); 

var casted = (A)b; 

casted.Foo(); // will call A.Foo 

Если ваше намерение перезаписать функциональность Foo в B, то вы можете использовать new ключевое слово в B:

public new void Foo() { ... } 

Или используйте virtual и override как вы заявили.

+0

мы можем напрямую создать экземпляр b и вызвать foo(), но почему люди пишут такой код A a = new B(), а затем вызывают a.foo()? какая цель может быть достигнута при написании такого кода.спасибо – Thomas

1

почему выше код запуска без ошибок?

Он производит предупреждение: 'B.Foo()' hides inherited member 'A.Foo()'. Use the new keyword if hiding was intended.

Так компилятор предупреждает вас о потенциальной ошибке, но она действует и B.Foo методы скрывает A.Foo один.

мы создаем экземпляр B, если да, то когда мы пишем a.Foo(), то Foo() функция класса Ь следует называть, но Foo() функция класса А вызывался почему ??

Вы звоните Foo по переменной A. Поэтому, даже если этот экземпляр A имеет тип B, вы вызываете метод с переменной A.

+0

мы можем напрямую создать экземпляр b и вызвать foo(), но почему люди пишут такой код A a = new B(), а затем вызывают a.foo()? какая цель может быть достигнута при написании такого кода. благодаря – Thomas

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