Вызов метода класса через интерфейс, реализованный базовым классом c # - PullRequest
2 голосов
/ 13 января 2012

У меня есть этот код, но я просто не могу его понять.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1 {
    interface IStoreable {
        void Read();
        void Write();
    }
    class Person : IStoreable {
        public virtual void Read() { Console.WriteLine("Person.Read()"); }
        public void Write() { Console.WriteLine("Person.Write()"); }
    }
    class Student : Person {
        public override void Read() { Console.WriteLine("Student.Read()"); }
        public new void Write() { Console.WriteLine("Student.Write()"); }
    }
    class Demo {
        static void Main(string[] args) {
            Person s1 = new Student();
            IStoreable isStudent1 = s1 as IStoreable;

            // 1
            Console.WriteLine("// 1");
            isStudent1.Read();
            isStudent1.Write();           

            Student s2 = new Student();
            IStoreable isStudent2 = s2 as IStoreable;

            // 2
            Console.WriteLine("// 2");
            isStudent2.Read();
            isStudent2.Write();

            Console.ReadKey();
        }
    }    
}

Я думал, что в обоих случаях будет вызываться Student.Write(), поэтому я был озадачен тем, что получил:

// 1
Student.Read()
Person.Write()
// 2
Student.Read()
Person.Write()

Почему Person.Write() вызывается вместо 'Student.Write () `?

Ответы [ 3 ]

4 голосов
/ 13 января 2012

Ключевое слово new означает, что вы не собираетесь переопределять метод Write() базового класса (в любом случае вы не можете этого сделать, поскольку метод Person *1003* не помечен virtual). Поскольку вы вызываете его через IStoreable, в интерфейсе IStoreable нет ничего, что связывало бы его с классом Student. Поскольку Write() не помечен virtual, полиморфизм этой функции не применяется.

0 голосов
/ 13 января 2012

Студент как IStoreable не может видеть метод Student.Write, так как он не переопределяется из базового класса Person. Почему он не помечен как виртуальный, и почему вы использовали ключевое слово new, чтобы скрыть реализацию базового класса?

0 голосов
/ 13 января 2012

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

class Person : IStoreable { 
    public virtual void Read() { Console.WriteLine("Person.Read()"); } 
    public virtual void Write() { Console.WriteLine("Person.Write()"); } 
} 
class Student : Person { 
    public override void Read() { Console.WriteLine("Student.Read()"); } 
    public override void Write() { Console.WriteLine("Student.Write()"); } 

"При использовании в качестве модификатора новое ключевое слово явно скрывает член, унаследованный от базового класса" через

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