解决方案 »
- 两个无关联窗体里的文本框之间怎么传值?
- winform的设计视图中未找到类型“(父类)”上的构造函数。
- combobox绑定数据源后的Text问题
- 求一些winform改写为windows service的资料或者案例
- 7PK游戏开发
- web应用,为什么点击网页按钮不能进入后台的服务器C#脚本执行?
- 怎样设置动态添加的右键的单击事件,大家帮忙!
- 请问,我在mdi模式中,在主窗体如何访问子窗体中的控件如textbox。谢谢
- 如何在onclick事件中添加javascript:window.open(test.aspx....)??
- 做一声音提醒功能,请帮我看下这段。
- 给大家看个小程序,这个怎么办呢?
- C#_JSP_登录
姓名:王五,年龄:23
部门:客服部,薪金:5000
以上信息是
Person .DisplayData(OneEmployee);
所以打印出来的
因为你用的父类对象来调的方法,而参数传的却是子类的
又因为DisplayData方法是重写的,所以它会先调用自己的,随后再是子类重写后的方法
也是基类的对象啊!
==>姓名:李四,年龄:40Person .DisplayData(OneEmployee);==>姓名:王五,年龄:23
部门:客服部,薪金:5000设置断点,单步调试就明白啦
执行到aPerson.Display();这句时,下一句就跳到了
protected override void Display()
{ base.Display();
Console.WriteLine("部门:{0},薪金:{1}", department , salary );
}
这一部分呢?为什么不去执行基类中的
protected virtual void Display()
{ Console.WriteLine("姓名:{0},年龄:{1}", name, age); }
以OneEmployee为参数执行static public void DisplayData(Person aPerson)
{
aPerson.Display();
}
这句就到执行protected override void Display()
{
base.Display();
Console.WriteLine("部门:{0},薪金:{1}", department , salary );
}
到了这里,注意是base.Display();是执行基类的 Display方法,也就是protected virtual void Display()
{ Console.WriteLine("姓名:{0},年龄:{1}", name, age); }
这里是关键了,这句的参数name, age,因为是以OneEmployee为参数,OneEmployee里有这句public Employee(string Name, int Age, string D, decimal S):base(Name, Age)
{
department = D;
salary = S;
}
注意这个:base(Name, Age) //派生类和基类通信,以base实现,基类首先被调用,所以其实
基类的public Person(string Name, int Age)
{
name = Name;
age = Age;
}
因为参数是:王五,23。所以base.Display();执行基类的protected virtual void Display()
{
Console.WriteLine("姓名:{0},年龄:{1}", name, age);
}
结果就是:姓名:王五,年龄:23 了
然后才是子类的Console.WriteLine("部门:{0},薪金:{1}", department , salary );
Person .DisplayData (OneEmployee);
这个方法的参数类型是Person,所以可以接受的参数是Person和它的子类。当在方法中执行
person.Display()时,会根据person的实际类型去调用。因为是Employee类型,且Display方法是override,所以调用的是Employee的display方法
//因为使用new的话是隐藏了基类的方法
Person .DisplayData(OneEmployee);
在这你传入了一个子类对象,
static public void DisplayData(Person aPerson)
{
aPerson.Display();
}
这个地方用父类的引用接收,相当于这样了
Person aPerson = new Employee("王五", 23, "客服部", 5000);
然后调用方法
aPerson.Display();
它实际上是子类对象,并且子类重写了display方法,所以就会调用子类重写的方法
2.1 base关键字其用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数、实例方法和实例属性访问器中,MSDN中小结的具体功能包括:调用基类上已被其他方法重写的方法。
指定创建派生类实例时应调用的基类构造函数。也就是说,其实还是调用了基类的Display方法。只不过因为传递到基类的参数是:王五, 23。
protected virtual void Display()
你没看到那个virtual啊?你去掉virtual和override就会调用了
override在子类中重写了基类的virtual方法,而这个重写的方法里又有base.Display,所以会调用基类的Display方法,基类Display方法的参数是:王五, 23。所以结果就这样了。
顺便多说一句,要是有多重继承的话,有BASE方法的话,那调用的方法应该是最高级父类的方法。
例如:
public class A
{
……
public virtual void M1()
{
……
}
public void M2()
{
……
}……
}
public class B:A
{……
public override void M1()
{
base.M1();
……
}
……
}
public class C:B
{……
public override void M1()
{
base.M1();
base.M2();
……
}
……
}B继承A,C继承B,B.M1显然是执行A中的M1,C.M1中因为继承了B.M1所以会执行B.M1而不是A.M1,而BASE.M2因为B中没有M2方法所以再去B的父类中找到了A.M2执行。
没有老爸那有儿子!
Employee是Person的儿子。Employee OneEmployee = new Employee ("王五", 23, "客服部", 5000);
Person .DisplayData(OneEmployee);
这个DisplayData你重写了,他肯定先去找老爸的方法、再找自己的方法
多看几遍就明白了。
的执行过程,一定是。爷爷,爸爸,自己
{
aPerson.Display();
} 时,这个Person此时实际上是(被实例化时是)一个Employee,因此Display是去执行这个Employee的Display,这是面向对象技术公认的规则。面向对象技术的基本规则是脱离语言实现的。各种语言实现机制不同,例如(过去的)c++与.net对继承的实现就完全不同,但是它们要实现的效果必须相同,必须符合面向对象的公认规则。例如过去c++的书上可能会告诉你Emplyoee对象内部有一个private的指针指向一个Person类型的对象,但是.net根本不是这样实现继承的。如果你抱着底层结构的角度去看面向对象设计,永远也看不明白。只有抛开语言具体的实现,才能看明白如何进行面向对象设计。