WPF学习(3)--不同类通过接口实现同种方法

一、接口概述

1.接口的概念

在C#中,接口(interface)是一种引用类型,它定义了一组方法、属性、事件或索引器,但不提供实现。接口只定义成员的签名,而具体的实现由实现接口的类或结构体提供。接口使用关键字 interface 定义。

接口实例

cs 复制代码
public interface IShape
{
    double GetArea();
    double GetPerimeter();
    string GetInfo();
}

类实现接口实例

cs 复制代码
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

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

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

XML 复制代码
<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>

三、实验结果

相关推荐
何事误红尘4 小时前
全志A40i学习笔记():开发资料、启用串口
学习
for_ever_love__4 小时前
python基础语法学习: 异常的传递性
开发语言·python·学习
PC2005-cloud5 小时前
DeepSeek Harness 创建 skill 指南:结构、安装、使用
笔记·学习
YM52e5 小时前
分页查询的基石:ArkTS 为鸿蒙商品列表设计 LIMIT/OFFSET 的表
android·学习·华为·harmonyos
math_hongfan5 小时前
主从嵌套层次分明:ArkUI 订单卡片内嵌明细的鸿蒙界面
学习·华为·harmonyos
还不秃顶的计科生7 小时前
具身智能论文学习8:Octo: An Open-Source Generalist Robot Policy
人工智能·深度学习·学习·机器学习·语言模型·vla·vlm
woshihuanglaoshi7 小时前
事务加持防超卖:ArkTS 在鸿蒙里玩转 TRANSACTION 出入库
学习·华为·harmonyos
世人万千丶8 小时前
去重插入与超限淘汰:ArkTS 实现鸿蒙搜索历史的 LIMIT 艺术
运维·服务器·学习·华为·harmonyos·鸿蒙
2601_949950639 小时前
在线练题更方便,用练题簿打造属于自己的移动题库
学习·考研·刷题·小程序推荐
woshihuanglaoshi10 小时前
十二商品二十流水:鸿蒙进销存种子数据装满预警看板
学习·华为·harmonyos