为什么我们不能在覆盖 C# 中的方法时更改访问修饰符? [英] Why can't we change access modifier while overriding methods in C#?

查看:27
本文介绍了为什么我们不能在覆盖 C# 中的方法时更改访问修饰符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C# 中,我们不能在覆盖基类方法时更改访问修饰符.例如

In C#, we can not change access modifier while overriding a method from base class. e.g.

Class Base
{
   **protected** string foo()
   {
       return "Base";
   }
}

Class Derived : Base
{
   **public** override string foo()
   {
       return "Derived";
   }
}

这在 C# 中无效,它会给出编译时错误.

This is not valid in C#, It will give compile time error.

我想知道原因,为什么不允许这样做.是否有任何技术问题或是否会导致访问限制不一致?

I want to know the reason, why it's not allowed. Is there any technical problem or can it lead to something which is not consistent in terms of access restriction???

推荐答案

在派生类型中更改方法的访问修饰符毫无意义,这就是为什么不允许这样做:

Changing the access modifier of a method in a derived type is pointless that's why it's not allowed:

案例 1:覆盖更严格的访问

Case 1: Override with a more restrictive access

这种情况显然是不允许的,原因如下:

This case is obviously not allowed due to the following situation:

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

class Derived: Base
{
    protected override void A()
}

现在我们可以说:

List<Base> list;
list.Add(new Derived());
list[0].A() //Runtime access exception

案例 2:使用限制较少的访问修饰符覆盖

Case 2: Overriding with a less restrictive access modifier

重点是什么?隐藏方法,你就完成了.显然,如果有人通过基类型调用,他们将无法访问派生类型中定义的新方法,但这与基类型的作者希望事情的方式一致,因此您没有权利"更改它.如果你想从派生类调用派生类的细节,在这种情况下 new 方法工作得很好.

What is the point? Hide the method and you are done. Obviously if someone calls through the base type they will not have access to the new method defined in the derived type but that is consistent with how the author of the base type wanted things to be so you have no "right" to change that. If you want the specifics of the derived class call from the derived class, in which case the new method works perfectly fine.

扩展案例 2

在案例 2 中,我想说的是,如果您想更改可访问性,您已经有办法更改任何方法(虚拟或非虚拟)的可访问性.

What I am trying to say in case 2, is that you already have the means to change accessibility of any method (virtual or not) if you want to change accessibility.

考虑以下代码:

public class Base
{
    protected virtual string WhoAmI()
    {
        return "Base";
    }
}

public class Derived : Base
{
    public new virtual string WhoAmI()
    {
        return "Derived";
    }
}

public class AnotherDerived : Derived
{
    public override string WhoAmI()
    {
        return "AnotherDerived";
    }
}

使用new 关键字,您已经有效地为Derived 类创建了一个具有相同名称和签名的新虚拟方法.请注意,允许声明 new 方法 virtual,因此任何从 Derived 派生的类都可以覆盖它.

With the new keyword you have effectively created a new virtual method for your Derived class with the same name and signature. Take note that it is ALLOWED to declare a new method virtual, so any class deriving from Derived will be allowed to override it.

不允许有人做以下事情:

What is not allowed is to have someone do the following:

 Base newBaseObject = new Derived();
 newBaseObject.WhoAmI() //WhoAmI is not accessible.

但是这个事实与是否能够覆盖 WhoAmI() 无关.无论如何,这种情况永远不会发生,因为 Base 没有声明 public WhoAmI().

But this fact has nothing to do with being able to override WhoAmI() or not. Whatever the case this situation can never be because Base does not declare a public WhoAmI().

因此,在 Derived.WhoAmI() 可以覆盖 Base.WhoAmI() 的理论 C# 中,这样做没有实际好处,因为您将永远无法无论如何从基类调用虚方法,所以 new 选项已经满足您的要求.

So in a theoretical C# where Derived.WhoAmI() could override Base.WhoAmI() there is no practical benefits in doing so because you will never be able to call the virtual method from the base class anyways, so the new option already meets your requirements.

我希望这能让你更清楚.

I hope this makes it clearer.

这篇关于为什么我们不能在覆盖 C# 中的方法时更改访问修饰符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆