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

上記のコードは、メソッド ReturnContents() をオーバーライドしていません。隠れています。だから発言を期待してた

this.ReturnContents(safeContents, 所有者);

Locksmith クラス (OpenSafe() メソッド内) に存在し、オブジェクト 'JewelThief' から参照される場合、ReturnContents() メソッドが呼び出され、Jewelthief オブジェクトが存在します。

しかし、ベースクラス メソッドを呼び出すたびに、ReturnContents. この動作はどのように説明されますか?

4

2 に答える 2

4

C# では、仮想メソッドを宣言する必要があります。多分あなたはJAVAについて考えていますか?

メソッド シグネチャを次のように変更します。

public virtual void ReturnContents(Jewels safeContents, Owner owner)

基本クラスの場合、および:

public override void ReturnContents(Jewels safeContents, Owner owner)

子クラス用。

非表示は、基本クラスが既に定義したメソッドを子クラスが再定義するときに発生します。この場合、ランタイムは参照された型のメソッドを呼び出し、ポリモーフィズムを使用しません。この動作が必要な場合は、サブクラスのメソッドを「new」キーワードでマークする必要があります。ただし、ポリモーフィズムを使用する場合は、基本クラスのメソッドを仮想として宣言し、子クラスのメソッドに「override」キーワードを使用する必要があります。

基本クラスでほとんどのコードを使用したいが、特定のメソッドに対してクラスに新しい動作を持たせ、これを定義しているクラスのすべてのサブクラスに公開したい場合は、非表示を使用します。隠蔽を使用します。これにより、メソッドへの内部呼び出しの基本クラスの動作が変更されなくなりますが、新しいクラスのユーザーに新しい実装を提供することはできます。

于 2013-03-04T05:39:37.377 に答える
0

メソッドを使用したくない場合は、演算子Overrideを使用して非表示にすることができますnew

    public new void ReturnContents(Jewels safeContents, Owner owner)
    {
        stolenJewels = safeContents;
        Console.WriteLine("JewelThief:I'm stealing the contents! " + stolenJewels.Sparkle());
    }
于 2013-03-04T05:43:58.040 に答える