【问题标题】:virtual and override how to use those?虚拟和覆盖如何使用这些?
【发布时间】:2014-11-14 02:01:05
【问题描述】:

你好,我写了两个简单的类

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

namespace Kus
{
    class Program : Class1
    {
        public Program()
        {}
        public override void findtheflyingdistance(out int x)
        {   x=0;
            Random r = new Random();
            for (int i = 0; i < 100; i++)
            {
                int z = r.Next(100, 500);
                x += x + z;
            }
            Console.WriteLine("Kuş" + x);

        }
        static void Main(string[] args)
        {
            int x;
            Program pg = new Program();
            pg.findtheflyingdistance(out x);
            Class1 C1 = pg;
            C1.findtheflyingdistance(out x);
        }
    }
}

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

namespace Kus
{
    class Class1
    {
        public Class1(){}
        public virtual void findtheflyingdistance(out int x)
        {   x=0;
            int z=200;
            x += x + z;
            Console.WriteLine("Leylek" +x);

        }
    }
}

据我了解,覆盖方法会覆盖虚拟方法。当我在主程序类中创建两个实例时。程序类中的 findtheflyingdistance(out int x) 适用于两个实例,但是当我在两个类中使用虚拟方法 findtheflyingdistance(out int x) 时。每个实例都使用自己的类。所以我不明白幕后的逻辑。我们为什么要写虚方法?如果我们想覆盖一个方法,我们可以覆盖已经被覆盖的非虚拟方法。

【问题讨论】:

  • "we can do override and non-virtual method that will be overriden already" - 你可以吗?不是根据 MSDN:“默认情况下,方法是非虚拟的。您不能覆盖非虚拟方法。” (msdn.microsoft.com/en-us/library/9fkccyh4.aspx)
  • 如果一些评论帮助你理解它并且你完成了这个问题接受它!

标签: c# class overriding virtual


【解决方案1】:

Virtual 允许您覆盖在基类中定义的方法。换句话说,它扩展了派生类中方法的实现。

this 会很有趣。

this stackoverflow 的回答还给出了一个简短的例子,为了方便起见,我在下面复制了这个例子:

virtual 关键字用于修改方法、属性、索引器或 事件声明,并允许它在派生类中被覆盖。 例如,此方法可以被任何继承的类覆盖 it:使用 new 修饰符显式隐藏继承自 a 的成员 基类。要隐藏继承的成员,请在派生中声明它 使用相同名称的类,并使用 new 修饰符对其进行修改。

这与多态性有关。调用虚方法时 在引用上,引用的对象的实际类型 指用于决定使用哪种方法实现。当一个 基类的方法在派生类中被覆盖,版本 在派生类中使用,即使调用代码不“知道” 该对象是派​​生类的一个实例。例如:

public class Base { public virtual void SomeMethod() { } }

public class Derived : Base { public override void SomeMethod() { } }
  ...

 Base b = new Derived(); 
b.SomeMethod(); 

最终会调用 Derived.SomeMethod 如果覆盖 Base.SomeMethod。

现在,如果您使用 new 关键字而不是 override,则 派生类不会覆盖基类中的方法,它只是 隐藏它。在这种情况下,代码如下:

 public class Base { public virtual void SomeOtherMethod() { } }

 public class Derived : Base { public new void SomeOtherMethod() { } }

 ...


 Base b = new Derived();
 Derived d = new Derived();
 b.SomeOtherMethod(); 
d.SomeOtherMethod();

将首先调用 Base.SomeOtherMethod ,然后是 Derived.SomeOtherMethod 。他们是 实际上是两个完全独立的方法,它们恰好具有 相同的名称,而不是覆盖基方法的派生方法。

如果您不指定 new 或 overrides,则结果输出为 与您指定 new 相同,但您还将获得一个编译器 警告(因为您可能不知道您在 基类方法,或者实际上您可能想要覆盖它,并且 只是忘了包含关键字)。

覆盖属性声明可能包含sealed 修饰符。 使用此修饰符可防止派生类进一步覆盖 财产。密封属性的访问者也是密封的。

【讨论】:

  • 必须学习虚拟、覆盖和新的。好吧,我需要开始阅读 msdn 链接。感谢分享。
  • @BeratEmreNebioglu 这可能是最好的信息来源之一,老实说,对于大多数东西,您无法获得比 mdsn 更官方的信息!
  • 确定 msdn 页面有非常好的东西。我最近开始阅读 c# 书。与 java 相比,有一些新概念。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-25
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 2018-07-26
相关资源
最近更新 更多