你记住一点,如果父类定义了一个方法,并且没有用virtual修饰它,那么无论如何你用父类类型调用它,都没有办法调用成子类定义的那个方法。 public class Father { public void DoWork() //不加virtual { Console.WriteLine("Father.DoWork()"); } }
public class Son :Father {
public new void DoWork() { Console.WriteLine("Son.DoWork()"); } } 你永远不可能试图实现 Father f = new Son(); f.DoWork(); //调用除Father.DoWork以外的另一个方法。
new是隐藏,override才是覆盖,你把子类中的new改成override,就会调用子类的方法了。 另外你的Son newSon = new Son(); newSon.DoWork(); 这个根本不是覆盖,就是直接调用的son的dowork
首先谢谢caozhy您的回答 Father son=new Son(); 构建了一个Son类的对象却赋值给了Father类的变量,是不是这个变量相当于简洁的变成了下面这个样: Father son=new Father(); 但又不完全是这个意思?
什么叫隐藏? Son son = new Son(); son.DoWork()按理说因为Son继承了Father,那么应该调用Father.DoWork(),但是因为你又定义了一个重名的变量叫DoWork()所以它“隐藏了”那个DoWork()。我们用变量名的隐藏类比下: class A { private int i = 123; public void foo1() { int i; i = 456; } public void foo2() { Console.WriteLine(i); } } 调用 A a = new A(); a.foo1(); a.foo2(); //输出多少?显然是123而不是456,为什么,因为foo1()中定义了一个也叫i的变量(和局部变量i毫无关系),并且修改的是那个i,那个i就隐藏了作为局部变量的i。 能不能不隐藏呢? public void foo1() { int i; this.i = 456; } 这样就输出456了。一个道理,如果你写 Son son = new Son(); son.DoWork();你调用的和基类的那个毫无关系。如果你像调用基类的,只能转化为基类的类型(如果前面给i加上this表明它是局部变量的i一样) ((Father)son).DoWork();
用基类类型访问,访问的是基类的,用子类类型访问,访问的是子类的(子类隐藏了基类的方法)。根本不是“覆盖”。
public class Father
{
public void DoWork() //不加virtual
{
Console.WriteLine("Father.DoWork()");
}
}
public class Son :Father
{
public new void DoWork()
{
Console.WriteLine("Son.DoWork()");
}
}
你永远不可能试图实现
Father f = new Son();
f.DoWork(); //调用除Father.DoWork以外的另一个方法。
另外你的Son newSon = new Son();
newSon.DoWork();
这个根本不是覆盖,就是直接调用的son的dowork
Father son=new Son();
构建了一个Son类的对象却赋值给了Father类的变量,是不是这个变量相当于简洁的变成了下面这个样:
Father son=new Father();
但又不完全是这个意思?
构建了一个Son类的对象却赋值给了Father类的变量
Father son这是定义了什么?
你认为是定义了一个Father类型的变量叫son
错!
这是定义了一个Father或它的派生类型的变量叫son。注意这个理解的差异,比如
IDispose d;
这是定义了什么?
定义了一个IDispose接口类型的变量?
接口都没有实现,哪里来的接口类型。如果你按照我说的就很好理解了,定义了一个实现了IDispose接口的任意类型的变量。
Son son = new Son();
son.DoWork()按理说因为Son继承了Father,那么应该调用Father.DoWork(),但是因为你又定义了一个重名的变量叫DoWork()所以它“隐藏了”那个DoWork()。我们用变量名的隐藏类比下:
class A
{
private int i = 123;
public void foo1()
{
int i;
i = 456;
}
public void foo2()
{
Console.WriteLine(i);
}
}
调用
A a = new A();
a.foo1();
a.foo2(); //输出多少?显然是123而不是456,为什么,因为foo1()中定义了一个也叫i的变量(和局部变量i毫无关系),并且修改的是那个i,那个i就隐藏了作为局部变量的i。
能不能不隐藏呢?
public void foo1()
{
int i;
this.i = 456;
}
这样就输出456了。一个道理,如果你写
Son son = new Son();
son.DoWork();你调用的和基类的那个毫无关系。如果你像调用基类的,只能转化为基类的类型(如果前面给i加上this表明它是局部变量的i一样)
((Father)son).DoWork();
您看看我的想法是不是正确(刚学C#)我自己想的:
我如果定义了一个Son的新方法: public void DoWork1()
{
Console.WriteLine("Son.DoWork1()");
}Father son=new Son();
这个son是无权访问这新方法的
如果强制类型转换成Son是可以访问的
是不是说明new Son()以后在堆里已经创建了对象,也有Son的全部方法。但是父类无权访问,内部是怎么控制的?
是不是有个方法权限表?
其实我想知道的就这个