继承的基本概念
一个类A继承另一个类B:
1、A将会继承类B的所有成员
2、A类将拥有B类的所有特征和行为
被继承的类 称为:父类、基类、超类
继承的类称为:子类、派生类
注意:子类可以有自己的特征和行为
| 特点 | 说明 |
|---|---|
| 1. 单根性 | C# 不支持多重继承,一个类只能直接继承一个父类。但可以通过接口实现多行为。 |
| 2. 传递性 | 如果 A 继承 B,B 继承 C,那么 A 也间接继承 C 的成员。 |
基本语法
cs
class 类名 : 被继承的类名
{
}
继承类的案例说明

cs
class Teacher
{
//名字
public string name;
//工号
public int number;
//介绍名字
public void SpeakName()
{
Console.WriteLine(name);
}
}
//继承Teacher类
class TeachingTeacher : Teacher
{
//科目
public string subject;
//介绍科目
public void SpeakSubject()
{
Console.WriteLine(subject+"老师");
}
}
class ChineseTeacher : TeachingTeacher
{
public void Skill()
{
Console.WriteLine("一行白鹭上青天");
}
}
这里你可以看出ChineseTeacher都是继承了TeachingTeacher的属性和行为------然后直接通过new 一个类名创建对应实例
cs
class Program
{
static void Main(string[] args)
{
// 创建基类实例
TeachingTeacher tt = new TeachingTeacher();
tt.name = "唐老狮";
tt.number = 1;
tt.SpeakName();
tt.subject = "Unity";
tt.SpeakSubject();
// 创建派生类实例
ChineseTeacher ct = new ChineseTeacher();
ct.name = "唐老师";
ct.number = 2;
ct.subject = "语文";
ct.SpeakName();
ct.SpeakSubject();
ct.Skill();
}
}
继承类的访问权限修饰
关键字:protected
不希望外部访问,子类可以访问
cs
class Teacher
{
............//这里使用protected访问权限
protected int number;
}
//继承Teacher类
class TeachingTeacher : Teacher
{
number=10;//可以用
}
class Program
{
static void Main(string[] args)
{
// 创建基类实例
TeachingTeacher tt = new TeachingTeacher();
tt.number = 1;//这里会报错,无法访问
}
}
如果父类中的成员是private,那么子类和外部都无法访问该成员
里氏替换原则
基本概念
任何父类出现的地方,子类都可以代替:即父类容器转载子类对象(因为子类对象包含了父类对象全部内容)
**作用:**方便进行对象存储和管理
案例使用说明
cs
class GameObject
{
}
class Player : GameObject
{
public void PlayerAtk()
{
Console.WriteLine("玩家攻击");
}
}
class Moster : GameObject
{
public void MosterAtk()
{
Console.WriteLine("怪物攻击");
}
}
class Boss : GameObject
{
public void BossAtk()
{
Console.WriteLine("Boss攻击");
}
}
cs
class Program
{
static void Main(string[] args)
{
Console.WriteLine("里氏替换原则");
// 里氏替换原则:用父类容器装载子类对象
GameObject player = new Player();
GameObject monster = new Monster();
GameObject boss = new Boss();
GameObject[] objects = new GameObject[] { new Player(), new Monster(), new Boss() };
}
}
但需要注意,此处子类对象都是GameObject类型,无法使用子类对象中特有的方法和行为。所以可能还需要强制转换相关参数。
is和as
当用GameObject类型 统一存储继承类 Player类,可以先用is判断该对象是否为Player类,再强制转换GameObject类为Player类
cs
GameObject player = new Player();
//is判断一个对象是否是指定的对象
//返回值bool
if (player is Player)
{
//as:将一个对象转换为指定类对象
//返回值:指定类型对象
//成功返回指定类对象 失败返回null
Player p = player as Player;
}
//可以正常使用Player类的功能了
p.PlayerAtk();
使用数组管理基类
cs
//实际使用时和数组配合使用多 方便进行对象存储和管理
GameObject[] objects = new GameObject[] { new Player(), new Moster(), new Boss() };
//遍历objects数组 来判断类和执行类
for (int i = 0; i < objects.Length; i++)
{
if (objects[i] is Player)
{
(player as Player).PlayerAtk();
}
else if (objects[i] is Moster)
{
(player as Moster).MosterAtk();
}
else if (objects[i] is Boss)
{
(player as Boss).BossAtk();
}
}
继承中的构造函数
基本概念
当声明一个子类对象时,先执行父类的构造函数再执行子类构造函数。
子类实例化时 默认调用无参 父类没有无参构造就会报错
cs
GameObject
{
public GameObject()
{
Console.WriteLine("GameObject的构造函数");
}
}
class Player : GameObject
{
public Player()
{
Console.WriteLine("Player的构造函数");
}
}
class MainPlayer : Player
{
public MainPlayer()
{
Console.WriteLine("Player的构造函数");
}
}
这里构造子类函数MainPlayer
cs
class Program
{
static void Main(string[] args)
{
Console.WriteLine("继承中的构造函数");
MainPlayer mp = new MainPlayer();
}
}
打印结果:

父类的无参构造函数很重要
cs
class Father
{
public Father (int a)
{
}
}
class Son : Father//报错
{
}
就算Son也是有参构造函数,父类也会报错------因为无参构造函数很重要!!
base调用指定父类构造
cs
class Father
{
//父类没有无参构造
public Father(int i)
{
Console.WriteLine("Father构造");
}
}
class Son : Father
{
public Son(int i) : base(i)//成功运行
{
Console.WriteLine("Son的一个参数的构造");
}
public Son(int i, string str) //报错!!
{
Console.WriteLine("Son的两个参数的构造");
}
}
解决方法是:1、给父类添加上无参构造函数 2、给子类添加上重载构造函数
以下是方法2
cs
class Father
{
public Father(int i)
{
Console.WriteLine("Father构造");
}
}
class Son : Father
{
public Son(int i) : base(i)//3、调用父类
{
Console.WriteLine("Son的一个参数的构造");
}
public Son(int i, string str) : this(i)//2、这里会调用Son(int i) : base(i),也是先进再执行
{
Console.WriteLine("Son的两个参数的构造");
}
}
class Program
{
static void Main(string[] args)
{
Son s2 = new Son(20, "Hello"); // 1、调用 Son(int, string)
}
}
cs
打印结果:
Father构造
Son的一个参数的构造
Son的两个参数的构造
万物之父
关键词:object
是一个基类 可以装任何东西
强制转换方式
引用类型和里氏替换原则一样用is和as
值类型使用括号强转
String类型有专门的函数
cs
// 引用类型
object o = new Son();
// 用 is as 来判断和转换即可
if (o is Son)
{
(o as Son).Speak();
}
// 值类型
object o2 = 1f;
// 用强转
float f1 = (float)o2;
// 特殊的 string 类型
object str = "123123";
string str2 = str.ToString();
装箱拆箱
值类型和object之间发生的
装箱:把值类型用引用类型存储 栈内存移到堆内存中
拆箱:把引用类型存储的值类型取出来 堆内存移到栈内存中
cs
int a =10;
//装箱
object o = a;
//拆箱
int b = (int)o;
密封类
关键字:sealed
作用是让类无法被继承 结扎
保证程序的规范性,安全性
cs
sealed class Father
{
}
class son:Fathter//报错
{
}