【问题标题】:Calling overriden method used on base type调用基类型上使用的重写方法
【发布时间】:2018-07-05 17:28:31
【问题描述】:

在这段代码中:

using System;

namespace ConsoleApp1
{
    public class TextInput
    {
        protected string _text = "";

        public void Add(char c)
        {
            _text += c;
        }

        public string GetValue()
        {
            return _text;
        }
    }


    public class NumericInput : TextInput
    {
        public new void Add(char c)
        {
            if (!char.IsDigit(c)) return;
            _text += c;
        }
    }


    public class Program
    {
        public static void Main(string[] args)
        {
            TextInput input = new NumericInput();
            input.Add('1');
            input.Add('a');
            input.Add('0');
            Console.WriteLine(input.GetValue());

            Console.WriteLine(char.IsDigit('1'));
            Console.WriteLine(char.IsDigit('a'));
            Console.WriteLine(char.IsDigit('0'));
        }
    }
}

...调用Console.WriteLine(char.IsDigit('a')); 正确返回False,但在被覆盖的Add 方法中它总是返回True

显然它调用TextInput.Add() 而不是NumericInput.Add()。这可以在覆盖的Add() 方法中更正吗? Main 中的代码可能不会更改!

【问题讨论】:

  • Add 设为虚拟并用override 关键字覆盖它
  • @AleksAndreev 在这种情况下这是唯一可能的选择吗?
  • 您能解释一下您为什么使用新关键字吗?如果您试图实现方法覆盖。第二件事,在这里您正在创建基类TextInput 的实例并调用Add(),执行不会进入派生类中存在的方法,不会检查IsDigit() 条件。请给我们一些有效的例子
  • 这是您的示例的输出:dotnetfiddle.net/J9Xjon
  • 我认为这个答案会有很大帮助:stackoverflow.com/a/3838692/6300600

标签: c# inheritance char


【解决方案1】:

查看 c# 中 new 和 override 的区别。另外,看看虚拟键。

我现在不打算解释了。此处和网络上有很多关于此的信息。

MS 文档:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/knowing-when-to-use-override-and-new-keywords

更多信息在这里:Difference between new and override

总而言之,在这种情况下使用覆盖。尝试他们两个,你会意识到他们是如何工作的。 那里

【讨论】:

    【解决方案2】:

    如果要实现方法覆盖,请在基类中使用virtual关键字,在派生类中使用override关键字。

    namespace ConsoleApp1
    {
        public class TextInput
        {
            protected string _text = "";
            //Virtual allows derived class to enhance its functionality.
            public virtual void Add(char c)
            {
                _text += c;
            }
            ....
        }
    
    
        public class NumericInput : TextInput
        {
            //Override function will add more functionality to base class function
            public override void Add(char c)
            {
                if (!char.IsDigit(c)) return;
                _text += c;
            }
        }
    

    现在new 关键字不会覆盖基类功能,它会隐藏基类功能。

    如果要覆盖派生类中的函数,请使用override 而不是new 关键字

    更多参考,请访问:Stackoverflow thread

    【讨论】:

    • 这很好,但是这不是 java,所以不需要@override
    【解决方案3】:

    为什么不使用抽象类:

    由于我们有多个add 实现,也不能在T 上使用运算符,因此将其声明为抽象并在派生类上实现

    public abstract class Input<T>
        {
            protected T __input;
            public abstract void Add(T c);
            public T GetValue()
            {
                return __input;
            }
        }
        public class NumericInput : Input<int>
        {
            public override void Add(int c)
            {
                __input += c;
            }
        }
        public class TextInput : Input<string>
        {
            public override void Add(string c)
            {
                __input += c;
            }
        }
    
    static void Main(string[] args)
            {
                var input = new NumericInput();
                input.Add(1);
                input.Add(2);
                Console.WriteLine(input.GetValue());
    
                var text = new TextInput();
                text.Add("a");
                text.Add("a");
                text.Add("a");
                Console.WriteLine(text.GetValue());
    
                Console.ReadLine();
            }
    

    【讨论】:

      猜你喜欢
      • 2012-12-12
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 2023-03-12
      • 2011-01-18
      相关资源
      最近更新 更多