144 lines
3.1 KiB
Markdown
144 lines
3.1 KiB
Markdown
|
|
# 继承
|
|||
|
|
概念:
|
|||
|
|
继承是面向对象三大特性之一
|
|||
|
|
可以让一个类在已有类的基础上继续扩展
|
|||
|
|
被继承的类一般叫==父类 / 基类(base class)==
|
|||
|
|
继承别人的类一般叫==子类 / 派生类(derived class)==
|
|||
|
|
|
|||
|
|
通常用法:
|
|||
|
|
1. 提取多个类的共同内容,减少重复代码
|
|||
|
|
2. 表达“==is-a==”关系
|
|||
|
|
3. 让子类在父类基础上增加自己的成员和功能
|
|||
|
|
|
|||
|
|
语法:
|
|||
|
|
```Csharp
|
|||
|
|
class 子类名 : 父类名
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
案例:
|
|||
|
|
```Csharp
|
|||
|
|
class Animal
|
|||
|
|
{
|
|||
|
|
public string name;
|
|||
|
|
protected int age;
|
|||
|
|
|
|||
|
|
public Animal(string name)
|
|||
|
|
{
|
|||
|
|
this.name = name;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Speak()
|
|||
|
|
{
|
|||
|
|
cw("动物发出声音");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class Dog : Animal
|
|||
|
|
{
|
|||
|
|
public Dog(string name, int age) : base(name)
|
|||
|
|
{
|
|||
|
|
this.age = age;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Bark()
|
|||
|
|
{
|
|||
|
|
cw(name);
|
|||
|
|
cw(age);
|
|||
|
|
cw("汪汪");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Dog d = new Dog("旺财", 3);
|
|||
|
|
d.Speak();
|
|||
|
|
d.Bark();
|
|||
|
|
```
|
|||
|
|
↑ `Dog : Animal` 就表示 `Dog` 继承了 `Animal`
|
|||
|
|
|
|||
|
|
注意:
|
|||
|
|
1. ==C# 的类只能直接继承一个父类==,也就是单继承
|
|||
|
|
2. 继承是可以传递的,A 继承 B,B 继承 C,那么 A 也会继承到 C 的可用成员
|
|||
|
|
3. ==构造函数不会被继承==,子类只是可以调用父类构造函数
|
|||
|
|
4. 父类的 `private` 成员子类==不能直接访问==,想给子类用一般写 `protected`
|
|||
|
|
5. 结构体 `struct` ==不支持继承类==,但可以实现接口
|
|||
|
|
6. 子类对象本质上也是父类对象的一种,所以继承是后面学[[多态vob|多态]]的基础
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
# base关键字
|
|||
|
|
概念:
|
|||
|
|
`base` 用来在==子类内部==访问父类成员
|
|||
|
|
最常见的用途就是调用父类构造函数
|
|||
|
|
|
|||
|
|
通常用法:
|
|||
|
|
1. 在子类构造函数中调用父类构造函数
|
|||
|
|
2. 在子类方法中访问父类同名成员或父类方法
|
|||
|
|
|
|||
|
|
语法:
|
|||
|
|
```Csharp
|
|||
|
|
class Dog : Animal
|
|||
|
|
{
|
|||
|
|
public Dog(string name) : base(name)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
调用父类成员:
|
|||
|
|
```Csharp
|
|||
|
|
base.父类成员名
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
案例:
|
|||
|
|
```Csharp
|
|||
|
|
class Father
|
|||
|
|
{
|
|||
|
|
public string name;
|
|||
|
|
|
|||
|
|
public Father(string name)
|
|||
|
|
{
|
|||
|
|
this.name = name;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Say()
|
|||
|
|
{
|
|||
|
|
cw("我是父类");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class Son : Father
|
|||
|
|
{
|
|||
|
|
public Son(string name) : base(name)
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public void Test()
|
|||
|
|
{
|
|||
|
|
base.Say();
|
|||
|
|
cw(base.name);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Son s = new Son("小李");
|
|||
|
|
s.Test();
|
|||
|
|
```
|
|||
|
|
↑ `base(name)` 是先调用父类构造函数,`base.Say()` 是调用父类方法
|
|||
|
|
|
|||
|
|
注意:
|
|||
|
|
1. `base` 只能在==实例构造函数、实例方法、实例属性访问器==里用
|
|||
|
|
2. ==静态方法里不能用 `base`==
|
|||
|
|
3. 如果父类没有无参构造函数,子类通常就要显式写 `: base(...)`
|
|||
|
|
4. `base` 是访问父类,不是创建一个新的父类对象
|
|||
|
|
|
|||
|
|
----
|
|||
|
|
引用:
|
|||
|
|
1. Microsoft Learn: [Inheritance - derive types to create more specialized behavior](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/object-oriented/inheritance)
|
|||
|
|
2. Microsoft Learn: [Inheritance in C# and .NET](https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/tutorials/inheritance)
|
|||
|
|
3. Microsoft Learn: [base (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/base)
|
|||
|
|
4. Microsoft Learn: [protected (C# Reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/protected)
|
|||
|
|
|
|||
|
|
#继承
|
|||
|
|
#核心
|