Robotronx
Robotronx

Reputation: 1818

Calling a method of a class through the interface implemented by the base class c#

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()`?

Upvotes: 3

Views: 959

Answers (3)

Jeb
Jeb

Reputation: 3799

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?

Upvotes: 1

FMM
FMM

Reputation: 4329

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.

Upvotes: 5

Brad
Brad

Reputation: 1529

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

Upvotes: 0

Related Questions