接口概述
接口像类一样声明,里面的成员可以包含方法的签名(是隐式public的且抽象的)、属性、事件和委托,但在接口中不可以定义数据成员(字段)和静态成员。
与类不同的是,接口中仅仅是他们的声明,并不提供实现。因此接口是函数声明的集合。如果类或结构从一个接口派生,则这个类或结构负责实现该接口中所声明的所有成员。一个接口可以从多个接口继承,而一个类或结构可以实现多个接口。
出现缘由:
由于c#语言不支持一个类同时继承多个类,因此,如果某个类需要继承多方面的行为时,可以通过继承多个接口实现。
接口的作用:
接口是一组规则的集合,它规定了实现本接口的类或接口必须拥有的一组规则。体现了自然界“如果你是……则必须能……”的理念。
接口声明格式:
【修饰符】 interface 接口名(建议以大写字母I开头) 【:基接口1,基接口2,……】
-
接口中每个成员的声明后必须加分号(属性的{ }后不用加),不能包含任何实现。
-
接口内的成员声明不能包含任何修饰符,所有接口成员的访问方式自动是public;
-
声明一个类来实现一个接口,如果该类还要显示声明基类,则基类和接口之间要有逗号分开,且基类写在前面。
-
若类要实现某个接口,则必须实现该接口里的所有接口成员;
-
如果基类实现了某个接口,则其接口成员就不能在该基类的派生类中再次实现了。基类也可以在接口成员上添加virtual关键字,则派生类可以通过重写来实现这些接口成员,可以参照基类的重写.
-
如果一个类实现了多个接口,并且有些接口里的成员的签名和返回类型相同,那么,在类中只需要实现一个就能满足所有相同的了。
-
接口和as运算符:如果我们尝试将类对象引用强制转换为类未实现的接口的引用,则会抛出一个异常,那么as运算符就是为了避免这个问题。格式:
接口名 变量名=类对象名 as 接口名; 这时,如果类实现了接口,表达式返回指向接口的引用,若未实现,表达式返回null而不是抛出异常;
接口实现方式
实现接口有两种方式,隐式和显示。
/*main 方法里:*/
IMust1 m1 = new MyClass();
m1.MustCan1();//显示实现的接口方法,只能接口类型实例来调用
IMust2 m2 = new MyClass();
m2.MustCan2();
MyClass c1 = new MyClass();
c1.MustCan2();
//c1..MustCan1();//编译报错,不能调用显示实现的方法:MustCan1()
(c1 as IMust1)?.MustCan1();//但可以转换成接口引用后再调用
Console.Read();
/*准备接口和实现类*/
public interface IMust1
{
void MustCan1();
}
public interface IMust2
{
void MustCan2();
}
public class MyClass:IMust1,IMust2
{
//显式实现接口,”指名道姓”的写出要实现哪个接口的哪个方法。
void IMust1.MustCan1()
{
throw new NotImplementedException();
}
//隐式实现接口,直接方法名。
public void MustCan2()
{
throw new NotImplementedException();
}
public virtual void MyFunc() => Console.WriteLine("I'm 1111.");
}
注意:
-
显式接口实现方式,是为了希望每个接口分离实现,且方法不能使用任何访问修饰符,都默认为私有。因此只可以通过指向接口的引用来访问。
-
隐式接口实现,类或接口都可以访问接口中的方法;
所以
-
当类实现单个接口时,通常使用隐式接口实现方式,这样类的对象可以直接去访问接口方法。
-
当类实现多个接口且不同接口中有相同方法签名和返回类型的方法时,则使用显示接口实现方式。即使没有相同的方法啊签名,在实现多个接口时,仍推荐使用显示接口实现方式,因为这样可以标识出哪个方法属于哪个接口。
显示接口实现的这些成员都不能通过类的对象访问。但是可以把类对象再显示的转换为对应的接口,然后通过接口来调用方法,这样就能调用了。
论接口(interface)与抽象类(abstract class)
有网友说:
单从具体功能来看,除多重继承外(C#,Java中),抽象类似乎完全能取代接口。但是,难道接口的存在是为了实现多重继承?当然不是。我认为,抽象类和接口的区别在于使用动机。使用抽象类是为了代码的复用,而使用接口的动机是为了实现多态性。所以,如果你在为某个地方该使用接口还是抽象类而犹豫不决时,那么可以想想你的动机是什么。”
参考:http://www.cnblogs.com/huihui-gohay/archive/2009/12/13/1623070.html。
觉得有理,自己再总结下:
接口:用于约束子类行为。体现了自然界“如果你是……则必须能……”的理念。
抽象类:为继承而用,所以代码复用是显然的意图。抽象类和子类,就是一般和特殊的区别。
不管是接口还是抽象类,结合子类或实现类,都能实现多态(抽象类需要子类各自覆写方法,接口实现类则直接各自实现方法即可)。
我是想,考虑代码复用的话,用抽象类,否则用接口。和上面网友观点基本一致。
更新于:2023-04-17
标签:c#,成员,接口,实现,基类,抽象类,public From: https://www.cnblogs.com/idasheng/p/17326628.html