接口简介
前面两篇博客C#学习笔记21-多态之抽象类和C#学习笔记20-多态之虚方法已经介绍了关于实现多态的两种方法,同时也了解了什么时候使用虚方法,什么时候使用抽象类,但是上述两种方法都建立在一个基础上,子类必须继承父类中的方法,在使用虚方法时,需要在父类中定义虚方法,而在抽象类中,也必须是使父类为抽象类,里面的方法为抽象方法;因此,在使用时会受到很多的限制。
由于继承具有单根性,一个子类只能继承一个父类,当遇到父类不同,子类中实现的方法相同时,上述两种实现多态的方法就会造成代码冗余,此时则可使用接口,如:鱼会游泳,鸭子会游泳,飞机不会游泳,汽车不会游泳,上述中鱼和鸭子是动物,飞机和汽车是交通工具,此时需使用接口
接口特点
1)接口是一种规范,只要一个类继承了一个接口,这个类就必须实现这个接口中的所有成员
2)为了多态,接口不能被实例化,也就是说接口不能创建对象
3)接口中的成员不能加“访问修饰符”,接口中的成员访问修饰符为public,不能修改
4)(默认为public)接口中的成员不能有任何实现(“光说不做”,只是定义了一组未实现的成员)
5)接口中只能由有方法、属性、索引器、事件,不能有“字段”和构造函数。
6)接口与接口之间可以继承,并且可以可以多继承
7)接口并不能去继承一个类,而类可以继承接口(接口只能继承于接口,而类既可以继承接口,也可以继承类)
8)一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承了父类A,并实现了接口IA,那么语法上A必须写在IA的前面
注:一个类可以同时继承多个接口,因此可以实现多个类的继承,理论上来讲,所有多态均可用接口实现
显示实现接口
显示实现接口的目的是为了解决方法的重名问题,如接口中的方法叫做Fly(),在子类中的方法中同样存在一个方法叫做Fly(),此时需要显示实现接口来区分这两类方法
public class Bird:IFlyable
{
public void Fly()
{
Console.WriteLine("鸟在飞");
}
void IFlyable.Fly()//显示实现接口
{
Console.WriteLine("我是接口的飞");
}
}
public interface IFlyable
{
//不允许有访问修饰符
//只能有方法、自动属性、索引器和事件
void Fly();
//不允许写方法体,不能包含字段
}
接口实例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _07接口的特点
{
class Program
{
static void Main(string[] args)
{
IFlyable fly1 = new Person();//new IFlyable();//接口不允许被实例化,抽象类不允许被实例化,静态类不允许被实例化
fly1.Fly();
//显示实现接口
IFlyable fly2 = new Bird();
fly2.Fly();
Bird bird = new Bird();
bird.Fly();
Console.ReadKey();
//显示实现接口就是为了解决方法的匿名问题
}
}
//自动属性与普通属性的区别
public class Person:IFlyable
{
string _name;
/// <summary>
/// 普通属性
/// </summary>
public string Name { get => _name; set => _name = value; }
/// <summary>
/// 自动属性
/// </summary>
public int Age//编译时会自动生成一个_age字段,比普通属性简单
{
get;
set;
}
public virtual void Fly()
{
Console.WriteLine("人类在飞");
}
}
public class Bird:IFlyable
{
public void Fly()
{
Console.WriteLine("鸟在飞");
}
void IFlyable.Fly()
{
Console.WriteLine("我是接口的飞");
}
}
public class Student:Person,IFlyable//不允许IFlyable写在Person前
{
public override void Fly()
{
Console.WriteLine("学生在飞");
}
}
public interface IFlyable
{
//不允许有访问修饰符
//只能有方法、自动属性、索引器和事件
void Fly();
//不允许写方法体,不能包含字段
}