OOP的四大基本特征是封装,继承,多态和抽象.这些概念共同构成了OOP的核心原则
不过,有时候人们会提到三大特性(即封装,继承,多态),这通常是将抽象和封装合并讨论,因为两者都涉及到隐藏实现细节
一.类与对象
类
类是一个模板或者说是一个蓝图,用于创建对象.它定义了对象的属性和行为 类可以包含字段,属性,方法,事件,构造函数等,使用Class关键字来声明一个类,类可以包含访问修饰符(如public,private等)来控制其可见性。
对象
在C#中,对象是类的实例化实体,通过new关键字在堆内存中动态分配空间并创建:执行new ClassName()时,系统自动调用匹配的构造函数(默认或参数化)完成初始化,生成包含独立属性和方法的对象,可通过引用访问其成员,生命周期由垃圾回收器自动管理。
代码
using System;
// 1. 类 = 模板
public class Phone
{
// 字段(内部状态)
private string _brand;
// 属性(对外接口)
public string Brand
{
get => _brand;
set => _brand = value;
}
// 方法(行为)
public void Call(string number)
{
Console.WriteLine($"[{Brand}] 正在拨号:{number}");
}
// 构造函数(诞生仪式)
public Phone(string brand)
{
Brand = brand;
Console.WriteLine($"新手机[{brand}] 已出厂");
}
}
// 2. 对象 = 实例化后的实体
class Program
{
static void Main()
{
// new 三步:开堆空间 → 调用构造函数 → 返回引用
Phone myPhone = new Phone("Xiaomi");
myPhone.Call("10086");
}
}
二.继承
1.定义
继承是面向对象编程中用于实现代码重用和逻辑扩展的机制。一个类(子类)可以继承另一个类(父类)的属性和方法,子类可以重用父类的代码,并且可以添加新的功能或重写父类的方法。
2.实现方式
- 使用冒号 : 来表达继承关系
- C#只支持单继承,一个类只能有一个直接父类,但可以实现多个接口
代码示例
// 父类:Animal
public class Animal
{
public string Name { get; set; }
public void Eat()
{
Console.WriteLine($"{Name} 正在吃东西。");
}
}
// 子类:Dog,继承自Animal
public class Dog : Animal
{
public void Bark()
{
Console.WriteLine($"{Name} 正在汪汪叫。");
}
}
//Dog类继承自Animal类,获得了Name属性和Eat方法。
//Dog类新增了Bark方法。
//子类可以直接使用父类的成员,实现了代码重用。
三.多态
1.定义
多态是指同一操作在不同对象上具有不同的表现形式.通过多态,可以使用统一的接口来调用不同对象的特定实现
2.实现方式
- 方法重写(Override):子类重写父类的虚方法
- 接口的实现:不同类实现相同的接口方法
- 方法重载:同一类中方法名相同,但参数列表不同(严格来说,这是编译时多态)
代码示例
1.继承重写方法实现
// 父类:Animal
public class Animal
{
public string Name { get; set; }
// 虚方法,可以被子类重写
public virtual void Speak()
{
Console.WriteLine($"{Name} 正在发出声音。");
}
}
// 子类:Dog
public class Dog : Animal
{
// 重写父类的Speak方法
public override void Speak()
{
Console.WriteLine($"{Name} 正在汪汪叫。");
}
}
// 子类:Cat
public class Cat : Animal
{
// 重写父类的Speak方法
public override void Speak()
{
Console.WriteLine($"{Name} 正在喵喵叫。");
}
}
2.实现接口
// 定义接口
public interface IShape
{
double GetArea();
}
// 实现接口的类:Circle
public class Circle : IShape
{
public double Radius { get; set; }
public double GetArea()
{
return Math.PI * Radius * Radius;
}
}
// 实现接口的类:Rectangle
public class Rectangle : IShape
{
public double Width { get; set; }
public double Height { get; set; }
public double GetArea()
{
return Width * Height;
}
}
说明:
方法重写:在父类中定义虚方法(virtual),在子类中使用override关键字重写
接口实现:不同类实现相同接口的方法,可以通过接口引用来调用具体实现
多态调用:通过父类或接口的引用,调用子类或具体实现的方法
List<Animal> animals = new List<Animal>
{
new Dog { Name = "小黑" },
new Cat { Name = "小白" },
new Animal { Name = "未知动物" }
};
foreach (var animal in animals)
{
animal.Speak();
}
/* 输出:
小黑 正在汪汪叫。
小白 正在喵喵叫。
未知动物 正在发出声音。
*/
// 接口多态
List<IShape> shapes = new List<IShape>
{
new Circle { Radius = 5 },
new Rectangle { Width = 4, Height = 6 }
};
foreach (var shape in shapes)
{
Console.WriteLine($"面积:{shape.GetArea()}");
}
/* 输出:
面积:78.5398163397448
面积:24
*/
四.抽象
1.定义
抽象是对现实世界复杂对象的建模,提取出关键特性,忽略不必要的细节.抽象可以通过抽象类和接口来实现,提供一个模板,让子类实现特定的功能
2.实现方式
- 抽象类(Abstract Class):使用abstract关键字修饰,不能实例化,可以包含抽象方法和非抽象方法
- 接口(Interface):定义一组未实现的方法或属性,需要由实现类提供具体实现
3.代码示例
抽象类
// 抽象类:Shape
public abstract class Shape
{
// 抽象方法,没有方法体,子类必须实现
public abstract double GetArea();
// 普通方法,子类可直接使用或重写
public virtual void Display()
{
Console.WriteLine("这是一个形状。");
}
}
// 子类:Circle
public class Circle : Shape
{
public double Radius { get; set; }
// 实现抽象方法
public override double GetArea()
{
return Math.PI * Radius * Radius;
}
// 重写父类方法
public override void Display()
{
Console.WriteLine($"这是一个半径为{Radius}的圆形。");
}
}
// 子类:Rectangle
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
// 实现抽象方法
public override double GetArea()
{
return Width * Height;
}
// 重写父类方法
public override void Display()
{
Console.WriteLine($"这是一个宽为{Width},高为{Height}的矩形。");
}
}
接口
// 接口:IMovable
public interface IMovable
{
void Move(double distance);
}
// 实现接口的类:Car
public class Car : IMovable
{
public void Move(double distance)
{
Console.WriteLine($"汽车行驶了{distance}公里。");
}
}
// 实现接口的类:Person
public class Person : IMovable
{
public void Move(double distance)
{
Console.WriteLine($"人行走了{distance}公里。");
}
}
说明:
抽象类:不能被实例化,提供了一个模板或基类,强制子类实现抽象方法
接口:定义了行为的契约,实现类必须实现接口中的所有成员
抽象类与接口的区别:
抽象类可以包含已实现的方法和字段,接口只能包含未实现的方法(C# 8.0开始,接口可以有默认实现)
一个类只能继承一个抽象类,但可以实现多个接口
List<Shape> shapes = new List<Shape>
{
new Circle { Radius = 5 },
new Rectangle { Width = 4, Height = 6 }
};
foreach (var shape in shapes)
{
shape.Display();
Console.WriteLine($"面积:{shape.GetArea()}");
}
/* 输出:
这是一个半径为5的圆形。
面积:78.5398163397448
这是一个宽为4,高为6的矩形。
面积:24
*/
// 接口的使用
List<IMovable> movables = new List<IMovable>
{
new Car(),
new Person()
};
foreach (var movable in movables)
{
movable.Move(10);
}
/* 输出:
汽车行驶了10公里。
人行走了10公里。
*/
总结
- 封装:通过访问修饰符和属性,保护对象的内部状态,提供受控的访问接口
- 继承;子类继承父类的属性和方法,实现代码重用和逻辑扩展
- 多态:通过方法重写和接口实现,实现相同接口的不同表现形式,增强代码的灵活性和可扩展性
- 抽象:通过抽象类和接口,定义对象的抽象模型,强制子类实现特定的行为









暂无评论内容