C# 关于凌驾性规则C的混淆#
我对方法重写和OOP原则的有效性有点困惑。 我知道一切关于密封,阴影,覆盖,虚拟等,但我遇到了一个场景,这只是困惑我。假设我有:C# 关于凌驾性规则C的混淆#,c#,oop,virtual-functions,overriding,sealed,C#,Oop,Virtual Functions,Overriding,Sealed,我对方法重写和OOP原则的有效性有点困惑。 我知道一切关于密封,阴影,覆盖,虚拟等,但我遇到了一个场景,这只是困惑我。假设我有: class classA { public virtual void sayhello() { Console.WriteLine("hello I'm A"); } }; class classB :classA { public override void sayhello() {
class classA
{
public virtual void sayhello()
{
Console.WriteLine("hello I'm A");
}
};
class classB :classA
{
public override void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
class Program
{
static void Main(string[] args)
{
classB a = new classB();
a.sayhello();
}
}
根据我到目前为止所研究的所有内容,可以在子类中使用override关键字覆盖声明为virtual或abstract的方法(在抽象类中)。根据这一点,上面的代码工作得非常完美。
当我删除virtual关键字,然后尝试使用override关键字重写该方法时,编译器给出的错误如下:
无法重写继承的成员“Inheritance.classA.sayhello()”,因为它未标记为虚拟、抽象或重写
然后我从子类中删除了override关键字,并提供了如下实现:
class classB :classA
{
public void sayhello()
{
Console.WriteLine("hello I'm B");
}
};
在这种情况下,可以重写该方法。我可以重写这个方法,它不是虚拟的或抽象的。因此,我的问题是:
1.它没有违反OOP原则吗?因为我可以重写该方法,该方法在父级中未标记为virtual
2.为什么允许我以这种方式重写该方法?哪一个甚至没有标记为虚拟
3.从classA方法中删除virtual关键字,当我试图在classB中重写该方法时,它给了我一种在classA中密封方法的感觉。(正如我前面提到的编译器错误)。如果我删除了virtual,这样子类就不会覆盖它,那么为什么子类可以聪明地覆盖它,删除它的override关键字?这是唯一的情况吗,sealed关键字是为这种情况设计的吗
方法sayhello()
隐藏
2.为什么允许我以这种方式重写该方法?哪一个甚至没有标记为虚拟
因为您可以用子实现隐藏父方法。
< P>我认为这是来自C++实现,使用SLIGEN()、 虽然C++类似于java,但在某些情况下(这一个和值类型的存在)遵循C++方式。 这之后的推理是,由于您的代码从A
变量调用方法sayhello
,程序员希望执行A.sayhello
的逻辑。它不会违反OOP原则,因为您正在执行A.sayhello
实现(因此它必须与A.sayhello
契约匹配)
与Java的区别不是OOP与非OOP,而是Java使用后期绑定
(实际执行的方法在运行时根据a
实际实例确定),而C#使用早期绑定
(方法在编译时确定),除非该方法是虚拟的
就我个人而言,我更喜欢后期绑定,虽然从面向对象的角度来看,C#方法是正确的,但我发现通常应该使用更专业的方法。好吧,最后它非常简单:
new
关键字(或完全忽略它)时,您正在编译时根据代码中可用的类型信息执行静态替换操作李>
这是两件完全不同的事情。我想告诉你,你给隐藏的父子方法没有被覆盖。
您可能还没有注意到的另一件事是看到警告,因为在警告部分中会清楚地提到 警告“行号”
“classB.sayhello”
隐藏继承的成员“classA.sayhello”
。使用新的
关键字,如果要隐藏
你的问题,
它没有违反OOP原则吗?因为我可以重写该方法,该方法在父级中未标记为虚拟
不,它肯定没有违反OOP原则,因为您已经隐藏了基类方法
为什么允许我以这种方式重写该方法?哪一个甚至没有标记为虚拟
因为C#不仅支持重写,而且还支持方法隐藏,并且必须使用new
关键字声明隐藏方法。有关更多信息,请阅读和
这是唯一的情况,密封关键字是专为
Fromsealed
关键字用于防止派生类并否定虚拟成员的虚拟方面
- 当应用于类时,sealed修饰符会阻止其他类从该类继承
- 密封修饰符只能应用于重写基类中虚拟方法或属性的方法或属性。这可以防止进一步重写特定的虚拟方法或属性,但它永远无法停止
。阅读了解更多信息方法隐藏
若你们真的想这样做,你们应该在方法定义中添加新的关键字,使警告消失,并作为一个文档。因此,其他查看您代码的开发人员知道您是故意这样做的。您执行了一个称为“方法隐藏”的概念,是的,但它不是违反了oop原则吗?比方说,classA不想让它的方法被隐藏?或者为什么我们要使用新的关键字进行阴影处理,是吗