21.面向对象-多态-接口
21.1 知识点
接口的概念
- 接口是行为的抽象规范
- 它也是一种自定义类型
- 接口是类用来继承的
- 关键字:
interface
接口声明的规范
- 不包含成员变量
- 只包含方法、属性、索引器、事件
- 成员不能被实现
- 成员可以不写访问修饰符,不能是私有的
- 接口不能继承类,但是可以继承另一个接口
接口的使用规范
- 类可以继承多个接口
- 类继承接口后,必须实现接口中所有成员
接口的特点
- 类似于类的声明
- 接口用来继承
- 接口不能被实例化,但是可以作为容器存储对象
接口实际作用举例
- 假设有个动物类 人和鸟继承动物类 但人不能飞 鸟可以飞 不能将飞这个行为抽象到动物类中
- 但是可以写一个飞的接口 让鸟继承 人不继承
- 这时 要是有个继承了机械类的飞机 也可以继承飞的接口
接口的声明
class语句块外namespace语句块内
// 接口关键字:interface
// 语法:
// interface 接口名
// {
// }
// 一句话记忆:接口是抽象行为的“基类”
// 接口命名规范:帕斯卡前面加个I
// 实例
// 飞翔接口
interface IFly
{
// int f; // 报错,接口不包含成员变量
// 方法,不能加方法体,不能被实现,默认是public
void Fly();
// 属性,get和set也不能有逻辑,不能被实现,默认是public
string Name
{
get;
set;
}
// 索引器,get和set也不能有逻辑,不能被实现,默认是public
int this[int index]
{
get;
set;
}
// 事件
event Action doSomthing;
}
接口的使用
class语句块外namespace语句块内
// 动物类
class Animal
{
}
// 1.类可以继承1个类,n个接口
class Person : Animal, IFly
{
// 2.继承了接口后,必须实现其中的内容,并且必须是public的
// 3.实现的接口函数,可以加virtual再在子类重写
public virtual void Fly()
{
}
public string Name
{
get;
set;
}
public int this[int index]
{
get
{
return 0;
}
set
{
}
}
public event Action doSomthing;
}
接口可以继承接口
class语句块外namespace语句块内
// 接口继承接口时,不需要实现
// 待类继承接口后,类自己去实现所有内容
// 走路接口
interface IWalk
{
void Walk();
}
// 移动接口,继承飞翔接口和走路接口
interface IMove : IFly, IWalk
{
}
// 移动测试类
class MoveTest : IMove
{
// 因为移动接口继承飞翔接口和走路接口
// 所以必须实现飞翔接口和走路接口里所有成员
public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public event Action doSomthing;
public void Fly()
{
throw new NotImplementedException();
}
public void Walk()
{
throw new NotImplementedException();
}
}
主函数内
// 4.接口也遵循里氏替换原则
IMove imove1 = new MoveTest();
IFly ifly1 = new MoveTest();
IWalk iwalk1 = new MoveTest();
// 因为实际容器是IWalk,所以只能使用IWalk的成员Walk
iwalk1.Walk();
//(iwalk1 as MoveTest).Fly();//报错,因为实际容器是IWalk,不能使用飞翔相关
(iwalk1 as MoveTest).Fly(); // 强转后,可以使用飞翔相关
显示实现接口
class语句块外namespace语句块内
// 当一个类继承两个接口
// 但是接口中存在着同名方法时
// 注意:显示实现接口时不能写访问修饰符
// 攻击方法接口
interface IAttack
{
void Attack();
}
// 超级攻击方法接口
interface ISuperAttack
{
void Attack();
}
// 同时继承攻击方法接口和超级攻击方法接口
class Player : IAttack, ISuperAttack
{
// 假如直接实现Attack,那么假如Player调用攻击
// 无论容器是攻击接口还是超级攻击接口,都会是同个行为
// 违背了接口抽象行为概念
public void Attack()
{
Console.WriteLine("Player攻击");
}
// 显示实现接口可以解决接口同名成员问题
// 显示实现接口就是用 接口名.行为名 去实现
void IAttack.Attack()
{
Console.WriteLine("IAttack攻击");
}
void ISuperAttack.Attack()
{
Console.WriteLine("ISuperAttack攻击");
}
}
主函数内
IAttack iAttack = new Player();
ISuperAttack iSuperAttack = new Player();
// 显示实现了接口,可以实现不同行为
// 要是没有显示实现了接口,都会输出Player攻击
iAttack.Attack(); // IAttack攻击
iSuperAttack.Attack(); // ISuperAttack攻击
Player player = new Player();
(player as IAttack).Attack(); // IAttack攻击
(player as ISuperAttack).Attack(); // ISuperAttack攻击
player.Attack(); // Player攻击
总结
继承类:是对象间的继承,包括特征行为等等
继承接口:是行为间的继承,继承接口的行为规范,按照规范去实现内容
由于接口也是遵循里氏替换原则,所以可以用接口容器装对象
那么就可以实现装载各种毫无关系但是却有相同行为的对象
注意:
- 接口值包含 成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
- 可以继承多个接口,但是只能继承一个类
- 接口可以继承接口,相当于在进行行为合并,待子类继承时再去实现具体的行为
- 接口可以被显示实现,主要用于实现不同接口中的同名函数的不同表现
- 实现的接口方法可以加
virtual
关键字,之后子类再重写
21.2 知识点代码
using System;
namespace Lesson19_多态_接口
{
#region 知识点一 接口的概念
//接口是行为的抽象规范
//它也是一种自定义类型
//接口是类用来继承的
//关键字 :interface
//接口申明的规范
//1.不包含成员变量
//2.只包含方法、属性、索引器、事件
//3.成员不能被实现
//4.成员可以不用写访问修饰符,不能是私有的
//5.接口不能继承类,但是可以继承另一个接口
//接口的使用规范
//1.类可以继承多个接口
//2.类继承接口后,必须实现接口中所有成员
//特点:
//1.它和类的申明类似
//2.接口是用来继承的
//3.接口不能被实例化,但是可以作为容器存储对象
//接口实际作用举例:
//假设有个动物类 人和鸟继承动物类 但人不能飞 鸟可以飞 不能将飞这个行为抽象到动物类中
//但是可以写一个飞的接口 让鸟继承 人不继承
//这时 要是有个继承了机械类的飞机 也可以继承飞的接口
#endregion
//class语句块外 namespace语句块内
#region 知识点二 接口的申明
//接口关键字:interface
//语法:
// interface 接口名
// {
// }
//一句话记忆:接口是抽象行为的“基类”
//接口命名规范 帕斯卡前面加个I
//实例
//飞翔接口
interface IFly
{
//int ifly1;//报错 接口不包含成员变量
//方法 不能加方法体 不能被实现 默认是public
void Fly();
//private void Fly2();//报错 接口不能是私有的
//属性 get和set也不能有逻辑 不能被实现 默认是public
string Name
{
get;
set;
}
//索引器 get和set也不能有逻辑 不能被实现 默认是public
int this[int index]
{
get;
set;
}
//事件
event Action doSomthing;
}
#endregion
#region 知识点三 接口的使用
//动物类
class Animal
{
}
//1.类可以继承1个类,n个接口
class Person : Animal, IFly
{
//2.继承了接口后 必须实现其中的内容 并且必须是public的
//3.实现的接口函数,可以加virtual再在子类重写
public virtual void Fly()
{
}
public string Name
{
get;
set;
}
public int this[int index]
{
get
{
return 0;
}
set
{
}
}
public event Action doSomthing;
}
#endregion
#region 知识点四 接口可以继承接口
//接口继承接口时 不需要实现
//待类继承接口后 类自己去实现所有内容
//走路接口
interface IWalk
{
void Walk();
}
//移动接口 继承飞翔接口和走路接口
interface IMove : IFly, IWalk
{
}
//移动测试类
class MoveTest : IMove
{
//因为移动接口继承飞翔接口和走路接口
//所以必须实现飞翔接口和走路接口里所有成员
public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
public event Action doSomthing;
public void Fly()
{
}
public void Walk()
{
}
}
#endregion
#region 知识点五 显示实现接口
//当一个类继承两个接口
//但是接口中存在着同名方法时
//注意:显示实现接口时 不能写访问修饰符
//攻击方法接口
interface IAttack
{
void Attack();
}
//超级攻击方法接口
interface ISuperAttack
{
void Attack();
}
//同时继承攻击方法接口和超级攻击方法接口
class Player : IAttack, ISuperAttack
{
//假如直接实现Attack 那么假如Player调用攻击
//无论容器是攻击接口还是超级攻击接口 都会是同个行为
//违背了接口抽象行为概念
public void Attack()
{
Console.WriteLine("Player攻击");
}
//显示实现接口可以解决接口同名成员问题
//显示实现接口 就是用 接口名.行为名 去实现
void IAttack.Attack()
{
Console.WriteLine("IAttack攻击");
}
void ISuperAttack.Attack()
{
Console.WriteLine("ISuperAttack攻击");
}
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("接口");
//主函数内
#region 知识点三 接口的使用
//IFly ifly = new IFly();//报错 无法实例化接口
//4.接口也遵循里氏替换原则
//Person继承接口IFly 把接口当父类 父类装子类
IFly ifly = new Person();
#endregion
#region 知识点四 接口可以继承接口
//4.接口也遵循里氏替换原则
IMove imove1 = new MoveTest();
IFly ifly1 = new MoveTest();
IWalk iwalk1 = new MoveTest();
//因为实际容器是IWalk 所以只能使用IWalk的成员Walk
iwalk1.Walk();
//iwalk1.Fly();//报错 因为实际容器是IWalk 不能使用飞翔相关
(iwalk1 as MoveTest).Fly();//强转后 可以使用飞翔相关
#endregion
#region 知识点五 显示实现接口
IAttack iAttack = new Player();
ISuperAttack iSuperAttack = new Player();
//显示实现了接口 可以实现不同行为
//要是没有显示实现了接口 都会输出Player攻击
iAttack.Attack();//IAttack攻击
iSuperAttack.Attack();//ISuperAttack攻击
Player player = new Player();
(player as IAttack).Attack();//IAttack攻击
(player as ISuperAttack).Attack();//ISuperAttack攻击
player.Attack();//Player攻击
#endregion
}
}
//总结:
//继承类:是对象间的继承,包括特征行为等等
//继承接口:是行为间的继承,继承接口的行为规范,按照规范去实现内容
//由于接口也是遵循里氏替换原则,所以可以用接口容器装对象
//那么久可以实现 装载各种毫无关系但是却有相同行为的对象
//注意:
//1.接口值包含 成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
//2.可以继承多个接口,但是只能继承一个类
//3.接口可以继承接口,相当于在进行行为合并,待子类继承时再去实现具体的行为
//4.接口可以被显示实现 主要用于实现不同接口中的同名函数的不同表现
//5.实现的接口方法 可以加 virtual关键字 之后子类 再重写
}
21.3 练习题
人、汽车、房子都需要等级,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记 使用接口实现登记方法
class语句块外 namespace语句块内
// 登记接口
interface IRegister
{
void Register();
}
// 人类
class Person : IRegister
{
public void Register()
{
Console.WriteLine("派出所登记");
}
}
// 车类
class Car : IRegister
{
public void Register()
{
Console.WriteLine("车管所登记");
}
}
// 房子类
class House : IRegister
{
public void Register()
{
Console.WriteLine("房管局登记");
}
主函数内
// 主函数内
IRegister[] IRegisterArray = new IRegister[] { new Person(), new House(), new Car() };
for (int i = 0; i < IRegisterArray.Length; i++)
{
IRegisterArray[i].Register();
}
麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅
- 直升机和部分鸟能飞
- 鸵鸟和企鹅不能飞
- 企鹅和天鹅能游泳
- 除直升机,其它都能走
- 请用面向对象相关知识实现
class语句块外 namespace语句块内
// 鸟类
abstract class Bird
{
// 鸟都能能走
public abstract void Walk();
}
// 飞行接口
interface IFly
{
void Fly();
}
// 游泳接口
interface ISwimming
{
void Swimming();
}
// 麻雀类
class Sparrow : Bird, IFly
{
public void Fly()
{
}
public override void Walk()
{
}
}
// 鸵鸟类
class Ostrich : Bird
{
public override void Walk()
{
}
}
// 企鹅类
class Penguin : Bird, ISwimming
{
public void Swimming()
{
}
public override void Walk()
{
}
}
// 鹦鹉类
class Parrot : Bird, IFly
{
public void Fly()
{
}
public override void Walk()
{
}
}
// 天鹅类
class Swan : Bird, IFly, ISwimming
{
public void Fly()
{
}
public void Swimming()
{
}
public override void Walk()
{
}
}
// 直升机类
class Helicopter : IFly
{
public void Fly()
{
}
}
多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据
- 移动硬盘与U盘都属于存储设备
- MP3属于播放设备
- 但他们都能插在电脑上传输数据
- 电脑提供了一个USB接口
- 请实现电脑的传输数据的功能
class语句块外 namespace语句块内
// USB接口
interface IUSB
{
void ReadData();
}
// 存储设备类
class StorageDevice : IUSB
{
public string name;
public StorageDevice(string name)
{
this.name = name;
}
public void ReadData()
{
Console.WriteLine("{0}传输数据", name);
}
}
// MP3类
class MP3 : IUSB
{
public void ReadData()
{
Console.WriteLine("MP3传输数据");
}
}
// 电脑类
class Computer
{
// 电脑有一个USB接口 外部给他赋值 相当于插到电脑上
public IUSB usb1;
}
主函数内
// 主函数内
StorageDevice moveDevice = new StorageDevice("移动硬盘");
StorageDevice uDevice = new StorageDevice("U盘");
MP3 mp3 = new MP3();
Computer computer = new Computer();
computer.usb1 = moveDevice;
computer.usb1.ReadData();//移动硬盘传输数据
computer.usb1 = uDevice;
computer.usb1.ReadData();//U盘传输数据
computer.usb1 = mp3;
computer.usb1.ReadData();//MP3传输数据
21.4 练习题代码
using System;
namespace Lesson19_练习题
{
//class语句块外 namespace语句块内
#region 练习题一
//人、汽车、房子都需要登记,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记
//使用接口实现登记方法
//登记接口
interface IRegister
{
void Register();
}
//人类
class Person:IRegister
{
public void Register()
{
Console.WriteLine("派出所登记");
}
}
//车类
class Car:IRegister
{
public void Register()
{
Console.WriteLine("车管所登记");
}
}
//房子类
class House:IRegister
{
public void Register()
{
Console.WriteLine("房管局登记");
}
}
#endregion
#region 练习题二
//麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅
//直升机和部分鸟能飞
//鸵鸟和企鹅不能飞
//企鹅和天鹅能游泳
//除直升机,其它都能走
//请用面向对象相关知识实现
//鸟类
abstract class Bird
{
//鸟都能能走
public abstract void Walk();
}
//飞行接口
interface IFly
{
void Fly();
}
//游泳接口
interface ISwimming
{
void Swimming();
}
//麻雀类
class Sparrow : Bird, IFly
{
public void Fly()
{
}
public override void Walk()
{
}
}
//鸵鸟类
class Ostrich:Bird
{
public override void Walk()
{
}
}
//企鹅类
class Penguin : Bird,ISwimming
{
public void Swimming()
{
}
public override void Walk()
{
}
}
//鹦鹉类
class Parrot : Bird,IFly
{
public void Fly()
{
}
public override void Walk()
{
}
}
//天鹅类
class Swan : Bird,IFly,ISwimming
{
public void Fly()
{
}
public void Swimming()
{
}
public override void Walk()
{
}
}
//直升机类
class Helicopter : IFly
{
public void Fly()
{
}
}
#endregion
#region 练习题三
//多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据
//移动硬盘与U盘都属于存储设备
//MP3属于播放设备
//但他们都能插在电脑上传输数据
//电脑提供了一个USB接口
//请实现电脑的传输数据的功能
//USB接口
interface IUSB
{
void ReadData();
}
//存储设备类
class StorageDevice : IUSB
{
public string name;
public StorageDevice(string name)
{
this.name = name;
}
public void ReadData()
{
Console.WriteLine("{0}传输数据", name);
}
}
//MP3类
class MP3 : IUSB
{
public void ReadData()
{
Console.WriteLine("MP3传输数据");
}
}
//电脑类
class Computer
{
//电脑有一个USB接口 外部给他赋值 相当于插到电脑上
public IUSB usb1;
}
#endregion
class Program
{
static void Main(string[] args)
{
Console.WriteLine("接口练习题");
//主函数内
#region 练习题一
IRegister[] IRegisterArray = new IRegister[] { new Person(), new House(), new Car() };
for (int i = 0; i < IRegisterArray.Length; i++)
{
IRegisterArray[i].Register();
}
#endregion
#region 练习题三
StorageDevice moveDevice = new StorageDevice("移动硬盘");
StorageDevice uDevice = new StorageDevice("U盘");
MP3 mp3 = new MP3();
Computer computer = new Computer();
computer.usb1 = moveDevice;
computer.usb1.ReadData();//移动硬盘传输数据
computer.usb1 = uDevice;
computer.usb1.ReadData();//U盘传输数据
computer.usb1 = mp3;
computer.usb1.ReadData();//MP3传输数据
#endregion
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com