在C#中,类和对象构成了面向对象编程(OOP)的基础。通过使用类和对象,开发者可以创建灵活且可维护的程序结构。本篇文章将深入探讨类与对象的基本概念及其高级应用,包括继承、多态和接口
类的基本概念
类是面向对象编程的基本单元,它是创建对象的模板或蓝图。在C#中,类定义了对象的数据(字段和属性)和行为(方法)。
类的定义
// 基本的类定义
public class Person
{
// 字段 - 存储数据
private string name;
private int age;
// 属性 - 提供对字段的访问
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
// 方法 - 定义行为
public void Greet()
{
Console.WriteLine($"Hello, my name is {name} and I am {age} years old.");
}
}
对象实例化
对象是类的实例。我们使用new关键字来创建类的实例。
// 创建Person类的实例
Person person1 = new Person();
person1.Name = "John";
person1.Age = 30;
person1.Greet(); // 输出: Hello, my name is John and I am 30 years old.
// 另一种初始化方式
Person person2 = new Person { Name = "Alice", Age = 25 };
person2.Greet(); // 输出: Hello, my name is Alice and I am 25 years old.
构造函数
构造函数是一种特殊的方法,用于初始化新创建的对象。构造函数的名称必须与类名相同,且没有返回类型。
public class Person
{
private string name;
private int age;
// 默认构造函数
public Person()
{
name = "Unknown";
age = 0;
}
// 带参数的构造函数
public Person(string name, int age)
{
this.name = name;
this.age = age;
}
// 属性和方法...
}
// 使用构造函数创建对象
Person person1 = new Person(); // 使用默认构造函数
Person person2 = new Person("Bob", 40); // 使用带参数的构造函数
访问修饰符
访问修饰符决定了类成员的可访问性:
- public: 可以被任何代码访问
- private: 只能被同一个类中的代码访问
- protected: 可以被同一个类或派生类中的代码访问
- internal: 可以被同一个程序集中的任何代码访问
- protected internal: 可以被同一个程序集或派生类中的代码访问
public class Example
{
public int PublicField; // 任何地方都可访问
private int PrivateField; // 只在类内部可访问
protected int ProtectedField; // 在类内部和派生类中可访问
internal int InternalField; // 在同一程序集中可访问
}
静态成员
静态成员属于类本身,而不是类的实例。使用static关键字声明静态成员.
public class MathUtility
{
// 静态字段
public static double PI = 3.14159;
// 静态方法
public static double CalculateCircleArea(double radius)
{
return PI * radius * radius;
}
}
// 访问静态成员(不需要创建类的实例)
double area = MathUtility.CalculateCircleArea(5);
Console.WriteLine($"Area: {area}");
进阶应用
继承
继承允许一个类从另一个类获取属性和行为,促进代码复用。
public class Animal
{
public void Eat()
{
Console.WriteLine("Eating");
}
}
public class Dog : Animal
{
public void Bark()
{
Console.WriteLine("Barking");
}
}
//Dog类继承自Animal类,因此它具有Eat方法。
方法重写
使用virtual和override关键字来实现方法重写。
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Animal sound");
}
}
public class Dog : Animal
{
public override void Speak()
{
Console.WriteLine("Woof");
}
}
Animal myDog = new Dog();
myDog.Speak(); // 输出:Woof
方法重载
同一个类中,定义多个具有相同名字但参数不同的方法。编译时决定调用哪个方法。
public class Printer
{
public void Print(string message)
{
Console.WriteLine(message);
}
public void Print(int number)
{
Console.WriteLine(number);
}
}
接口实现
public interface IAnimal
{
void Speak();
}
public class Bird : IAnimal
{
public void Speak()
{
Console.WriteLine("Tweet");
}
}
public class Fish : IAnimal
{
public void Speak()
{
Console.WriteLine("Blub");
}
}
public class Zoo
{
public static void Main(string[] args)
{
List<IAnimal> animals = new List<IAnimal>
{
new Bird(),
new Fish()
};
foreach (var animal in animals)
{
animal.Speak();
}
// 输出:
// Tweet
// Blub
}
}
抽象类
抽象类提供了一种强制子类实现特定方法的机制,同时也可以包含具体方法。关键字 abstract
public abstract class Shape
{
public abstract double Area();
public void Display()
{
Console.WriteLine("Displaying shape");
}
}
public class Circle : Shape
{
private double radius;
public Circle(double r)
{
radius = r;
}
public override double Area()
{
return Math.PI * radius * radius;
}
}
实践习题
1.继承与方法重写:创建Vehicle基类,并派生出Car和Bicycle子类,实现启动方法并重写一个虚拟函数以打印不同的信息。
2.多态应用:使用多态创建一个动物园管理系统,定义Animal基类和Speak方法,然后实现几个动物的子类,各自覆盖其Speak方法。
3.接口与抽象类:定义一个IShape接口描述基本图形操作,创建Rectangle类实现该接口并计算面积。然后扩展一个抽象类ColoredShape,增加颜色属性。
通过学习这些关于C#类和对象的概念和应用,您将能更好地设计和实现复杂的软件架构。如果有任何疑问或者需要进一步讨论,请随时联系我!