【C#补全计划:类和对象(九)】接口
一、接口的概念
1. 概念:接口是行为的抽象规范,也是一种自定义类型
2. 接口声明规范:
(1)不包含成员变量
(2)只包含属性、方法、索引器、事件
(3)成员不能被实现
(4)成员可以不写访问修饰符(默认public),不能是私有的
(5)接口不能继承类,但是可以继承另一个接口
3. 接口使用规范
(1)类可以继承多个接口
(2)类继承接口后,必须实现接口中所有成员
4. 特点:
(1)接口的声明和类的声明类似
(2)接口是用来继承的
(3)接口不能被实例化,但是可以作为容器存储对象
二、接口的声明
1. 关键字:interface
2. 语法:
interface 接口名
{
}
3. 作用:接口是抽象行为的“基类”
4. 命名规范:I + 帕斯卡命名
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}
}
三、接口的使用
1. 类可以继承一个父类,n个接口
2. 类继承接口后,必须实现接口中的所有内容,并且必须是public的
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}public void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}
}
3. 实现的接口函数,可以加virtual再在子类重写
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}// 实现的接口函数,可以加virtual再在子类重写public virtual void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}
}
4. 接口也遵循里氏替换原则
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}// 实现的接口函数,可以加virtual再在子类重写public virtual void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}class Program{static void Main(string[] args){// 接口也遵顼里氏替换原则IFly f = new Bird();}}
}
5. 接口可以继承接口
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}interface IWalk // 声明第二个接口{void walk();}interface IMove : IFly, IWalk // 接口继承接口{void move(string value);}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}// 实现的接口函数,可以加virtual再在子类重写public virtual void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}class Person : IMove{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get {return index;}set {}}public virtual void fly() // 实现接口方法{Console.WriteLine("人乘坐飞机飞了" + Height + "米");}public void walk() // 实现接口方法{Console.WriteLine("人用腿行走");}public void move(string value) // 实现接口方法{if(value == "fly") {fly();} else if(value == "walk") {walk();}}}class Program{static void Main(string[] args){// 接口也遵顼里氏替换原则IFly f = new Bird();// 都遵循里氏替换原则IMove move = new Person();IFly fly = new Person();IWalk walk = new Person();}}
}
四、显式实现接口
1. 作用:当一个类继承多个接口,而接口中存在同名方法时,使用显式实现接口
2. 语法:接口名.函数名() {}
3. 代码:
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}interface IWalk // 声明第二个接口{void walk();}interface IMove : IFly, IWalk // 接口继承接口{void move(string value);}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}// 实现的接口函数,可以加virtual再在子类重写public virtual void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}class Person : IMove{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get {return index;}set {}}public virtual void fly() // 实现接口方法{Console.WriteLine("人乘坐飞机飞了" + Height + "米");}public void walk() // 实现接口方法{Console.WriteLine("人用腿行走");}public void move(string value) // 实现接口方法{if(value == "fly") {fly();} else if(value == "walk") {walk();}}}/*----------------------------------------------------------*/// 显式实现接口interface IAtk{void atk();}interface ISkill{void atk();}class Player : IAtk, ISkill // 实现多个接口{void IATK.atk() // 显式实现接口方法{Console.WriteLine("玩家普通攻击");}void ISkill.atk() // 显式实现接口方法{Console.WriteLine("玩家释放技能攻击");}}class Program{static void Main(string[] args){// 接口也遵顼里氏替换原则IFly f = new Bird();// 都遵循里氏替换原则IMove move = new Person();IFly fly = new Person();IWalk walk = new Person();}}
}
4. 注意:
若使用子类容器,则无法调用显式实现接口的方法,需要转换尾父类容器。
using System;namespace Interface
{interface IFly // 声明接口{int Height { // 成员属性不能被实现get; set;}int this[int index] { // 成员索引器不能被实现get; set;}void fly(); // 成员方法不能被实现}interface IWalk // 声明第二个接口{void walk();}interface IMove : IFly, IWalk // 接口继承接口{void move(string value);}class Animal // 基类{string Name {get; set;}}// 类可以继承一个父类,n个接口// 类继承接口后,必须实现接口中的所有内容,并且必须是public的class Bird : Animal, IFly // 继承父类和接口{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get { return index; }set { }}// 实现的接口函数,可以加virtual再在子类重写public virtual void fly() // 实现接口方法{Console.WriteLine("鸟用翅膀飞了" + Height + "米");}}class Person : IMove{public int Height { // 实现接口属性get; set;}public int this[int index] { // 实现接口索引器get {return index;}set {}}public virtual void fly() // 实现接口方法{Console.WriteLine("人乘坐飞机飞了" + Height + "米");}public void walk() // 实现接口方法{Console.WriteLine("人用腿行走");}public void move(string value) // 实现接口方法{if(value == "fly") {fly();} else if(value == "walk") {walk();}}}/*----------------------------------------------------------*/// 显式实现接口interface IAtk{void atk();}interface ISkill{void atk();}class Player : IAtk, ISkill // 实现多个接口{void IAtk.atk() // 显式实现接口方法{Console.WriteLine("玩家普通攻击");}void ISkill.atk() // 显式实现接口方法{Console.WriteLine("玩家释放技能攻击");}}class Program{static void Main(string[] args){// 接口也遵顼里氏替换原则IFly f = new Bird();// 都遵循里氏替换原则IMove move = new Person();IFly fly = new Person();IWalk walk = new Person();Player player = new Player();// person.atk(); // 调用接口方法, 编译报错Console.WriteLine("转换为IATK类:");(player as IAtk)?.atk(); // 显式实现接口方法,调用时需要转换类型Console.WriteLine("转换为ISkill类:");(player as ISkill)?.atk(); // 显式实现接口方法,调用时需要转换类型}}
}
至此,面向对象的三大特性之一:多态就学习完了。
今天的学习就到这里了,感谢阅读。
再见!