一、接口概述
1.接口的概念
在C#中,接口(interface)是一种引用类型,它定义了一组方法、属性、事件或索引器,但不提供实现。接口只定义成员的签名,而具体的实现由实现接口的类或结构体提供。接口使用关键字 interface
定义。
接口实例
public interface IShape
{
double GetArea();
double GetPerimeter();
string GetInfo();
}
类实现接口实例
public class Circle : IShape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public double GetArea()
{
return Math.PI * Radius * Radius;
}
public double GetPerimeter()
{
return 2 * Math.PI * Radius;
}
public string GetInfo()
{
return $"Circle - Radius: {Radius}, Area: {GetArea():F2}, Perimeter: {GetPerimeter():F2}";
}
}
2.使用接口的好处
-
解耦和可替换性:
- 接口定义了行为的契约,而不关心具体的实现。这样,代码依赖于接口而不是具体实现,使得具体实现可以很容易地替换或修改而不影响使用接口的代码。
-
提高代码的可测试性:
- 接口使得代码更容易进行单元测试。我们可以为接口创建模拟(Mock)对象,测试代码可以使用这些模拟对象来独立验证逻辑,而不需要依赖具体实现。
二、实例代码分析
1.Shapes.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfApp
{
public interface IShape
{
double GetArea();
double GetPerimeter();
string GetInfo();
}
public class Circle : IShape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
public double GetArea()
{
return Math.PI * Radius * Radius;
}
public double GetPerimeter()
{
return 2 * Math.PI * Radius;
}
public string GetInfo()
{
return $"Circle - Radius: {Radius}, Area: {GetArea():F2}, Perimeter: {GetPerimeter():F2}";
}
}
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height)
{
Width = width;
Height = height;
}
public double GetArea()
{
return Width * Height;
}
public double GetPerimeter()
{
return 2 * (Width + Height);
}
public string GetInfo()
{
return $"Rectangle - Width: {Width}, Height: {Height}, Area: {GetArea():F2}, Perimeter: {GetPerimeter():F2}";
}
}
}
2.MainWindow.xmal.cs
using System;
using System.Collections.Generic; // 用于 List<T>
using System.ComponentModel; // 用于 INotifyPropertyChanged 接口
using System.Windows; // 用于 WPF 相关类
namespace WpfApp
{
public partial class MainWindow : Window
{
// 存储形状的列表
List<IShape> Shapes;
// 存储形状信息的对象,用于数据绑定
private ShapeInfo MyShapeInfo;
// 构造函数,初始化组件和数据
public MainWindow()
{
InitializeComponent();
Shapes = new List<IShape>();
MyShapeInfo = new ShapeInfo();
MyShapeInfo.Info = ""; // 初始化 Info 属性
DataContext = new { ShapeInfo = MyShapeInfo }; // 设置数据上下文
}
// 添加圆形按钮的点击事件处理程序
private void Button_Click_AddCircle(object sender, RoutedEventArgs e)
{
double radius = DateTime.Now.Second; // 使用当前秒数作为圆的半径
Circle circle = new Circle(radius); // 创建新的 Circle 对象
Shapes.Add(circle); // 将 Circle 对象添加到列表中
}
// 添加矩形按钮的点击事件处理程序
private void Button_Click_AddRectangle(object sender, RoutedEventArgs e)
{
double height = DateTime.Now.Second; // 使用当前秒数作为矩形的高度
double width = height / 2; // 使用当前秒数的一半作为矩形的宽度
Rectangle rectangle = new Rectangle(width, height); // 创建新的 Rectangle 对象
Shapes.Add(rectangle); // 将 Rectangle 对象添加到列表中
}
// 显示形状信息按钮的点击事件处理程序
private void Button_Click_ShowInfo(object sender, RoutedEventArgs e)
{
string info = "";
// 遍历所有形状,获取其信息
foreach (IShape shape in Shapes)
{
if (shape != null)
{
info += shape.GetInfo(); // 获取形状信息
info += Environment.NewLine; // 添加换行符
}
}
MyShapeInfo.Info = info; // 更新 ShapeInfo 对象的 Info 属性
ShapesInfo.Text = MyShapeInfo.Info; // 更新 UI 中显示的信息
}
}
// 用于存储和通知形状信息变化的类
public class ShapeInfo : INotifyPropertyChanged
{
// 私有字段,存储信息字符串
private string _info;
// 公有属性,获取或设置信息字符串
public string Info
{
get { return _info; }
set
{
_info = value;
OnPropertyChanged("Info"); // 通知属性值变化
}
}
// 属性变化事件
public event PropertyChangedEventHandler PropertyChanged;
// 触发属性变化事件的方法
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
3.MainWindow.xmal
<Window x:Class="WpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Shape Info" Height="350" Width="525">
<Grid>
<StackPanel>
<Button Content="Add Circle" Click="Button_Click_AddCircle" Margin="10"/>
<Button Content="Add Rectangle" Click="Button_Click_AddRectangle" Margin="10"/>
<Button Content="Show Shapes Info" Click="Button_Click_ShowInfo" Margin="10"/>
<TextBlock Name="ShapesInfo" Margin="10" FontSize="16" TextWrapping="Wrap" Text="{Binding ShapeInfo.Info}" />
</StackPanel>
</Grid>
</Window>