接口:
派生类只能继承一个类(单根性决定的),但是如果需要继承多个类时候,就可以使用接口来实现,一个派生类可以继承多个接口
类只能单继承,但接口可以多实现
ps:接口这里一般称为实现,而不称为继承
接口的成员不能加访问修饰符,默认为public
接口是一种规范,为了实现多态
接口只能包括方法,属性,事件,索引器(其实这些都是方法)
当一个抽象类继承了接口的时候,如果不想把接口中的成员实现,可以把该成员实现为abstract
接口成员不能有定义,就是说接口不能有方法体,接口不能有实现,空的实现也不可以,光说不做,只是定义了一组未实现的成员
一个类如果继承了一个接口,则必须实现该接口中所有的成员(这里是实现,和虚方法以及抽象类中的重写类似但不同)
接口中只能有方法,属性,事件,索引器,但是不能有字段和构造函数
接口与接口之间可以继承,并且可以多继承
类可以继承接口,并且可以多继承,但是接口不能继承类
如果一个类继承了另外一个类并且实现了其他接口,则继承的类必须写在接口的前面
为了统一接口一般以I开头,以able结尾,表示“我可以“,表示一种能力
抽象类,静态类,接口都不能实例化
子类继承接口的时候有普通实现和显示实现两种方式,一般使用普通实现,显示实现和普通实现的效果是一样的,但是显示实现解决了子类中有相同方法的名称的问题,显示实现接口,只能通过接口变量来调用,应为显示实现的成员访问修饰符为private
接口的功能要尽量单一,满足单一功能原则,一个接口尽量只有一个单一功能
这样在实现多态的时候才能更灵活
例如:
超人会飞,会游泳
鱼会游泳
鸟会飞
这时候可以把飞和游泳分开成两个接口,一个为游泳的接口,一个为飞的接口
鱼实现游泳的接口,鸟实现飞的接口,超人同时实现飞和游泳的接口,这样就可以满足所有的要求
但是如果飞和游泳写在一个接口里面,则鱼和鸟就无法实现这个接口
接口实现多态:
接口类
public interface IPerson
{
string SayHelo();
}
学生类:
public class Student : IPerson
{
public string SayHelo()
{
return "I am a Student";
}
}
老师类:
public class Teacher : IPerson
{
public string SayHelo()
{
return "I am a Teacher";
}
}
多态的实现
static void Main(string[] args){
//用接口实现多态
IPerson[] ip = { new Student(), new Teacher() };
foreach (var item in ip)
{
Console.WriteLine(item.SayHelo());
}
Console.ReadKey();
}
接口的成员:
/// <summary>
/// 接口,这里命名不规范,随便写的
/// </summary>
public interface Class1
{
/// <summary>
/// 接口里的成员不能有访问修饰符
/// 一个类只能继承一个类,类继承的单根性
/// 但是一个类可以实现多个接口,接口的多实现
///
/// 接口解决了不同类型之间的多态的问题
/// 比如鱼和船,他们属于不同的类,没法抽象出一个父类,但是他们都可以在水里游,只是方式不同
/// 要实现他们的多态,就可以考录使用接口,定义一个游的接口,然后让鱼和穿去实现它,从而实现船和鱼的不同游泳方式
/// </summary>
void SayHi();
/// <summary>
/// 在接口里面这表示一个未实现的属性
/// </summary>
string Name
{
get;
set;
}
/// <summary>
/// 索引器
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
string this[int index]
{
get;
set;
}
}
/// <summary>
/// 实现接口
/// </summary>
public class Person : Class1
{
/// <summary>
/// 实现方法SayHi
/// </summary>
public void SayHi()
{
throw new NotImplementedException();
}
/// <summary>
/// 实现属性Name
/// </summary>
public string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
/// <summary>
/// 实现索引器
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public string this[int index]
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
接口的效率问题:
一个类实现了接口并且实现了该接口的所有成员
这个类的子类也去实现该接口,比不实现该接口效率要高
例如:
/// <summary>
/// 定义一个接口类
/// </summary>
public interface IPerson
{
void SayHi();
}
/// <summary>
/// 定义一个学生类,实现接口,并且实现接口汇总所有的成员
/// </summary>
public class Student : IPerson
{
public void SayHi()
{
Console.WriteLine("我是个学生");
}
}
/// <summary>
/// 定义一个三号学生类,继承学生类
/// 如果一个类Student实现一个接口IPerson并且实现了该接口所有的成员
/// 这个类Student的子类GoodStudent由于继承了父类Student的方法,所以可以直接使用父类实现的方法(如这种写法:GoodStudent : Student)
/// 这样写是正确的,使用是完全没有问题的
///
/// 但是为了提高效率,我们可以直接让这个类的子类也实现父类已经实现的接口(如:GoodStudent : Student,IPerson)
/// 这是后应为父类已经实现了该接口的所有成员,所以子类不必再去实现接口的成员
/// 而且在使用多态的时候,应为查询到子类实现了接口,则可以直接转换
/// 如果子类没有实现接口,则子类需要转换成父类,然后再转换成接口类
/// 虽然两种方式都可以,但是子类实现接口之后会提高效率
/// </summary>
public class GoodStudent : Student,IPerson
{
}