我们为什么需要接口?






4.93/5 (35投票s)
我们为什么需要接口?
前提条件 - 具备一定的编程知识将会有所帮助
接口的概念 – 一般来说,我们都知道接口的含义非常简单,它是两种媒介之间的媒介。让我们举一个例子来说明我所说的具体含义。
- 显示器 – 这个显示器充当了人类操作员和 CPU 之间的接口。我们并不关心幕后操作是如何执行的,比如如何显示东西,点击按钮如何产生期望的结果。简而言之,我们并不关心它的内部功能或结构。因此,它是一个抽象层。
- 自动取款机 (ATM) – 一台让你随时通过借记卡取款的机器。这台机器也是你和银行之间的接口。同样,在这种情况下,我们并不关心机器的内部结构以及整个流程是如何发生的,最终是如何吐出现金的(如果里面有现金的话:-P)。
面向对象编程 (OOP) 强烈依赖于现实世界对象的属性和状态的概念,这导致了 OOP 中接口的概念。现在,
作为关键字的接口 - 接口包含最抽象的相关功能的定义,类或结构体可以实现这些功能。接口可以实现其他接口。接口不能直接初始化,因为它们没有成员的定义,它们应该由类或结构体来实现。
在我们的编程中使用接口有很多优点:-
- 松耦合 – 让我们专注于“耦合”这个词。在这里,我将把这个词理解为一对。一对是两个人,对吧?丈夫和妻子。现在考虑一下,如果有多个丈夫和多个妻子以某种方式相互依赖,那么想想会发生什么混乱。我想现在更容易理解这个概念了(笑)。每个需要创建的类都必须具有单一职责。当一个类的职责分散在其他类中或关注点分散时,就会出现多个妻子和丈夫的情况。让我们看一段代码:-
紧耦合:-
class CustomerRepository
{
private readonly Database database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
class Database
{
public void AddRow(string Table, string Value)
{}
}
松耦合:-
class CustomerRepository
{
private readonly IDatabase database;
public CustomerRepository(Database database)
{
this.database = database;
}
public void Add(string CustomerName)
{
database.AddRow("Customer", CustomerName);
}
}
interface IDatabase
{
void AddRow(string Table, string Value);
}
class Database: IDatabase
{
public void AddRow(string Table, string Value)
{}
}
- 隐藏对象的实现细节 – 参考自动取款机和显示器的例子,让我们谈谈 WCF 服务。当我们创建一个 API 时,我们通常在接口内部声明方法签名,并用 ServiceContract 属性修饰它。好处 - 使用此服务的客户端通过接口而不是实际类暴露,使客户端远离 API 的实际实现。这解决了安全问题并使代码更具可维护性 - 为什么?每当 API 发生更改时,不需要更改接口,只需要修改实现。客户端代码不受影响。
- 以相同的方式处理不同的类型 – 如今,我们都携带智能手机,在某些方面比其他型号的手机更智能,例如功能方面。这些手机仍然提供基本/根本的目的,那就是通话。当您接到电话时,它会响铃以通知您有电话要接听。因此,每部手机都会响铃,有些只是哔哔声,有些是和弦铃声,有些是 mp3 音乐。让我们看一段代码。
interface IRingable
{
Public Sound Ring();
}
class SmartPhone: IRingable
{
public Sound Ring();
{
return PlayMp3Music();
}
}
class SemiSmartPhone: IRingable
{
public Sound Ring();
{
return PolyPhonicMusic();
}
}
class BasicPhone: IRingable
{
public Sound Ring();
{
return 8BitMusic();
}
}
class Main
{
public static void Main(string[] args)
{
List<IRingable> phones = new List<IRingable>();
IRingable htc = new SmartPhone();
Phones.Add(htc);
IRingable samsung = new SemiSmartPhone();
Phones.Add(samsung);
IRingable nokia = new BasicPhone();
Phones.Add(nokia);
// Lets Ring them all
foreach(IRingable phone in Phones)
{
phone.Ring();
}
}
}
接口使我能够以相同的方式处理所有类型的手机。因为接口抽象了手机的一个基本行为。
- 有助于使应用程序能够开放扩展 – 遵守 SOLID 原则,O – 开放扩展,封闭修改,让我们讨论一个应用程序,它可以根据用户的偏好对整数列表进行排序,并且允许用户创建自己的排序算法并将其插入到应用程序中。让我们看看如何:-
interface ISorting
{
bool execute(IList<int> numbers);
}
// Insertion Sort
class InsertionSort: ISorting
{
public bool execute(List<int> numbers)
{
System.out.println("Executing InsertionSort");
return true;
}
}
//Bubble Sort
class BubbleSort: ISorting
{
public bool execute(List<int> numbers)
{
System.out.println("Executing BubbleSort");
return true;
}
}
//Redix Sort
class RedixSort: ISorting
{
public bool execute(List<int> numbers)
{
System.out.println("Executing RedixSort");
return true;
}
}
//Custom Sort
class CustomSort: ISorting
{
public bool execute(List<int> numbers)
{
System.out.println("Executing CustomSort");
return true;
}
}
//Set Context
class Context {
private ISorting SortingStrategy;
public Context(ISorting Sortingstrategy)
{
this. SortingStrategy = Sortingstrategy;
}
Public bool executeStrategy(List<int> numbers)
{
return this.SortingStrategy.execute(numbers);
}
}
// Tests the pattern //
class StrategyExample {
public static void main(String[] args)
{
Context context;
context = new Context(new InsertionSort ());
bool resultA = context.executeStrategy(new List<int>(9,8,7,6,5,4,3,2,1));
context = new Context(new BubbleSort ());
bool resultB = context.executeStrategy(new List<int>(9,8,7,6,5,4,3,2,1));
context = new Context(new RedixSort ());
bool resultC = context.executeStrategy(new List<int>(9,8,7,6,5,4,3,2,1));
Console.WriteLine("Result A : " + resultA );
Console.WriteLine("Result B : " + resultB );
Console.WriteLine("Result C : " + resultC );
}
}
您可能已经观察到,我们能够添加新的策略来排序列表并根据需要使用它。哎呀,我们刚刚学习了策略模式。
- 祝你编码愉快。