C#基础之接口的学习
1、定义
接口为不同应用的实现提供了一种规范和约束,只要每个应用都遵守这种规范和约束,整个系统就可以得到有效的组织,从而为应用系统的低代价开发提供有效的途径。
接口使用interface 关键字进行定义,可由方法、属性、事件、索引器或这四种成员类型的任意组合构成。它不实现任何的方法或属性,只是告诉继承它的类至少要实现哪些功能,继承它的类可以增加自己的方法。
接口声明:
interface ISample
{
void Sample(int x); //方法
int count { get; set; } //属性(可读,可写)
event EventHandler OnDraw; //事件
string this[int index] { get; set; } //索引器
}
2、特点
-
接口类似于抽象类,不能直接实例化接口
-
接口中的方法都是抽象方法(并不是定义成抽象方法),实现接口的任何非抽象类都必须实现接口的所有成员
-
当显式实现接口的成员时,只能通过接口实例访问成员
当隐式实现接口的成员时,可以通过类实例访问成员,也可以通过接口实例访问成员
无论哪种实现方式,前提是成员必须为公有的
-
接口不能保函常量、字段、运算符、实力构造函数、静态成员、析构函数或类型等
-
接口成员是自动公开的,且不能包含任何访问修饰符
-
一个接口可从多个接口继承,一个类或结构可继承多个接口,但接口不能继承类
-
当一个类既继承基类,又继承接口时,必须将基类写在前面,基类和接口之间用逗号隔开。一个类只能有一个基类,但可以继承多个接口
关于显式实现接口和隐式实现接口的解释:
(1)隐式实现接口
创建一个IChinese接口,包含一个Speak成员
namespace InterfaceLearn
{
public interface IChinese
{
string Speak();
}
}
创建一个Speaker类继承该接口,实现接口成员
namespace InterfaceLearn
{
public class Speaker:IChinese
{
public string Speak()
{
return "中文";
}
}
}
隐式实现调用方法:
(通过接口实例访问成员)
或者
(通过类实例访问成员)
(2)显示实现接口
创建一个IEnglish接口,包含一个Speak成员
namespace InterfaceLearn
{
public interface IEnglish
{
string Speak();
}
}
创建一个English类继承该接口,实现接口成员
namespace InterfaceLearn
{
public class English:IEnglish
{
string IEnglish.Speak()
{
return "英语";
}
}
}
显式实现调用方法:
(只能通过接口实例访问成员)
如果采用类实例访问成员则会出现如下情况:
3、接口与抽象类的区别
-
接口用于规范,抽象类用于共性
-
抽象类不能被实例化,但能拥有自己的成员字段和非抽象方法,但接口比抽象类更加抽象,其成员只能是一般的方法、属性和索引函数,不能拥有自己的成员字段和构造函数、
-
抽象类是类,所以只能被单继承,但是接口却可以一次实现多个继承
-
抽象类可以提供某些方法的部分实现,接口不可以
-
接口、抽象类、非抽象类都可以继承接口
-
用abstract声明的抽象类中的方法必须有访问修饰符如public等关键字进行修饰,其次抽象类里面的方法须用abstract声明为抽象方法或用virtual声明为虚拟方法(非抽象方法除外,虚拟方法有简单执行代码,派生类中可以选择不重写,抽象方法没有任何执行代码,派生类中必须重写)。在其派生类中重写抽象方法或虚拟方法时,必须用override修饰。而在用interface声明的接口中的接口方法,首先不允许是静态的,其次除了无执行代码外不能加任何访问限制修饰符,且不能用virtual或abstract进行修饰。同时在继承接口的类中不能用override修饰符来重写方法,且必须实现继承的接口中的所有方法,但可以用new关键字来隐藏父接口中的方法。
完整实例:
1、创建两个接口:IPerson、IStudent
namespace InterfaceLearn
{
public interface IPerson
{
string Name { get; set; }
void Show(string name);
}
}
namespace InterfaceLearn
{
public interface IStudent
{
string StudentId { get; set; }
void Show(string studentId);
}
}
2、创建一个Student类继承两个接口(包含显式实现和隐式实现)
namespace InterfaceLearn
{
public class Student : IPerson, IStudent
{
//隐式实现接口
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public void Show(string name)
{
Console.WriteLine("姓名为{0}", name);
}
//显式实现接口
private string _studentId;
string IStudent.StudentId
{
get
{
return _studentId;
}
set
{
_studentId = value;
}
}
void IStudent.Show(string studentId)
{
Console.WriteLine("学号为{0}", studentId);
}
}
}
3、执行代码
namespace InterfaceLearn
{
class Program
{
static void Main(string[] args)
{
Student s = new Student();
Console.WriteLine("输入姓名");
s.Name = Console.ReadLine();
Console.WriteLine("输入学号");
IStudent id = s;//由于是显式实现,所以必须通过接口实例
id.StudentId = Console.ReadLine();
s.Show(s.Name);
id.Show(id.StudentId);
Console.ReadLine();
}
}
}