- 接口:接口是一种用来定义程序的协议,它描述可属于任何类或结构的一组相关行为,可以把它看成是实现一组类的模板。接口可有方法、属性、事件和索引器或这4种成员类型的任何组合构成,但不能包含字段。
类和结构可以像类继承基类一样从接口继承,但是可以继承多个接口。当类和结构继承接口时,它继承成员定义但不继承实现。若要实现接口成员,类和结构中的成员必须是公共的,非静态的,并且与接口成员具有相同的名称和签名。类或结构的属性和索引器可以作为接口中定义的属性或索引器定义额外的访问器。例如,接口可以声明一个带有get访问其的属性,而实现该接口的类可以声明同时带有set和get访问器的同一属性。但是,如果属性或索引器使用显示实现,则访问器必须匹配。
另外,接口可以继承其他接口,类可以通过其继承的基类或接口多次继承某个接口,在这种情况下,如果该接口声明为新类的一部分,则类只能实现该接口一次。如果没有将继承的接口声明为新类的一部分,其实现将由声明它的基类提供。基类可以使用虚拟成员实现接口成员。在这种情况下,继承接口的类可通过重写虚拟成员来更改接口行为。
-
-
-
-
- 定义接口
-
-
-
格式:访问修饰符(public) 关键字(interface) 接口的名字(开始字母是大写I)
{
//只能定义属性,索引器,方法和事件
void Print();
string Name{get;set;}
string this[int idx]{get;set}
}
-
-
-
-
- 接口的继承
-
-
-
接口之间也可以实现继承,和类与类之间的继承方式完全一样。
派生接口:基接口
{
//
}
注:接口可以继承接口,不可以继承类。一个类有且只有一个基类,但是一个类可以实现多个接口,如果一个类实现接口和继承类,先写基类后写接口,逗号隔开,继承类必须放在接口的前面。
-
-
-
-
- 类实现接口(当类实现多个接口时,有可能要显式某个或某些实现接口的方法(名字相同))
-
-
-
如果一个实现了某个接口,则必须实现接口中定义的所有的内容。
-
-
-
-
- 接口作为方法的参数(形参)
-
-
-
凡是实现接口的类的对象都可以作为调用方法的实参进行传递。
-
-
-
-
- 接口作为方法的返回类型
-
-
-
凡是实现接口的类的对象,都可以作为方法返回值。
接口的特征:
- 接口类似抽象基类,继承接口的任何抽象类型都必须实现接口的所有成员。
- 不能直接实例化接口。
- 接口可以包含事件、索引器、方法和属性。
- 接口不能包含方法的实现。
- 类和结构可以从多个接口继承。
- 接口自身可以从多个接口继承。
注:1、接口声明时,通常以大写字母I开头。2、接口声明时,除了interface关键字和接口名称外,其他的都是可选项。3、接口使用new、public、protected、internal和private等修饰符声明接口,但接口成员必须是公共的。4、继承接口时,必须在子类和接口之间用冒号(:)另外,如果继承多个接口,那么在继承的每个接口之间用逗号(,)隔开。
例1:类实现接口
public interface IFly
{
void Fly();
string Name { get; set; }
int this[int idx] { get; set; }
}
public class Bird : IFly
{
public void Fly();
public string Name { get; set; }
public int this[int idx] { get; set; }
}
例2: 接口继承接口
public interface IBase
{
void Fly();
}
public interface IFly:IBase
{
new void Fly();
string Name { get; set; }
int this[int idx] { get; set; }
}
例3:利用接口选择不同的语言。
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
/// <summary>
/// 声明一个接口,用于定义Seak方法,而具体Speak方法功能的实现是在类中进行的
/// </summary>
interface ISelectLanguage
{
void Speak(string str);
}
/// <summary>
/// 如果跟中国人对话,则说汉语
/// </summary>
class C_SpeakChinese : ISelectLanguage
{
public void Speak(string str)
{
MessageBox.Show("您对中国友人说:" + str, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
/// <summary>
/// 如果跟美国人对话,则说英语
/// </summary>
class C_SpeakEnglish : ISelectLanguage
{
public void Speak(string str)
{
MessageBox.Show("您对美国友人说:" +str, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 0;
}
public bool CheckChinese(string str)
{
bool flag = false;
UnicodeEncoding a = new UnicodeEncoding();
byte[] b = a.GetBytes(str);
for(int i=0;i<b.Length;i++)
{
i++;
if (b[i] != 0)
{
flag = true;
}
else
{
flag = false;
}
}
return flag;
}
private void button1_Click(object sender, EventArgs e)
{
if (txtContent.Text == "")
{
MessageBox.Show("不想跟友人说点什么吗?", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
if (comboBox1.SelectedIndex == 0)//与中国人对话
{
if (CheckChinese(txtContent.Text))
{
ISelectLanguage Interface1 = new C_SpeakChinese();
Interface1.Speak(txtContent.Text);
}
else
{
MessageBox.Show("请和中国友人说汉语?", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
else//与美国人对话
{
if (CheckChinese(txtContent.Text))
{
MessageBox.Show("请和美国友人说英语?", "警告", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else
{
ISelectLanguage Interface1 = new C_SpeakEnglish();
Interface1.Speak(txtContent.Text);
}
}
}
}
}
接口作为方法的参数(形参): 凡是实现接口的类的对象都可以作为调用方法的实参进行传递。
接口作为方法的返回类型:凡是实现接口的类的对象,都可以作为方法的返回值
C# 接口的显示实现和隐示实现
接口的实现很多人都知道,但接口的实现方式分显示实现和隐示实现不知道是不是很多人知道呢!但我觉的公司技术部里很少提到这个,就想起来写写这篇blogs。
目前常用的方式:
public interface IReview
{
void GetReviews();
}
public class ShopReview :IReview
{
public void GetReviews(){}
}
这种方式是隐示实现:
IReview rv = new ShopReview();rv.GetReviews();
ShopReview rv = new ShopReview();rv.GetReviews();
都可以调用GetReviews这个方法。
还有一种方式是显示实现:
public interface IReview
{
void GetReviews();
}
public class ShopReview :IReview
{
void IReview.GetReviews(){}
}
通过这种方式的接口实现。GetReviews就只能通过接口来调用:
IReview rv = new ShopReview();rv.GetReviews();
下面的这种方式将会编译错误:
ShopReview rv = new ShopReview();rv.GetReviews();
结论:
隐示实现接口和类都可以访问
显示实现只有接口可以访问。
显示实现益处
1:隐藏代码的实现
2:在使用接口访问的系统中,调用者只能通过接口调用而不是底层的类来访问。
PS:可以运用到公司目前的接口+Sevice架构的系统中。避免我们总是要求大家一定要通过接口访问。因为现在不用接口访问也不行
1.C#类和接口的区别
接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!
而类是负责功能的具体实现!
在类中也有抽象类的定义,抽象类与接口的区别在于:
抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进一步的专业化。
但接口是一个行为的规范,里面的所有东西都是抽象的!
一个类只可以继承一个基类也就是父类,但可以实现多个接口
PS:接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设计原则以及设计模式的使用中,无不体现作为一个接口的使用好处,最直接的就是设计原则中OCP(开放封闭原则),我们使用接口,而不需要关心他的具体实现,具体实现的细节变化也无关客户端(使用接口的类)的使用,对与扩展是开放的,我们可以另写一个接口的实现来扩展当前程序,而不影响上层的使用,但对修改是封闭的,即我们不能够再去修改接口的定义,当然这个“不能够”是指在规范原则上不应该这么做!
2.抽象类和接口的区别
答:抽象类(abstract class)可以包含功能定义和实现,接口(interface)只能包含功能定义
抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性
分析对象,提炼内部共性形成抽象类,用以表示对象本质,即“是什么”
为外部提供调用或功能需要扩充时优先使用接口