c# - 为什么我们不能在 C# 中重写方法时更改访问修饰符?

标签 c# oop access-modifiers

在 C# 中,我们不能在重写基类的方法时更改访问修饰符。 例如

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

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

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

我想知道为什么不允许这样做。是否存在任何技术问题或是否会导致访问限制方面不一致???

最佳答案

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

案例 1:使用更严格的访问权限覆盖

由于以下情况,这种情况显然是不允许的:

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:使用限制较少的访问修饰符覆盖

重点是什么?隐藏方法,你就完成了。 显然,如果有人通过基类型调用,他们将无法访问派生类型中定义的新方法,但这与基类型的作者想要的东西是一致的,所以你没有“权利”改变它。如果您想要从派生类调用派生类的细节,在这种情况下,new 方法工作得很好。

编辑:扩展案例 2

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

考虑以下代码:

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 的类都可以覆盖它。

不允许有人做以下事情:

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

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

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

我希望这能让它更清楚。

关于c# - 为什么我们不能在 C# 中重写方法时更改访问修饰符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6236909/

相关文章:

c# - 调用 IEnumerable.Count() 需要多秒

java - 关注点分离、封装、松散耦合、意大利面条式代码

c++ - 公共(public)、 protected 、私有(private)

C# 将类实例的创建限制在命名空间内

c# - 为什么将 <LangVersion>default</LangVersion> 添加到 .csproj 文件可以修复 C# 语言版本错误?

c# - session 状态未在页面之间保存

java - 非 void 方法中缺少 return 语句编译

swift - Swift 中的 Getters 和 Setters - 改用 WillSet 和 DidSet 是否有意义?

java - 使用子类引用访问包外部的 protected 成员

c# - 使用来自另一个合并词典的合并词典中定义的样式