c# - 隐藏基类中存在的方法

标签 c# .net inheritance overriding method-hiding

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, owner);

存在于 Locksmith 类中(在 OpenSafe() 方法内),如果从对象“JewelThief”引用,将调用 ReturnContents() 方法呈现 Jewelthief 对象。

但是每次调用基类方法时,ReturnContents.如何解释这种行为?

最佳答案

在 C# 中,您必须声明虚拟方法。也许您正在考虑 JAVA?

将方法签名更改为:

public virtual void ReturnContents(Jewels safeContents, Owner owner)

对于基类,并且:

public override void ReturnContents(Jewels safeContents, Owner owner)

针对子类。

当子类重新定义基类已经定义的方法时,就会发生隐藏。在这种情况下,运行时将调用引用类型的方法,而不使用多态性。如果需要这种行为,您应该使用“new”关键字标记子类中的方法。但是,如果您想使用多态性,则需要将基类的方法声明为虚拟方法,并为子类中的方法使用“override”关键字。

如果您想要使用基类中的大部分代码,但您希望在类中为特定方法提供新行为,并将其公开给您所使用的方法的所有子类,则可以使用隐藏。正在定义使用隐藏。这将避免改 rebase 类对方法的内部调用的行为,但仍然允许您向​​新类的用户提供新的实现。

关于c# - 隐藏基类中存在的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15195161/

相关文章:

c# - 无效的对象名称 (ASP.NET MVC)

c# - 如何更新此类/方法以改进代码指标

c++ - 在派生类中作为模板实现的虚函数

c# - 如何在 TPL 数据流中设置/获取/使用 block 的名称?

c# - 使用动态值而不是固定值的范围属性

c# - Parallel.ForEach 性能不佳

c# - AADSTS9002331 : Application is configured for use by Microsoft Account users only. 请使用/consumers 端点来满足此请求

java - 输出未按预期显示

java - super.input1 = input.nextInt();

c# - 从异步 HttpWebRequest 流读取 NullReferenceException