C#核心:继承

继承的基本概念

一个类A继承另一个类B:

1、A将会继承类B的所有成员

2、A类将拥有B类的所有特征和行为

被继承的类 称为:父类、基类、超类
继承的类称为:子类、派生类

注意:子类可以有自己的特征和行为

特点 说明
1. 单根性 C# 不支持多重继承,一个类只能直接继承一个父类。但可以通过接口实现多行为。
2. 传递性 如果 A 继承 BB 继承 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//报错
{

}
相关推荐
rit84324996 小时前
MATLAB中Teager能量算子提取与解调信号的实现
开发语言·matlab
开源技术6 小时前
Python GeoPandas基础知识:地图、投影和空间连接
开发语言·ide·python
Cult Of6 小时前
Alicea Wind的个人网站开发日志(2)
开发语言·python·vue
我找到地球的支点啦7 小时前
通信扩展——扩频技术(超级详细,附带Matlab代码)
开发语言·matlab
微小冷7 小时前
Rust异步编程详解
开发语言·rust·async·await·异步编程·tokio
A9better7 小时前
C++——不一样的I/O工具与名称空间
开发语言·c++·学习
清水白石0087 小时前
《为什么说 deque 是 Python 滑动窗口的“隐藏神器”?深入解析双端队列的高效之道》
开发语言·python
杜子不疼.7 小时前
Ascend_C自定义算子开发
c语言·开发语言
WooaiJava7 小时前
流式TTS音频播放项目 - 面试问答(后端)
java·开发语言
新缸中之脑7 小时前
开发AI代理必备的8个Python 库
开发语言·人工智能·python