接口为什么可以解耦

本文是转载,且未获得原作者授权。
假设有一个磁盘接口,主要用来存储文件。
硬盘和U盘都实现了这个接口

// 定义一个接口 磁盘
interface Disk(){
  // 保存文件
  void save(File file);  
}

// U盘实现
class UDisk implement Disk{
 void save(File file);  
}
// 硬盘实现
class HardDisk implement Disk{
 void save(File file);  
}

我们在使用保存文件这个方法时,只需要调用相应的接口,就可以实现。
为了方便,我们写一个下载类。

    /**
    * 下载类
    * /
    class Download{
      Disk disk; //这里用接口声明,因为我们不知道,也不用知道,我们未来会存到什么样的磁盘,我们不依赖于任何类型的磁盘,我们只依赖于这个接口
	  
	  // 调用保存文件方法
      void download(File file){
           disk.save(file);
      }
    	
      //具体接口的实现
      void setDisk(Disk disk){
           this.disk=disk;
      }
    }

当我们要保存时,调用下载类就好

 public static void main(String[] args){
 	  // 实例化下载类
      Download download = new Download();
      
      // 设置存储目标是U盘
      download.setDisk(new UDisk());
      // 文件被存到了U盘
      download.download(file);
    
      // 设置存储目标为硬盘
      download.setDisk(new HardDisk());
      // 文件被存到了硬盘
      download.download(file);
	  
	  /*
	  *  某天我们想把下载的文件保存到CD里边,我们只需要增加CDDisk类,实现Disk接口就可以不对download本身做任何修改,
	  * 就可以方便的将文件下载到CD或其他介质里。我们的Download类不依赖于任何具体的类,这样就解除了与任何具体存储设备的耦合!
	  */
	
	/// 文章有删改,文末有原文地址
  }

笔者自己的理解:
接口可以看作是一种标准,我们在使用接口时,并不知道接口要被那个类实现。我们只是用接口定下一个标准,所有实现这个和接口的类都必须遵守这个标准。那上文来说,download类在声明时用的是接口,这样无论哪个类去调用这个下载类,只要改变接口声明的实例(setDisk方法),就可以实现不同的功能。

原作者:xiukongtiao;
原文地址:https://bbs.youkuaiyun.com/topics/370098383?list=16125326;

### 通信接口设计中的解耦方法 在 C# 中,使用接口和基类实现解耦设计是一种常见的做法,尤其在构建可扩展、可维护的系统时尤为重要。接口定义了行为的契约,而基类提供了部分实现,二者结合可以实现灵活的系统架构。 #### 接口用于定义行为契约 接口不包含实现细节,仅定义类必须实现的方法和属性。这种设计使得多个类可以共享相同的行为规范,而不受具体实现细节的约束。例如: ```csharp public interface ICommunication { void Connect(); void Disconnect(); string Read(); void Write(string data); } ``` 该接口定义了通信设备必须支持的四个基本操作:连接、断开、读取和写入。任何实现该接口的类都必须提供这些方法的具体实现[^2]。 #### 基类用于提供共享实现 基类可以封装通用的实现逻辑,避免重复代码。例如,可以定义一个 `CommunicationBase` 类来实现部分通用功能: ```csharp public abstract class CommunicationBase : ICommunication { public virtual void Connect() { Console.WriteLine("Connecting..."); } public virtual void Disconnect() { Console.WriteLine("Disconnecting..."); } public abstract string Read(); public abstract void Write(string data); } ``` 在此基础上,具体的通信类(如串口通信、TCP 通信等)可以继承该基类并实现抽象方法: ```csharp public class SerialCommunication : CommunicationBase { public override string Read() { return "Serial Data"; } public override void Write(string data) { Console.WriteLine("Serial Write: " + data); } } ``` ```csharp public class TcpCommunication : CommunicationBase { public override string Read() { return "TCP Data"; } public override void Write(string data) { Console.WriteLine("TCP Write: " + data); } } ``` 这种设计允许不同的通信方式共享相同的接口和部分实现逻辑,从而实现解耦[^3]。 #### 接口与基类的组合使用 C# 支持一个类继承一个基类并实现多个接口,这种机制可以进一步增强系统的灵活性。例如: ```csharp public interface ILoggable { void Log(string message); } public class AdvancedCommunication : CommunicationBase, ILoggable { public void Log(string message) { Console.WriteLine("Log: " + message); } public override string Read() { string data = "Advanced Data"; Log("Read data: " + data); return data; } } ``` 该类继承了 `CommunicationBase` 并实现了 `ILoggable` 接口,从而具备了通信和日志记录两种功能。这种组合方式使得系统具备更强的可扩展性和可维护性[^2]。 #### 接口继承接口 接口也可以继承其他接口,形成层次化的契约结构。例如: ```csharp public interface IDevice : ICommunication, ILoggable { string GetDeviceId(); } ``` 该接口继承了 `ICommunication` 和 `ILoggable`,并新增了一个 `GetDeviceId` 方法。任何实现 `IDevice` 接口的类都必须实现这三个接口定义的所有方法和属性[^2]。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值