3

I have this code but I just can't understand it.

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();
        }
    }    
}

I thought Student.Write() would be called in both cases, so I was puzzled by what I got:

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

Why is Person.Write() called instead of 'Student.Write()`?

FMM
  • 4,289
  • 1
  • 25
  • 44
Robotronx
  • 1,728
  • 2
  • 21
  • 43
  • 2
    Overriding and shadowing are different things. http://stackoverflow.com/questions/392721/difference-between-shadowing-and-overriding-in-c – Oded Jan 12 '12 at 20:30

3 Answers3

5

The new keyword indicates that you do not intend to override the base class's Write() method (you can't anyway, since Person's Write() method isn't marked virtual). Since you're calling it via IStoreable, there's nothing about the IStoreable interface that links it to the Student class. Since Write() is not marked virtual, polymorphism for this function doesn't apply.

FMM
  • 4,289
  • 1
  • 25
  • 44
  • So, when I call `Write()` using the reference of the interface type, the method that will be executed is the one that has been implemented in the class that implemented the interface originally (`Person` in this case)? – Robotronx Jan 12 '12 at 20:37
  • 1
    Yes, because the base class didn't mark the `Write()` method `virtual`; therefore, subclasses of it can't `override` it. – FMM Jan 12 '12 at 20:44
  • So the only thing that `IStoreable` is linked to is the base class `Person` and all the conclusions about which method to call (when calling via `IStoreable`) are drawn from that fact? (Sorry for asking practically the same thing, but I want to make sure I understand correctly) – Robotronx Jan 13 '12 at 07:24
1

Student as an IStoreable cannot see the Student.Write method since it is not overriden from the base class Person. Why is it not marked virtual, and why have you used the new keyword to hide the base class's implementation?

Jeb
  • 3,689
  • 5
  • 28
  • 45
  • It is just an example in a textbook from the local college. It was loaned to me so I found this example in it and could not figure it out. – Robotronx Jan 12 '12 at 20:40
  • Ah I see, it's a good question. Oded's comment on your question is a good reference too. – Jeb Jan 12 '12 at 20:42
0

Make the person's write method Virtual. When you mark it new it does not act as an inherited method. When you mark the method virtual that means you provide an implementation and can override it by a child class. Abstract requires you implementat a method (just a little more fyi).

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()"); } 

"When used as a modifier, the new keyword explicitly hides a member inherited from a base class" via

Brad Semrad
  • 1,501
  • 1
  • 11
  • 19