虚方法 实现多态的三种手段:1、虚方法 2,抽象类 3,接口 ##### 有如下三个有继承关系的类 父类:Person 子类:Chinese、American 他们都有一个SayHello方法
//父类 public class Person { private string _name;//姓名字段 public string Name//姓名属性 { get { return _name; } set { _name = value; } } public void SayHello()//方法 { Console.WriteLine("Hello,我是人类"); } //构造函数 public Person(string name) { this.Name = name; } }
//子类,中国人 public class Chinese : Person { public Chinese(string name) : base(name) { } public void SayHello() { Console.WriteLine("我是中国人,我叫{0}", this.Name); } }
//子类,美国人 public class American : Person { public American(string name) : base(name) { } public void SayHello() { Console.WriteLine("我是美国人,我叫{0}", this.Name); } }
我们尝试用一个父类数组装两个子类对象,然后输出自己的SayHello方法
//创建中国人对象
Chinese chinese = new Chinese("张三");
//创建美国人对象
American american = new American("迈克尔杰克逊");
Person person = new Person("人类");
//父类数组
Person[] people = { chinese, american, person };
//循环调用他们自己的方法
for (int i = 0; i < people.Length; i++)
{
if (people[i] is Chinese)//判断是否是自己子类对应的类型
{
((Chinese)people[i]).SayHello();
}
else if (people[i] is American)
{
((American)people[i]).SayHello();
}
else
{
people[i].SayHello();
}
}
可以看到,在循环输出自己的SayHello方法时,很麻烦,要判断,然后将子类转为对应的类型再调用
使用虚方法,解决
步骤:
1、将父类的方法标记为虚方法 ,使用关键字 virtual,这个函数可以被子类重新写一遍。
2、子类重写用override重写
我们只需要在父类的SayHello方法改为虚方法,再在子类的SayHello里重写父类的SayHello方法就行了,如:
//父类
public class Person
{
private string _name;//姓名字段
public string Name//姓名属性
{
get { return _name; }
set { _name = value; }
}
public virtual void SayHello()//方法
{
Console.WriteLine("Hello,我是人类");
}
//构造函数
public Person(string name)
{
this.Name = name;
}
}
//子类,中国人
public class Chinese : Person
{
public Chinese(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine("我是中国人,我叫{0}", this.Name);
}
}
//子类,美国人
public class American : Person
{
public American(string name) : base(name)
{
}
public override void SayHello()
{
Console.WriteLine("我是美国人,我叫{0}", this.Name);
}
}
这样在循环调用的时候就不用把父类数组里的子类依依判断然后转为子类再调用方法,可以直接调用SayHello方法,因为子类重写了,所以循环调用SayHello的时候,表面上虽然是Person父类的类型,实际上调用的却是子类自己的SayHello方法
//创建中国人对象
Chinese chinese = new Chinese("张三");
//创建美国人对象
American american = new American("迈克尔杰克逊");
Person person = new Person("人类");
//父类数组
Person[] people = { chinese, american, person };
//循环调用他们自己的方法
for (int i = 0; i < people.Length; i++)
{
people[i].SayHello();
}
这样也实现了判断转子类调用SayHello方法
使用虚方法的目的
原本父类只能调父类方法,但是重写后可以调子类,
相当于实例父类,但是根据对象不同,方法也就不同。
比如写一个通用方法,主体是父类,参数是子类,以后拓展代码只要改下参数就好
也就是,让子类自己实现这个方法,父类这个SayHello方法就不会写死了。这样如果还有一个新的子类,
也只需要重写这个SayHello方法,这样就实现父类的方法在不同的子类实现不同的功能,也就是多态
virtual:将父类的方法标记为虚方法,这样子类就可以重写这个方法
override的效果是实例父类,根据对象子类不同,可以实现不同方法,可以写出通用代码。
virtual和new关键字的区别
有点相似,表面上都是让子类用自己的功能,不用父类的功能。
实际上,new的效果是子类调用子类,父类调用父类,各管各,没有实现多态
所以说 new 和 override区分了想不想重写