C#入门 <字段与属性><构造方法与访问修饰符><虚方法、抽象类、接口、>

发布于 15 天前  40 次阅读


C# 核心知识点总结

适合初学者的C#基础知识指南


目录

  1. 属性与访问器 (get, set, init)
  2. 自动属性与后备字段
  3. 构造方法
  4. 访问修饰符
  5. 类的继承
  6. 虚方法与重写
  7. 抽象类与接口

1. 属性与访问器 (get, set, init)

属性是C#中封装字段(类内部数据)的一种方式,通过访问器(Accessor)控制读写权限。

基本语法

public class Person
{
    private string _name;  // 后备字段( backing field)

    // 属性
    public string Name
    {
        get { return _name; }           // 读取时执行
        set { _name = value; }         // 写入时执行,value是隐式参数
    }
}

三种访问器详解

访问器 作用 说明
get 读取属性值 必须返回对应类型的值
set 设置属性值 value 是隐式参数,代表赋的值
init 初始化属性 只能在对象创建时赋值,之后只读

init 示例

public class User
{
    public string Username { get; init; }  // 创建后不可修改

    public User()
    {
        Username = "张三";  // OK:创建时可以赋值
    }
}

// 使用
User user = new User();
user.Username = "李四";  // ❌ 编译错误!init属性只能在创建时赋值

2. 自动属性与后备字段

自动属性(Auto Property)

编译器自动生成后备字段,适合简单的get/set逻辑:

// 完整写法
public string Email { get; set; }

// 带初始值 (C# 6.0+)
public int Age { get; set; } = 18;

// init-only 自动属性
public string Password { get; init; }

后备字段(Backing Field)

当需要额外逻辑时,手动定义后备字段:

private string _phone;  // 后备字段,习惯以下划线开头

public string Phone
{
    get { return _phone; }
    set 
    { 
        // 可以添加验证逻辑
        if (value.Length < 11)
            throw new ArgumentException("手机号长度不对");
        _phone = value; 
    }
}

对比总结

特性 自动属性 后备字段
代码量 简洁 较多
灵活性 高(可添加逻辑)
使用场景 简单存储 需要验证/计算

3. 构造方法(Constructor)

构造方法用于初始化对象,在创建对象时自动调用。

基本语法

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }

    // 无参构造方法
    public Student()
    {
        Name = "未知";
        Age = 0;
    }

    // 带参构造方法
    public Student(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

构造方法链

使用 this() 调用其他构造方法:

public class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public string Category { get; set; }

    // 主构造方法(带所有参数)
    public Product(string name, decimal price, string category)
    {
        Name = name;
        Price = price;
        Category = category;
    }

    // 次构造方法:调用主构造方法,设置默认值
    public Product(string name, decimal price) : this(name, price, "未分类")
    {
        // 这里可以添加额外逻辑
    }

    // 默认构造方法
    public Product() : this("商品", 0, "未分类")
    {
    }
}

调用示例

Product p1 = new Product();                           // 调用无参
Product p2 = new Product("苹果", 5.5m);               // 调用两个参数
Product p3 = new Product("香蕉", 3.0m, "水果");       // 调用三个参数

4. 访问修饰符

访问修饰符控制类、属性、方法等的可见性。

修饰符 访问范围 使用场景
public 任何地方都可以访问 对外公开的成员
private 仅同类内部可访问(默认) 类内部使用的成员
protected 同类及子类可访问 供子类使用的成员
internal 同程序集可访问 程序集内部的成员
protected internal 同程序集或子类可访问 跨程序集继承场景
private protected 同程序集且同类或子类可访问 C# 7.2+

示例

public class Animal
{
    public string Name { get; set; }        // 任何地方都能访问
    private int _age;                         // 只有Animal类内部能访问
    protected string _species;               // Animal和子类能访问
    internal string Color { get; set; }      // 同程序集可访问

    public void PublicMethod() { }
    private void PrivateMethod() { }
    protected void ProtectedMethod() { }
}

5. 类的继承

继承允许创建一个类基于另一个类构建,实现代码复用。

基本语法

// 基类(父类)
public class Animal
{
    public string Name { get; set; }

    public void Eat()
    {
        Console.WriteLine("{Name} 正在吃东西");
    }
}

// 派生类(子类)
public class Dog : Animal
{
    public string Breed { get; set; }  // Dog独有的属性

    public void Bark()
    {
        Console.WriteLine("{Name} 在汪汪叫");
    }
}

使用示例

Dog dog = new Dog();
dog.Name = "旺财";
dog.Breed = "金毛";
dog.Eat();   // 继承自Animal的方法
dog.Bark();  // Dog自己的方法

Object 类型

在C#中,所有类都直接或间接继承自 System.Object

// 以下两种写法等价
public class MyClass { }
public class MyClass : System.Object { }

// Object类的常用方法
object obj = new Dog();
obj.ToString();      // 返回类型名称
obj.GetHashCode();   // 返回哈希码
obj.Equals(obj2);    // 判断相等
obj.GetType();       // 获取类型信息

sealed 关键字

sealed 修饰的类不能被继承:

public sealed class FinalClass
{
    public string Data { get; set; }
}

// 编译错误!无法继承sealed类
// public class TryInherit : FinalClass { }

也可用在方法上,防止被重写:

public class BaseClass
{
    public virtual void Show() { Console.WriteLine("Base"); }

    public sealed override void Show() { Console.WriteLine("Final"); }
}

6. 虚方法与重写

虚方法(virtual)

virtual 关键字声明的方法,可以在子类中被重写:

public class Shape
{
    public virtual void Draw()
    {
        Console.WriteLine("绘制图形");
    }
}

重写(override)

子类使用 override 重写父类方法:

public class Circle : Shape
{
    public double Radius { get; set; }

    public override void Draw()
    {
        Console.WriteLine("绘制圆形,半径: {Radius}");
    }
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public override void Draw()
    {
        Console.WriteLine("绘制矩形: {Width}x{Height}");
    }
}

多态示例

// 父类引用指向子类对象
Shape s1 = new Circle { Radius = 5 };
Shape s2 = new Rectangle { Width = 4, Height = 3 };

s1.Draw();  // 输出: 绘制圆形,半径: 5
s2.Draw();  // 输出: 绘制矩形: 4x3

// 放在数组中统一调用
Shape[] shapes = { s1, s2 };
foreach (var shape in shapes)
{
    shape.Draw();  // 多态:自动调用各自的重写方法
}

关键区别

关键字 作用 使用位置
virtual 声明方法可被重写 父类方法
override 重写父类方法 子类方法

7. 抽象类与接口

抽象类(abstract class)

不能直接实例化,必须被继承:

public abstract class Vehicle
{
    public string Brand { get; set; }

    // 抽象方法:没有实现,必须被子类重写
    public abstract void Move();

    // 普通方法:可以有实现
    public void Stop()
    {
        Console.WriteLine("车辆停止");
    }
}

public class Car : Vehicle
{
    public override void Move()
    {
        Console.WriteLine($"{Brand}汽车在公路上行驶");
    }
}

// 使用
Vehicle car = new Car();  // 可以用父类类型引用
car.Brand = "宝马";
car.Move();  // 调用的是Car的实现

接口(interface)

接口只定义契约(方法签名),不提供实现(C# 8.0前):

public interface IFlyable
{
    // 接口中的属性
    int MaxAltitude { get; }

    // 接口中的方法
    void Fly();
}

public interface ISwimmable
{
    void Swim();
}

// 类可以实现多个接口
public class Duck : IFlyable, ISwimmable
{
    public int MaxAltitude => 1000;  // 属性实现

    public void Fly()
    {
        Console.WriteLine("鸭子在空中飞");
    }

    public void Swim()
    {
        Console.WriteLine("鸭子在水中游");
    }
}

抽象类 vs 接口

特性 抽象类 接口
关键字 abstract class interface
多继承 不支持 支持(类可实现多接口)
字段 可以有实例字段 不能有实例字段
方法实现 可以有 C# 8.0前不能有默认实现
构造方法 可以有 不能有
访问修饰符 可以有各种修饰符 默认public

使用建议

// 当需要提供共享实现时 → 使用抽象类
// 当需要定义行为契约时 → 使用接口
// 当需要多继承时 → 必须使用接口

public interface IComparable
{
    int CompareTo(object obj);
}

public interface IDisposable
{
    void Dispose();
}

快速参考表

概念 关键字 用途
读取属性 get 获取属性值
写入属性 set 设置属性值
初始化属性 init 仅创建时可写
自动实现属性 public T Prop { get; set; } 编译器生成字段
构造方法 public ClassName() 初始化对象
继承 : ParentClass 子类继承父类
虚方法 virtual 允许子类重写
重写方法 override 重写父类方法
密封类 sealed class 禁止被继承
抽象类 abstract class 不能实例化
接口 interface 定义行为契约

📚 继续加油!这些是C#面向对象编程的核心概念,熟练掌握后可以继续学习多态、泛型、委托等高级主题。