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

C#基础09-面向对象关键字

零、文章目录

C#基础09-面向对象关键字

1、new 关键字

(1)作为运算符(创建对象)
  • 作用:在托管堆上分配内存并调用构造函数,返回对象引用。
  • 语法:
ClassName obj = new ClassName();  // 引用类型 
int num = new int();             // 值类型(等价于 int num = 0)
  • 场景:
    • 实例化类、结构体或数组(如 List<int> list = new List<int>();)。
    • 为值类型调用默认构造函数(初始化默认值,如 int 初始化为 0)。
(2)作为修饰符(隐藏继承成员)
  • 作用:显式隐藏基类中的同名成员(字段、方法、属性等),消除编译器警告。
  • 语法:
public class BaseClass {public void Method() => Console.WriteLine("Base");
}public class DerivedClass : BaseClass {new public void Method() => Console.WriteLine("Derived"); // 隐藏基类方法 
}
  • 关键点:
    • 隐藏后,通过派生类实例访问的是新成员;通过基类引用访问原成员。
    • override 区别:new 创建新成员(无多态),override 扩展基类成员(支持多态)。
DerivedClass d = new DerivedClass();
d.Method();       // 输出 "Derived"
((BaseClass)d).Method(); // 输出 "Base"
(3)作为泛型约束(限制类型参数)
  • 作用:要求泛型类型参数必须有公共无参构造函数。
  • 语法:
public class Factory<T> where T : new() {public T Create() => new T(); // 可安全实例化 T 
}
  • 场景:泛型工厂模式(如 Factory<Employee>.Create())。
(4)注意事项
  • 命名冲突解决:优先使用 new 修饰符而非忽略警告,明确设计意图。
  • 内存管理:new 运算符为引用类型分配堆内存,需注意垃圾回收机制。
  • 值类型优化:new int()int num = 0 等效,编译器自动优化。

2、this 关键字

(1)四大核心作用
  • 区分成员变量与局部变量:当方法参数与类字段同名时,使用 this 明确指定成员变量:
public class Person {private string name;public void SetName(string name) {this.name = name; // this.name 指代成员变量,name 为参数}
}
  • 链式调用构造函数:在构造函数中使用 this 调用同类其他构造函数,减少代码重复:
public class Student {public string Name;public int Age;public Student(string name) : this(name, 18) { } // 调用下方构造函数public Student(string name, int age) {Name = name;Age = age;}
}
  • 传递当前对象引用:将当前实例作为参数传递给其他方法或类:
public class Logger {public void Log(object obj) { /* 记录对象状态 */ }
}
public class User {public void Save() {new Logger().Log(this); // 传递当前 User 实例 }
}
  • 支持扩展方法:为现有类型添加新方法时,this 修饰首参数以绑定目标类型,无需修改源码即可增强类型功能
public static class StringExtensions {public static bool IsNumeric(this string str) { // this 绑定 string 类型return double.TryParse(str, out _);}
}
// 调用:"123".IsNumeric();
(2)关键限制与注意事项
场景是否允许使用 this说明
静态方法(static❌ 禁止静态方法无实例上下文,使用将导致编译错误
静态属性访问器❌ 禁止同静态方法限制
结构体(struct⚠️ 受限this
在结构体中是只读变量(不可修改引用)
构造函数链式调用✅ 推荐仅限构造函数首行使用(如 : this(...)
(3)最佳实践与性能建议
  • 避免冗余使用:成员访问若无命名冲突,可省略 this(如 name = "Alice" 替代 this.name = "Alice"),提升代码简洁性。
  • 慎用于高频调用场景:this 本身无性能开销,但过度链式构造函数可能增加初始化复杂度。
  • 索引器实现 :通过 this[...] 语法定义类索引器,使对象支持类似数组的访问方式,增强数据封装灵活性。
public class Collection {private int[] data = new int[10];public int this[int index] {get => data[index];set => data[index] = value;}
}
// 调用:Collection col = new(); col[0] = 100;
(4)错误用法示例
public class Example {private int id;public static void Print() {Console.WriteLine(this.id); // 错误:静态方法中禁止使用 this }
}
  • ❌ 编译错误:CS0120: 非静态字段、方法或属性“Example.id”要求对象引用

3、base关键字

(1)核心用途
  • 调用基类构造函数
    • 当基类没有无参构造函数时,必须在派生类构造函数中通过base(参数)显式调用基类构造函数
    • 若未显式调用,编译器会尝试调用基类无参构造;若无参构造不存在,则编译报错
public class Animal {public Animal(string name) => Console.WriteLine($"Animal: {name}");
}
public class Dog : Animal {public Dog(string name) : base(name) {  // 显式调用基类构造函数Console.WriteLine("Dog created");}
}
  • 调用基类被重写的方法
    • 子类重写基类虚方法(override)后,可通过base.方法名()保留基类逻辑
    • 适用于扩展而非完全替换基类方法的场景
public class Base {public virtual void Show() => Console.Write("Hello");
}
public class Derived : Base {public override void Show() {base.Show();  // 调用基类方法Console.Write(" World");  // 扩展新逻辑}
}
// 输出:"Hello World"
  • 访问基类被隐藏的成员
    • 当子类使用new关键字隐藏基类同名成员时,可通过base访问基类原始成员
public class Parent { public int Value = 100; }
public class Child : Parent {new public int Value = 200;  // 隐藏基类成员public void PrintBase() => Console.WriteLine(base.Value);  // 输出100
}
(2)关键限制与注意事项
  • 适用场景限制:
    • 仅在实例构造函数、实例方法或属性访问器中有效,静态方法中不可使用。
    • 只能访问直接基类的成员,无法跨级访问更高层基类。
  • 构造函数调用规则:
    • 若基类存在无参构造函数,子类可省略: base()(编译器自动调用);
    • 若基类只有有参构造,子类必须显式调用base并传参。
  • this的区别:this指向当前类实例,base指向直接基类实例。两者可结合使用(如this.Name vs base.Name)。
(3)典型场景速查表
场景代码示例作用
初始化基类字段public Child(int x) : base(x) { }确保基类数据正确初始化
扩展基类方法逻辑base.Method(); /*新增逻辑*/复用基类方法并增强功能
解决父子类成员名冲突int val = base.Field;访问被隐藏的基类成员
  • 注意:滥用base可能破坏封装性。优先通过重写设计扩展逻辑,而非频繁绕过继承层级。

4、static关键字

(1)核心作用
  • 全局共享性
    • 修饰的成员(变量/方法)不属于对象实例,而是属于类本身
    • 所有实例共享同一份内存空间,修改一处即全局生效
class Counter {public static int Count = 0;  // 所有实例共享 public Counter() { Count++; }
}
// 测试 
var c1 = new Counter(); 
var c2 = new Counter();
Console.WriteLine(Counter.Count); // 输出 2
  • 直接访问性:无需实例化类,通过 类名.成员 直接访问

Math.Pow(2, 3); // 经典静态方法调用

(2)五大使用场景
  • 静态成员变量
    • 特点:
      • 类加载时初始化,生命周期 = 应用程序域生存期
      • 默认值:数值型为 0,引用类型为 null
    • 典型用途:
      • 全局配置项(如日志开关)
      • 跨实例共享数据(如计数器)
  • 静态方法
    • 规则:
      • 只能访问静态成员,不可调用实例方法/属性
      • 不能使用 thisbase 关键字
    • 典型用途:
      • 工具类方法(如 File.ReadAllText()
      • 工厂模式创建对象
public static Logger CreateLogger() { return new FileLogger(); 
}
  • 静态类
    • 强制约束:
      • 类本身必须标记 static,且仅包含静态成员
      • 不可被实例化或继承(本质是 sealed abstract 类)
    • 典型用途:
      • 工具类(如 System.Math
      • 扩展方法容器(需配合 this 参数)
  • 静态构造函数
    • 特性:
      • 在类首次被访问时自动执行,且仅执行一次
      • 无参数和访问修饰符
    • 典型用途:初始化静态成员或加载资源
class ConfigLoader {public static string ApiKey;static ConfigLoader() {ApiKey = File.ReadAllText("key.txt"); // 初始化}
}
  • 静态局部变量 (C# 8.0+)
    • 作用域:方法内定义,但生命周期延长至应用程序结束
    • 典型用途:跨方法调用保持状态(替代全局变量)
void TrackCall() {static int callCount = 0; callCount++;Console.WriteLine($"Called: {callCount} times");
}
(3)关键注意事项
  • 线程安全问题:静态成员默认非线程安全,高并发时需加锁
private static readonly object _lock = new object();
public static void UpdateResource() {lock(_lock) { // 修改共享资源 }
}
  • 内存泄漏风险:静态引用对象不会被 GC 回收,需手动解除引用
static List<byte[]> _cache = new List<byte[]>();
// 长期持有大对象 → 可能泄漏
  • 初始化顺序:静态成员初始化顺序不可控,避免循环依赖
  • 测试困难:静态成员难以 Mock,过度使用降低代码可测试性
(4)最佳实践建议
  • 适用场景
    • ✅ 无状态工具方法(如数学计算)
    • ✅ 全局配置项(如应用设置)
    • ✅ 共享只读资源(如本地化字典)
  • 规避场景
    • ❌ 频繁修改的共享状态(优先用依赖注入)
    • ❌ 替代单例模式(需控制初始化时机的场景)
  • 性能优化
    • 只读静态数据标记 readonlyconst
    • 延迟初始化用 Lazy<T> 减少启动开销
private static readonly Lazy<Logger> _logger = new Lazy<Logger>(() => new Logger());
public static Logger Instance => _logger.Value;
(5)内存模型

5、sealed关键字

(1)核心功能与使用场景
  • 密封类(Sealed Class)
    • 作用:禁止其他类继承(相当于 Java 的 final)。
    • 典型场景:
      • 工具类(如 System.String),防止继承破坏设计逻辑。
      • 安全性要求高的类(如加密模块),避免恶意重写核心方法。
    • 语法:
sealed class MyClass { /* 类成员 */ }  
  • 密封方法(Sealed Method)
    • 作用:阻止子类重写父类的虚方法。
    • 强制要求:必须与override联用,不能修饰非虚方法。
    • 语法:
class Base {  public virtual void Method() { }  
}  
class Derived : Base {  public sealed override void Method() { } // 禁止孙类重写  
}
(2)关键技术特性
  • 性能优化
    • 密封类无派生类,JIT 编译器可将虚方法调用转为非虚调用,提升执行效率。
    • 示例:高频调用的密封类方法(如数学计算库)可减少运行时开销。
  • 设计约束
    • ❌ 禁止与 abstract 联用:抽象类要求被继承,而密封类禁止继承。
    • ❌ 不可修饰静态方法或属性:静态成员默认不可重写,无需密封。
  • 替代方案
    • 若需子类重写父类方法但限制孙类重写,可在中间层方法添加 sealed
(3)最佳实践与注意事项
  • 使用原则:
    • 慎用密封类:过度使用会降低代码扩展性,仅用于明确无需继承的场景。
    • 文档化理由:在代码注释中说明密封原因(如安全或性能需求)。
  • 常见误区:
    • 误用作“优化手段”:除非性能测试证明瓶颈在虚方法调用,否则优先考虑代码可维护性。
    • 混淆 newsealed
      • sealed:禁止重写(要求方法原本是虚方法)。
      • new:隐藏父类同名方法(非重写)。
(4)综合示例
// 密封类示例  
sealed class EncryptionService {  public void Encrypt(string data) { /* 核心加密逻辑 */ }  
}  // 密封方法示例  
class Vehicle {  public virtual void StartEngine() { }  
}  
class Car : Vehicle {  public sealed override void StartEngine() { // 固定启动流程 }  
}  
class SportsCar : Car {  // 编译错误:无法重写密封方法 StartEngine()  
}
  • 设计提示:在框架开发中,密封核心类(如 System.IO.File)可确保行为一致性。
http://www.dtcms.com/a/431645.html

相关文章:

  • 增长超人网站建设价格教育培训网站建设
  • 互联网项目各阶段数据驱动与AI技术的深度运用策略
  • 网站开发语言php5.1做网站客户总是要退款
  • 天津网站推广方法html购物网页设计报告
  • 奉贤青岛网站建设网站迭代
  • 高唐企业建网站服务商短租网站那家做的好处
  • GD32 I2C外设详介绍
  • 【C++】C++的多态是个啥,咋用的?
  • 【Linux 系统】进程状态
  • 搜索引擎网站排行榜广州seo优化公司排名
  • 【强化学习】#8 DQN(深度Q学习)
  • 【原创】SpringBoot3+Vue3学生信息管理系统
  • Linux查看日志方法
  • 个人签名设计网站服装网站策划设计
  • 《Span-based Localizing Network for Natural Language Video Localization》
  • VRRP上行逃生:两种核心方案详解
  • 方法的调用:递归
  • 设计师常用的灵感网站做网站怎么盈利
  • 工程承包网站哪个好?临汾工程建设招标投标网站
  • 从新疆油田数据采集器,看Digi ZigBee模块在石油行业上的应用
  • C语言指针与字符串详解
  • 全长抗体表达:从载体策略到产业化,如何实现高活性抗体的高效生产?
  • 0.3 神经网络学习率、激活函数、损失函数
  • 最全的ppt模板网站舆情监测系统永久免费
  • MySQL通过二进制日志恢复数据
  • 建立网站专业公司吗wordpress 换主题问题
  • 高功耗显卡装机实战:电源 / 机箱 / 主板兼容问题全解析与解决方案
  • Java 性能监控与分析工具
  • 写作网站六大神书wordpress改小程序
  • 网站没建设可以访问吗最流行的网站开发