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

namespace LearnOverride
{
    class Program
    {
        static void Main(string[] args)
        {
            Owner owner = new Owner();
            Safe safe = new Safe();

            Console.WriteLine("When \tLocksmith locksmith = new Locksmith();\n");
            Locksmith locksmith = new Locksmith();
            locksmith.OpenSafe(safe, owner);
            Console.WriteLine("when ReturnContents() called from main,");
            Jewels openedLocksmith = safe.Open("12345");
            locksmith.ReturnContents(openedLocksmith, owner);
            Console.WriteLine();

            Console.WriteLine("\n\nWhen \tJewelThief jewelThief = new JewelThief();\n");
            JewelThief jewelThief = new JewelThief();
            jewelThief.OpenSafe(safe, owner);
            Console.WriteLine("when ReturnContents() called from main,");
            Jewels opened = safe.Open("12345");
            jewelThief.ReturnContents(opened, owner);
            Console.WriteLine();

            Console.WriteLine("\n\nWhen \tLocksmith jewelThiefAsLocksmith = new JewelThief();\n");
            Locksmith jewelThiefAsLocksmith = new JewelThief();
            jewelThiefAsLocksmith.OpenSafe(safe, owner);
            Console.WriteLine("when ReturnContents() called from main,");
            Jewels j = safe.Open("12345");
            jewelThiefAsLocksmith.ReturnContents(j, owner);

            ///JewelThief jewelThief = new Locksmith(); is error
            Console.ReadKey();
        }
    }

    class Jewels
    {
        public string Sparkle()
        {
            return "Sparkle, sparkle!";
        }
    }

    class Safe
    {
        private Jewels contents = new Jewels();
        private string safeCombination = "12345";
        public Jewels Open(string combination)
        {
            if (combination == safeCombination)
                return contents;
            else
                return null;
        }
        public void PickLock(Locksmith lockpicker)
        {
            lockpicker.WriteDownCombination(safeCombination);
        }
    }

    class Owner
    {
        private Jewels returnedContents;
        public void ReceiveContents(Jewels safeContents)
        {
            returnedContents = safeContents;
            Console.WriteLine("Owner:Thank you for returning my jewels! " + safeContents.Sparkle());
        }
    }

    class Locksmith
    {
        public void OpenSafe(Safe safe, Owner owner)
        {
            safe.PickLock(this);
            Jewels safeContents = safe.Open(writtenDownCombination);
            this.ReturnContents(safeContents, owner);
        }

        private string writtenDownCombination = null;
        public void WriteDownCombination(string combination)
        {
            writtenDownCombination = combination;
        }
        public void ReturnContents(Jewels safeContents, Owner owner)
        {
            owner.ReceiveContents(safeContents);
        }
    }

    class JewelThief : Locksmith
    {
        private Jewels stolenJewels = null;
        public void ReturnContents(Jewels safeContents, Owner owner)
        {
            stolenJewels = safeContents;
            Console.WriteLine("JewelThief:I'm stealing the contents! " + stolenJewels.Sparkle());
        }
    }
}

The above code is not overriding the method ReturnContents(). It is hiding. So I was expecting the statement

this.ReturnContents(safeContents, owner);

present in Locksmith class(inside OpenSafe() method), will call ReturnContents() method present Jewelthief object if refer from object 'JewelThief'.

But every time it calls baseclass method, ReturnContents. How this behavior is explained?

有帮助吗?

解决方案

In C#, you have to declare your virtual methods. Maybe you are thinking about JAVA?

Change your method signatures to:

public virtual void ReturnContents(Jewels safeContents, Owner owner)

for the base class, and :

public override void ReturnContents(Jewels safeContents, Owner owner)

for the child class.

Hiding happens when a child class redefines a method that a base class has already defined. In this case, the run-time will invoke the method of the referenced type and not use polymorphism. If this behavior is desired, you should mark the method in the subclass with the "new" keyword. If you want to use polymorphism however, you need to declare the base class's method as virtual and use the "override" keyword for the method in the child class.

You would use hiding in the case where you want to use most of the code in a base class, but you want to have new behavior in your class for a certain method and expose this to all sub-classes of the one you are defining to use hiding. This would keep from altering the behavior of the base class for its internal calls to the method, but would still allow you to offer a new implementation to the users of your new class.

其他提示

If you dont want to Override the method you can hide it by using the new operator

    public new void ReturnContents(Jewels safeContents, Owner owner)
    {
        stolenJewels = safeContents;
        Console.WriteLine("JewelThief:I'm stealing the contents! " + stolenJewels.Sparkle());
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top