面向对象-多态
文章目录
1、Vob
1、多态的概念
多态:多种状态
让继承同一父类的子类们在执行相同方法时有不同的表现(状态)
主要目的
同一父类的对象,执行相同的行为(方法)有不同的表现
解决问题
让同一个对象有唯一行为的特征
2、多态的实现
编译时多态:函数重载
运行时多态:
vob、抽象函数、接口
v:virtual(虚函数) //可以被子类重新
o:override(重写) //重写虚函数
b:base(父类) //代表父类,可以通过base来保留父类的行为
GameObject p = new Player("玩家1");
p.Atk();
(p as Player).Atk();
class GameObject
{
public string name;
public GameObject(string name)
{
this.name = name;
}
public virtual void Atk()
{
Console.WriteLine("游戏对象进行攻击");
}
}
class Player : GameObject
{
public Player(string name) : base(name)
{
}
public override void Atk()
{
base.Atk();//保留父类atk方法
Console.WriteLine("玩家对象进行攻击");
}
}
2、抽象类和抽象方法
1、抽象类
概念
被abstract修饰的类
特点
1、不能被实例化
2、可以包含抽象方法
3、继承抽象类必须重新其抽象方法
2、抽象方法
又叫纯虚方法
用abstract关键字修饰的方法
特点
1、只能在抽象类中声明
2、没有方法体
3、不能私有
4、继承后必须实现,用override重写
abstract class Graph
{
public abstract float GetArea();
public abstract float getLength();
}
3、接口
1、接口的概念
概念
接口是行为的抽象规范
是一种自定义类型
关键字 interface
接口声明的规范
1、不包含成员变量
2、只包含方法、属性索引器、事件
3、成员不能被实现
4、成员可以不用写访问修饰符,不能是私有的
5、接口不能继承类,但可以继承另一个接口
接口的使用规范
1、类可以继承多个接口
2、类继承接口狗,必须实现接口中所有成员
特点
1、它和类的声明类似
2、接口是用来继承的
3、接口不能被实例化,但可以作为容器存储对象
2、接口的声明
关键字 interface
语法
interface I接口名{}
接口是抽象行为的基类
接口命名规范:帕斯卡前加I
interface IFly{
void Fly(); //方法
string Name{ //属性
get;
set;
}
int this[int index]{ //索引器
get;
set;
}
event Action doSomthing; //事件
}
3、接口的使用
接口用来继承
1、类可以继承1个类,n个接口
2、继承了接口后,必须实现其中的内容,并且必须是是public(不写默认为public)
3、实现的接口函数,可以加virtual再在子类重写
4、接口也遵循里氏替换原则,接口可以继承接口
IFly fly = new Person();
interface IFly
{
void Fly();
string Name
{
get;
set;
}
int this[int index]
{
get;
set;
}
event Action doSomthing;
}
class Animal { }
class Person : Animal, IFly
{
public int this[int index] { get { return 0; } set { } }
public string Name { get; set; }
public event Action doSomthing;
public virtual void Fly() //可以加virtual继承下去
{
}
}
4、接口可以继承接口
接口继承接口时,不需要实现
待类继承接口后,类自己去实现所有内容
interface IWork{
void Work();
}
interface IMove : IFly,IWork{
void Move();
}
5、显示实现接口
当一个类继承两个接口,但是接口中存在着同名方法时
注意:显示实现接口时,不能写访问修饰符
Player p = new Player();
(p as IAtk).Atk();
(p as ISuperAtk).Atk();
p.Atk();
interface IAtk{
void Atk();
}
interface ISuperAtk{
void Atk();
}
class Player : IAtk,ISuperAtk{
//显示实现接口,就是用接口名.行为名
void IAtk.Atk(){}
void ISuperAtk.Atk(){}
public void Atk(){}
}
总结
继承类:
是对象间的继承,包括特征行为等
继承接口:
是行为间的继承,继承接口的行为规范,按照规范去实现内容
由于接口也遵循里氏替换原则,所以可以用接口容器装对象,就可以实现装载各种毫无关系但却有相同行为的对象
注意:
1、接口值包含成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
2、可以继承多个接口,但是只能继承一个类
3、接口可以继承接口,相当于行为合并,待子类继承时再去实现具体的行为
4、接口可以被显示实现,主要用于实现不同接口中的同名函数的不同表现
5、实现的接口方法,可以加virtual,之后子类再重写
思考 电脑使用USB接口读取数据
//多态来模拟移动硬盘、u盘、MP3插到电脑上读取数据
//移动硬盘与u盘都属于存储设备
//MP3属于播放设备,但是它们都能插再电脑上传输数据
//电脑提供了一个usb接口,请实现电脑的传输数据的功能
StorageDevice yingPan = new StorageDevice("硬盘");
StorageDevice uPan = new StorageDevice("u盘");
MP3 mP3 = new MP3();
Computer c = new Computer();
c.usb1 = yingPan;
c.usb1.ReadData();
c.usb2 = uPan;
c.usb2.ReadData();
c.usb3 = mP3;
c.usb3.ReadData();
interface IUSB
{
void ReadData();
}
class StorageDevice : IUSB
{
public string name;
public StorageDevice(string name)
{
this.name = name;
}
public void ReadData()
{
Console.WriteLine(name+"传输数据");
}
}
class MP3 : IUSB
{
public void ReadData()
{
Console.WriteLine("MP3传输数据");
}
}
class Computer
{
public IUSB usb1;
public IUSB usb2;
public IUSB usb3;
}
4、密封方法
关键字
sealed
作用
让虚方法或者抽象方法之后不能被重写
特点
和override一起出现
abstract class Animal{
public string name;
public abstract void Eat();
public virtual void Speak(){}
}
class Person : Animal{
public sealed override void Eat(){}
public sealed override void Speak(){}
}