当前位置: 首页 > news >正文

【C#学习Day13笔记】静态成员、接口、运算符重载和索引器

前言

在C#第13天的学习中,我系统掌握了静态成员接口设计运算符重载索引器四大核心概念。本文100%保留我的原始代码和注释,这些注释是我学习过程中的重要思考记录,对复习和理解代码逻辑至关重要。所有代码示例均来自我的课堂实践,包含完整的注释说明,帮助大家深入理解面向对象编程的高级特性!


一、静态成员:类级别的共享资源

class Test
{// 不能在静态类中声明实例字段、方法//静态类里所有成员都必须是静态的,是不能被实例化的,不能被对象调用// 静态字段(类级别共享)public static string name;// 实例字段(对象级别)public int age;// 静态属性public static string Name{get{// 访问静态字段return name;}set{// 设置静态字段name = value;}}// 静态方法public static void Show(){// 静态方法内部只能访问静态字段Console.WriteLine(name);// Console.WriteLine(age); // 错误!不能访问实例字段}// 实例方法public void Show1(){// 实例方法可以访问静态成员和实例成员Console.WriteLine(name);Console.WriteLine(age);}
}class Class1 //: Test
{public void Show(){// 通过类名访问静态字段Test.name = "王五";}
}static void Main(string[] args)
{// 静态类不能被实例化,也不能被继承// Test test = new Test(); // 错误!// 静态字段只能通过类名访问设置Test.name = "张三";// 静态属性只能通过类名访问设置Test.Name = "李四";Console.WriteLine(Test.name); // 输出:李四Test.Show(); // 输出:李四// 不是静态的成员不能使用类名调用,必须使用实例化对象调用// Test.show1(); // 错误!// 实例方法需要通过对象调用Class1 c1 = new Class1();c1.Show();Console.WriteLine(Test.Name); // 输出:王五
}

静态成员关键点

  1. 访问限制​:

    • 静态成员通过类名访问(Test.name
    • 实例成员通过对象访问(testInstance.age
  2. 内存特性​:

    • 静态成员在程序启动时创建
    • 生命周期与程序相同
    • 所有实例共享同一静态成员
  3. 使用场景​:

    • 工具类方法(如Math类)
    • 全局配置项
    • 计数器等共享状态

二、接口:多态性的契约

internal interface IFly
{//使用接口创建一个变量 写了两个构造 这在编程中叫做多态 //因为fly发生了变化 之前是飞机 后面变成了小鸟 //他的形态是可以变化的 这种语法在C#中叫做多态// 方法声明(没有实现)void Fly();// 攻击方法void Attack();
}internal class Brid : IFly
{public void Fly(){// 实现接口方法Console.WriteLine("小鸟在空中飞");}public void Attack(){// 实现接口方法Console.WriteLine("小鸟在空中捕猎");}
}internal class Plane : IFly
{public void Fly(){// 实现接口方法Console.WriteLine("飞机在空中飞");}public void Attack(){// 实现接口方法Console.WriteLine("飞机在空中战斗");}
}static void Main(string[] args)
{//定义一个接口 在语法上跟定义一个抽象类是没有区别的 //但是不允许提供接口中任意成员的实现方式 //一般接口只会包含 方法 索引器 和事件的声明 不允许声明成员的修饰符  //哪怕是public都不行 因为接口总是共有的 也不能声明虚拟和静态//接口不会有构造函数 也不能有数据字段// 创建具体对象Plane plane = new Plane();plane.Fly(); // 输出:飞机在空中飞// 接口不能被实例化// 使用接口引用IFly fly;// 多态应用:同一接口不同实现fly = new Plane();fly.Fly(); // 输出:飞机在空中飞fly = new Brid();fly.Fly(); // 输出:小鸟在空中飞
}

接口核心要点

  1. 契约特性​:

    • 只有方法声明,没有实现
    • 不能包含字段和构造函数
    • 所有成员默认public
  2. 多态实现​:

    • 同一接口引用不同对象
    • 不同对象有不同行为
    • 提高代码灵活性
  3. 设计优势​:

    • 解耦定义与实现
    • 支持多重实现
    • 便于单元测试

三、接口继承:扩展契约能力

internal abstract class Student
{//在继承中 除了第一个要继承的类或者是接口使用: 后面再继承的接口要使用逗号隔开//类是不允许多继承的 每个类只能有一个基类 // 学生基类属性public int Id { get; set; }public string Name { get; set; }public string Addres { get; set; }public string Phone { get; set; }public int Age { get; set; }protected Student() { }
}internal class No : Student { }internal interface Interface1
{void YY();
}internal interface Interface2
{void cy();
}internal class Yes : Student, Interface1, Interface2
{public Yes(string name){// 构造函数初始化Name = name;}public void YY(){// 实现Interface1方法Console.WriteLine($"{Name}是会游泳的学生");}public void cy(){// 实现Interface2方法Console.WriteLine($"{Name}会打篮球");}
}static void Main(string[] args)
{// 接口多态应用Interface1 i;i = new Yes("张三");i.YY(); // 输出:张三是会游泳的学生Interface1 i1;i1 = new Yes("李四");i1.YY(); // 输出:李四是会游泳的学生
}

接口继承要点

  1. 继承规则​:

    • 类可继承一个基类
    • 类可实现多个接口
    • 接口可继承多个接口
  2. 多态优势​:

    • 统一处理不同对象
    • 扩展类功能而不修改类
    • 提高代码复用性
  3. 设计模式应用​:

    • 策略模式
    • 适配器模式
    • 插件系统架构

四、运算符重载:自定义对象运算

internal class Class1
{public int Age { get; set; }public string Name { get; set; }public int Id { get; set; }public Class1(int age, string name, int id){// 构造函数初始化Age = age;Name = name;Id = id;}// 重载==运算符public static bool operator ==(Class1 a, Class1 b){// 自定义相等比较逻辑if (a.Age == b.Age && a.Name == b.Name && a.Id == b.Id){return true;}return false;}// 重载!=运算符(必须成对实现)public static bool operator !=(Class1 a, Class1 b){// 基于==运算符实现return !(a == b);}// 重载+运算符public static int operator +(Class1 a, Class1 b){// 自定义加法逻辑int num = a.Age - b.Age;return num;}
}static void Main(string[] args)
{//函数重载就是把某个函数表现为新的状态  运算符重载就是把运算符重写 实现新的功能//使用运算符重载 比较对象中的数据 默认比较的是地址 //而运算符重载是通过定义的方法逻辑进行比较的// 创建相同数据的对象Class1 c1 = new Class1(18, "张三", 12345);Class1 c2 = new Class1(18, "张三", 12345);// 默认比较地址Console.WriteLine(c1 == c2); // false// 使用重载运算符比较内容Console.WriteLine(c1 == c2); // true// 使用重载运算符Console.WriteLine(c1 + c2); // 0
}

运算符重载要点

  1. 重载规则​:

    • 必须使用static修饰
    • 必须使用operator关键字
    • 参数至少有一个是当前类型
  2. 必须成对重载​:

    • ==!=
    • ><
    • >=<=
  3. 应用场景​:

    • 自定义相等比较
    • 数学运算扩展
    • 领域特定语言(DSL)

五、索引器:类中的数组式访问

internal class Class1
{// 内部数组public int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };public string name;public string age;// 定义数值索引器public int this[int index]{get{// 获取数组元素return arr[index];}set{// 设置数组元素arr[index] = value;}}// 定义字符串索引器public string this[string property]{get{// 根据属性名返回值if (property == "name"){return this.name;}else if (property == "age"){return this.age;}return "";}set{// 根据属性名设置值if (property == "name"){this.name = value;}else if (property == "age"){this.age = value;}}}
}static void Main(string[] args)
{Class1 c2 = new Class1();// 设置属性c2.name = "张三";c2.age = "18";// 通过索引器访问属性Console.WriteLine(c2["age"]); // 输出:18// 通过索引器修改数组c2[5] = 1000;Console.WriteLine(c2[5]); // 输出:1000
}

索引器核心要点

  1. 访问方式​:

    • 类似数组访问语法
    • 可定义多种参数类型
    • 支持get和set访问器
  2. 实现技巧​:

    • 可基于不同参数类型重载
    • 可包含复杂逻辑
    • 可返回任意类型
  3. 应用场景​:

    • 封装集合类
    • 配置数据访问
    • 动态属性访问

学习总结

四大特性对比表

特性核心概念应用场景代码示例
静态成员类级别共享工具类、全局配置Test.name
接口多态契约插件系统、策略模式IFly fly = new Plane()
运算符重载自定义运算领域特定语言c1 == c2
索引器类数组访问集合封装c2["age"]

关键编程原则

  1. 静态成员​:

    • 谨慎使用全局状态
    • 注意线程安全问题
    • 适合无状态工具方法
  2. 接口设计​:

    • 遵循单一职责原则
    • 使用明确的行为命名
    • 优先组合而非继承
  3. 运算符重载​:

    • 保持运算符合直觉
    • 成对实现相关运算符
    • 避免过度使用
  4. 索引器应用​:

    • 提供统一访问接口
    • 添加边界检查
    • 避免复杂业务逻辑

复习建议

  1. 代码实践​:

    • 实现自定义集合类(索引器)
    • 设计多态支付系统(接口)
    • 创建分数运算类(运算符重载)
  2. 调试技巧​:

    • 使用断点观察静态字段变化
    • 通过接口引用调试多态行为
    • 单步执行验证运算符逻辑

编程箴言
"注释是写给未来的自己的信,好的注释让代码重生"

http://www.xdnf.cn/news/1210897.html

相关文章:

  • 小杰数据结构(one day)——心若安,便是晴天;心若乱,便是阴天。
  • python基础:request请求Cookie保持登录状态
  • p5.js 从零开始创建 3D 模型,createModel入门指南
  • MongoDB系列教程-教程概述
  • SQL 怎么学?
  • STM32--DHT11(标准库)驱动开发
  • spring cloud sentinel 动态规则配置
  • 【华为机试】20. 有效的括号
  • docker docker、swarm 全流程执行
  • C++多态:面向对象编程的灵魂之
  • 网络安全第15集
  • 力扣30 天 Pandas 挑战(3)---数据操作
  • C# _列表(List<T>)_ 字典(Dictionary<TKey, TValue>)
  • uniapp 实现全局变量
  • Rust 实战三 | HTTP 服务开发及 Web 框架推荐
  • React 中获取当前路由信息
  • 2.oracle保姆级安装教程
  • 《零基础入门AI:传统机器学习入门(从理论到Scikit-Learn实践)》
  • 如何解决人工智能在社会治理中面临的技术和伦理挑战?
  • 网络原理--HTTPHTTPS
  • AI产品经理手册(Ch3-5)AI Product Manager‘s Handbook学习笔记
  • PyCharm插件开发与定制指南:打造个性化开发环境
  • FSMC的配置和应用
  • SpringBoot集成deepseek
  • Export useForm doesn‘t exist in target module
  • vue3组件通信的几种方法,详解
  • 05动手学深度学习(下)
  • Linux - 权限的理解(深入浅出,详细细微)
  • 书籍推荐算法研究
  • gRPC性能陷阱:低延迟网络下的客户端瓶颈揭秘