我正在看这篇博文,并有以下问题:
new关键字,只是指定隐藏基类方法.我的意思是,为什么我们需要它?如果我们不使用override关键字,是不是我们隐藏了基类方法?在C++中,我必须明确指定'virtual'关键字以使成员函数'overridable',因为当成员函数被覆盖时,会产生创建虚拟表和vpointer的开销(因此每个成员函数都隐式不能覆盖表现原因).
当子类提供具有相同名称和签名的单独实现时,它还允许隐藏成员函数(如果未覆盖).
在C#中也使用相同的技术.我想知道为什么Java摆脱了这种行为,并默认使每个方法都可以覆盖,并提供了在显式使用'final'关键字时禁用覆盖行为的能力.
可能重复:
为什么C#默认将方法实现为非虚方式?
我主要讲的是C#,.NET 3.5,但总体上想知道不考虑所有"虚拟"的好处是什么 - 也就是说在子类实例中调用的方法总是执行最多的子版本那种方法.在C#中,如果父方法未使用"虚拟"修饰符标记,则情况并非如此.例:
public class Parent
{
public void NonVirtual() { Console.WriteLine("Non-Virtual Parent"); }
public virtual void Virtual(){ Console.WriteLine("Virtual Parent"); }
}
public class Child : Parent
{
public new void NonVirtual() { Console.WriteLine("Non-Virtual Child"); }
public override void Virtual() { Console.WriteLine("Virtual Child"); }
}
public class Program
{
public static void Main(string[] args)
{
Child child = new Child();
Parent parent = new Child();
var anon = new Child();
child.NonVirtual(); // => Child
parent.NonVirtual(); // => …Run Code Online (Sandbox Code Playgroud) 在Java中,默认情况下方法是虚拟的; C#正好相反.
哪个更好?每种方法有哪些优缺点?
可能重复:
为什么C#默认将方法实现为非虚方式?
定义哪些方法不可克服而不是可以克服的方法要少得多,因为(至少对我而言),当你设计一个类时,你不关心它的继承人是否会覆盖你的方法. ..
那么,为什么C#中的方法不会自动虚拟?这是什么常识?
我似乎记得在某处读到C#中虚拟调用的成本并不像在C++中那么高.这是真的?如果是这样 - 为什么?
我和我的朋友,他是一名Java程序员,正在讨论继承问题.当我们为相同类型的代码得到不同的结果时,对话几乎达到了高度.我在.NET中的代码:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleDemo
{
class Program
{
static void Main(string[] args)
{
Base objBaseRefToDerived = new Derived();
objBaseRefToDerived.Show();
Console.ReadLine();
}
}
public class Base
{
public virtual void Show()
{
Console.WriteLine("Show From Base Class.");
}
}
public class Derived : Base
{
public void Show()
{
Console.WriteLine("Show From Derived Class.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
给我这个结果:
从基类显示.
而这段代码用Java编写
public class Base {
public void show() {
System.out.println("From Base");
}
}
public class Derived extends Base { …Run Code Online (Sandbox Code Playgroud) 为什么我们需要将方法显式定义为虚拟,然后在C#中指定override以完成方法重写,而在Java中不使用这两个关键字时实现相同的操作.它有什么用途?
默认情况下,C#中的方法是非虚拟的。这个对另一个问题的答案解释了这样做的好处:
应该为继承设计类,以便能够利用它。默认情况下,将方法虚拟化意味着可以将类中的每个函数插入并替换为另一个函数,这并不是一件好事。
甚至Anders Hejlsberg 似乎也给出了相同的原因:
当我们在API中发布虚拟方法时,我们不仅承诺在调用此方法时还会发生x和y。我们还承诺,当您重写此方法时,相对于其他方法,我们将以特定的顺序调用它,并且状态将处于此不变状态。[...]您不希望用户在API中的任意点上重写和挂接,因为您不一定会做出这些承诺。
我同意这种推理:通常,当我创建一个非私有方法时,我只想创建可以从类外部的某个地方调用的代码。通常,不考虑其他人如何覆盖此方法以及将产生何种效果。对于特殊情况,我可以用virtual信号表示确实以覆盖有意义的方式创建了代码。
但是,默认情况下仍未打开类。该默认假定我花确保继承一个类有意义的额外的努力。
在这方面,有什么使类不同于方法的吗?
编辑
我真的不知道要更改的内容-基于意见的内容。我从没问过意见。也许我必须明确地说出来?
我不要意见
正确的答案将提供类与方法不同的示例,或者声明在这种情况下没有区别。
我想知道为什么在下面的例子中,即使我在工厂模式"Builder"返回对象的新实例时覆盖它,总是会调用基本方法?
interface FactoryInter
{
void MakeDetails();
}
class Builder {
public static Builder getObject(string obj)
{
if(obj == "Cont")
{
return new Cont();
}else{
return new Builder();
}
}
public void MakeDetails()
{
Console.WriteLine("I will always get called..");
}
}
class Cont : Builder, FactoryInter {
public void MakeDetails()
{
Console.WriteLine("Hello..");
}
}
public class Test
{
public static void Main()
{
Builder b = new Builder();
b = Builder.getObject("Cont");
b.MakeDetails();
// your code goes here
}
}
Run Code Online (Sandbox Code Playgroud)
任何帮助将不胜感激
c# ×9
java ×4
virtual ×3
c++ ×2
inheritance ×2
overriding ×2
.net ×1
oop ×1
polymorphism ×1
syntax ×1