黑马程序员—面向对象之多态
多态是面向对象里面的一个重要概念,从字面上可以理解为一个对象所表现出的多种状态。实现多态有三种方法:虚方法、抽象类、接口。
虚方法:
用virtual修饰的方法叫做虚方法。父类的方法里标记virtual表示可以让子类通过override关键字重写这个方法,如public virtual void 方法名();子类的方法里标记override表示子类已经重写了父类的这个方法,如public override void 方法名();看以下例子:
//一个人类父类,有三个子类黄种人、黑种人、白种人,他们都有自己的肤色。
添加一个人类,作为父类,里面有个Complexion方法也标记virtual;然后再添加三个类,一个黄种人类继承人类,重写父类方法标记override;一个黑种人类继承人类,重写父类方法标记override;一个白种人类继承人类,重写父类方法标记override;
Main函数里代码:
Person person = new Person();
person.Complexion();
Yellow yellow = new Yellow();
yellow.Complexion();
Black black = new Black();
black.Complexion();
White white = new White();
white.Complexion();
Console.ReadKey();
父类代码:
public class Person
{
public virtual void Complexion()
{
Console.WriteLine("每个人种都有自己的肤色! ");
}
}
黄种人类代码:
public class Yellow:Person
{
public override void Complexion()
{
Console.WriteLine("我们是黄种人,我们有黄皮肤。");
}
}
黑种人类代码:
public class Black:Person
{
public override void Complexion()
{
Console.WriteLine("We are Black people,our skin is Black.");
}
}
白种人类代码:
public class White:Person
{
public override void Complexion()
{
Console.WriteLine("We are White people,we have White skin.");
}
}
抽象类:
用abstract修饰的方法和类叫做抽象类,抽象方法。父类的类和方法里标记abstract表示可以让子类通过override关键字重写这个方法,如
public abstract class 类名
{
public abstract void 方法名();
}
子类的方法里标记override表示子类已经重写了父类的这个方法,如public override void 方法名();需要说明的是,抽象方法没有方法体,抽象成员只能存在于抽象类中,抽象类可以有非抽象成员,抽象类的派生类必须实现抽象方法体,抽象类只能用作基类,无法实例化。看以下例子:
//一个人类父类,有两个子类中国人和英国人,他们都有自己的语言。
添加一个人类,作为父类标记abstract,里面有个Talk方法也标记abstract;然后再添加两个类,一个中国人类继承人类,重写父类方法标记override;一个英国人类继承人类,重写父类方法标记override;
Main函数里代码:
Chinese chinese = new Chinese();
chinese.Talk();
English english = new English();
english.Talk();
Console.ReadKey();
父类代码:
Public abstract class Person
{
public abstract void Talk()
}
中国人类代码:
public class Chinese : Person
{
public override void Talk()
{
Console.WriteLine("我们是中国人,我们的母语是汉语。");
}
}
英国人类代码:
public class English : Person
{
public override void Talk()
{
Console.WriteLine("We are English,English is our mother tongue.");
}
}
虚方法及抽象类总结:
从以上例子可以看出,虚方法和抽象类、抽象方法是有区别的:
- 虚方法标记virtual,可以被子类重写,也可以不重写,不强制重写,但是抽象方法标记abstract,子类必须重写父类方法。
- 虚方法有方法体,而抽象方法不能有方法体。
- 虚方法可以实例化,而抽象方法不能实例化。
- 虚方法除了密封类(sealed)都可以写,而抽象方法只能存在于抽象类中。
接口:
被interface标记的,是特殊的抽象类,接口中可以有属性、方法等。接口的成员没有任何访问修饰符。继承自接口的类必须实现接口中的方法。如果一个类即继承了类又实现了接口,那么类必须写在前面。一个类只能继承一个父类,但可以实现多个接口。
Interface Iinterface
{
Void 方法名();
}
看下例:
//一个人类父类,有三个子类黄种人、黑种人、白种人,他们都有自己的肤色。同时让父类继承一个吃的接口IPersonEat;
添加一个接口IPersonEat,里面有个吃的方法Eat();添加一个人类,作为父类继承接口IPersonEat,实现Eat()方法,里面有个Complexion方法标记virtual;然后再添加三个类,一个黄种人类继承人类,实现Eat()方法,重写父类方法标记override;一个黑种人类继承人类,实现Eat()方法,重写父类方法标记override;一个白种人类继承人类,实现Eat()方法,重写父类方法标记override;
Main函数里代码:
Person person = new Person();
person.Complexion();
person.Eat();
Yellow yellow = new Yellow();
yellow.Complexion();
yellow.Eat();
Black black = new Black();
black.Complexion();
black.Eat();
White white = new White();
white.Complexion();
white.Eat();
Console.ReadKey();
接口里代码:
public interface IPersonEat
{
void Eat();
}
父类里代码:
public class Person : IPersonEat
{
public void Eat()
{
Console.WriteLine("人们都要吃饭。");
}
public virtual void Complexion()
{
Console.WriteLine("每个人种都有自己的肤色! ");
}
}
黄种人类代码:
public class Yellow:Person
{
new public void Eat()
{
Console.WriteLine("我们喜欢吃中餐。");
}
public override void Complexion()
{
Console.WriteLine("我们是黄种人,我们有黄皮肤。");
}
}
黑种人类代码:
public class Black:Person
{
new public void Eat()
{
Console.WriteLine("We like our own food.");
}
public override void Complexion()
{
Console.WriteLine("We are Black people,our skin is Black.");
}
}
白种人类代码:
public class White:Person
{
new public void Eat()
{
Console.WriteLine("We like Western-style food.");
}
public override void Complexion()
{
Console.WriteLine("We are White people,we have White skin.");
}
}