C# 关于继承和多态
继承
继承一个类时,类成员的可访问性是一个重要的问题。子类(派生类)不能访问基类的私有成员,但是可以访问其公共成员。这就是说,只要使用public声明类成员,就可以让一个类成员被基类和子类(派生类)同时访问,同时也可以被外部的代码访问。
为了解决基类成员访问问题,C# 还提供了另外一种可访问性:protected
,只有子类(派生类)才能访问protected
成员,基类和外部代码都不能访问protected
成员。
除了成员的保护级别外,还可以为成员定义其继承行为。基类的成员可以是虚拟的,成员可以由继承它的类重写。子类(派生类)可以提供成员的其他执行代码,这种执行代码不会删除原来的代码,仍可以在类中访问原来的代码,但外部代码不能访问它们。如果没有提供其他执行方式,外部代码就直接访问基类中成员的执行代码。
另外,基类还可以定义为抽象类。抽象类不能直接实例化,要使用抽象类就必须继承这个类,然后再实例化。
说明:
继承类时,需要使用冒号加类名。当对一个类应用sealed
修饰符时,该修饰符会阻止其他类从该类继承。
多态
当然如果它们都继承自某个类,可以把这些子类(派生类)都放到一个数组中。如果这些对象都有同名方法,就可以调用每个对象的同名方法。
C# 中,类的多态性是通过在子类(派生类)中重载基类的虚方法或函数成员来实现的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 多态小练习
{
public class MyClass1
{
private int x = 1;
private int y = 2;
public int X {
set {
x = value;
}
get {
return x;
}
}
public int Y {
set {
y = value;
}
get {
return y;
}
}
public virtual int Add()
{
return X + Y;
}
}
public class MyClass2 : MyClass1
{
public override int Add()
{
X = 10;
Y = 20;
return X + Y;
}
}
class Program
{
static void Main(string[] args)
{
MyClass2 mc2 = new MyClass2();
Console.WriteLine(mc2.Add());
MyClass1 mc1 = mc2; // 基类可以直接用派生类赋值
mc1.X = 1;
mc1.Y = 2;
// 这里指向的是派生类的 Add() 函数,内部被X=10;Y=20赋值了一遍,结果还是 30。
Console.WriteLine(mc1.Add());
MyClass1 mc1_1 = new MyClass1();
Console.WriteLine(mc1_1.Add());
}
}
}
输出:
30
30
3
请按任意键继续. . .
说明:
当子类(派生类)从基类继承时,它会获得基类的所有方法、字段、属性和事件。若要更改基类的数据和行为,有两种选择:可以使用新的派生成员替换基成员,或者可以重写虚拟的基成员。上面的实例重写了基类中的虚方法,另外,开发人员还可以使用新的派生成员替换基类的成员,这时需要使用new
关键字。如果基类定义了一个方法、字段或属性,则new
关键字用于在子类(派生类)中创建该方法、字段或属性的新定义。new
关键字放置在要替换的类成员的返回类型之前,例如,上面实例中重写基类中虚方法的代码也可以替换为下面的形式。
public class MyClass2: MyClass1
{
public new int Add() // 这里改成 new
{
X = 10;
Y = 20;
return X + Y;
}
}
new
基类中不需要 virtual
来表示,override
只能重写 virtual
标识的虚方法。
输出:
30
3 // 这是 MyClass1 付的初始值相加得到
请按任意键继续. . .
注意:
① virtual
修饰符不能与private、static、abstract
或者override
修饰符同时使用。
② override
修饰符不能与new、static
或者virtual
修饰符同时使用,并且重写方法只能用于重写基类中的虚方法。
③ C# 中,继承、虚方法和重写方法组合在一起才能实现多态性。
参考:入门到精通 -> P144
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了