C#面向对象编程


面向对象编程(Object-Oriented Programming, OOP)是现代软件开发的核心范式,C#作为一门纯面向对象的语言,全面支持OOP的各种特性。本文将详细介绍C#中面向对象编程的核心概念和应用。

一、面向对象基础概念

1. 类和对象

是对象的蓝图或模板,定义了对象的属性和行为。对象是类的具体实例。

// 定义一个Person类
public class Person
{
    // 字段(属性)
    public string Name;
    public int Age;

    // 方法(行为)
    public void Introduce()
    {
        Console.WriteLine($"大家好,我是{Name},今年{Age}岁。");
    }
}

// 创建Person对象
Person person1 = new Person();
person1.Name = "张三";
person1.Age = 25;
person1.Introduce();

2. 四大基本特性

面向对象编程有四大基本特性:

  • 封装:隐藏内部实现细节,暴露必要接口
  • 继承:子类继承父类的特征和行为
  • 多态:同一操作作用于不同对象产生不同行为
  • 抽象:提取共性形成抽象类或接口

二、封装与访问修饰符

封装通过访问修饰符控制类成员的可见性:

  • public:完全公开
  • private:仅类内部可访问
  • protected:类内部和子类可访问
  • internal:同一程序集内可访问
  • protected internal:同一程序集或子类可访问
public class BankAccount
{
    private decimal _balance;  // 私有字段

    public decimal Balance    // 公有属性
    {
        get { return _balance; }
    }

    public void Deposit(decimal amount)
    {
        if (amount > 0)
            _balance += amount;
    }

    public bool Withdraw(decimal amount)
    {
        if (amount > 0 && _balance >= amount)
        {
            _balance -= amount;
            return true;
        }
        return false;
    }
}

三、继承与多态

1. 继承

子类继承父类的成员,并可扩展新功能:

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

    public virtual void Speak()
    {
        Console.WriteLine("动物发出声音");
    }
}

public class Dog : Animal  // 派生类
{
    public override void Speak()
    {
        Console.WriteLine("汪汪汪");
    }

    public void Fetch()
    {
        Console.WriteLine($"{Name}在捡球");
    }
}

// 使用
Animal myDog = new Dog();
myDog.Name = "阿黄";
myDog.Speak();  // 输出"汪汪汪"

2. 多态

通过虚方法(virtual)和重写(override)实现运行时多态:

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

public class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("绘制圆形");
    }
}

public class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("绘制矩形");
    }
}

// 多态示例
List<Shape> shapes = new List<Shape>
{
    new Shape(),
    new Circle(),
    new Rectangle()
};

foreach (var shape in shapes)
{
    shape.Draw();  // 根据实际类型调用相应方法
}

四、抽象类与接口

1. 抽象类

包含抽象成员的类,不能实例化:

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

    public abstract void Start();  // 抽象方法

    public void Stop()
    {
        Console.WriteLine("车辆已停止");
    }
}

public class Car : Vehicle
{
    public override void Start()
    {
        Console.WriteLine($"{Model}汽车启动");
    }
}

2. 接口

定义契约,不包含实现:

public interface ILogger
{
    void Log(string message);
    string GetLogs();
}

public class FileLogger : ILogger
{
    public void Log(string message)
    {
        File.AppendAllText("log.txt", $"{DateTime.Now}: {message}\n");
    }

    public string GetLogs()
    {
        return File.ReadAllText("log.txt");
    }
}

3. 抽象类 vs 接口

特性抽象类接口
实现可包含实现不包含实现
成员可包含字段只能包含方法、属性等
继承单继承多实现
构造函数可以有不能有
访问修饰符可以有默认为public

五、其他重要概念

1. 静态成员

属于类而非实例:

public class MathUtility
{
    public static double PI = 3.14159;

    public static int Add(int a, int b)
    {
        return a + b;
    }
}

// 使用
double pi = MathUtility.PI;
int sum = MathUtility.Add(5, 3);

2. 属性与索引器

属性的高级用法:

public class Temperature
{
    private double _celsius;

    public double Celsius
    {
        get => _celsius;
        set => _celsius = value >= -273.15 ? value : -273.15;
    }

    public double Fahrenheit
    {
        get => _celsius * 9 / 5 + 32;
        set => _celsius = (value - 32) * 5 / 9;
    }
}

// 索引器示例
public class StringArray
{
    private string[] _array = new string[10];

    public string this[int index]
    {
        get => _array[index];
        set => _array[index] = value;
    }
}

3. 构造函数与析构函数

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

    // 构造函数
    public Student(string name, int age)
    {
        Name = name;
        Age = age;
    }

    // 析构函数
    ~Student()
    {
        Console.WriteLine($"Student {Name}被销毁");
    }
}

六、面向对象设计原则

  1. 单一职责原则(SRP):一个类只负责一个功能领域
  2. 开放封闭原则(OCP):对扩展开放,对修改封闭
  3. 里氏替换原则(LSP):子类必须能够替换父类
  4. 接口隔离原则(ISP):客户端不应依赖它不需要的接口
  5. 依赖倒置原则(DIP):依赖抽象而非具体实现

七、综合示例

// 定义接口
public interface IShape
{
    double CalculateArea();
    void Draw();
}

// 抽象类实现部分功能
public abstract class Shape : IShape
{
    public string Name { get; set; }

    public abstract double CalculateArea();

    public virtual void Draw()
    {
        Console.WriteLine($"正在绘制{Name}");
    }
}

// 具体类
public class Circle : Shape
{
    public double Radius { get; set; }

    public override double CalculateArea()
    {
        return Math.PI * Radius * Radius;
    }

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

// 使用
List<IShape> shapes = new List<IShape>
{
    new Circle { Name = "大圆", Radius = 5 },
    new Circle { Name = "小圆", Radius = 2 }
};

foreach (var shape in shapes)
{
    Console.WriteLine($"{shape.Name} 面积: {shape.CalculateArea():F2}");
    shape.Draw();
}

面向对象编程是C#的核心,掌握这些概念和技术将帮助你构建更健壮、可维护的应用程序。通过合理运用封装、继承、多态和抽象,可以创建出结构清晰、扩展性强的代码架构。


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注