c#里面的继承,封装,多态

继承

继承:父类继承到子类里面,父类也叫基类,子类也叫派生类。也就是说现在有两个类A和B,B继承于A,那么A里面的变量和函数都可以继承到B里面,这样可以避免代码的复用。

举个例子:现在我们要拿两个类来统计一下张三和李四的个人数据,我们需要统计姓名,身高,年龄,性别。

那么我们就有以下代码:

public class ZhangSan
{
    public string name;
    public int age;
    public string gender;
    public float height;
    public ZhangSan ()
    {
        name = "张三";
        age = 18;
        gender = "男";
        height = 170;
    }
}

public class LiSi
{
    public string name;
    public int age;
    public string gender;
    public float height;
    public LiSi ()
    {
        name = "李四";
        age = 20;
        gender = "男";
        height = 175;
    }
}

这样看起来是不是我们干了许多重复的工作,虽然看起来就是复制粘贴一下就好,但是这里只是存在一些变量,如果还存在很多函数呢,如果要统计的人数很多呢,那么复制粘贴就特别不友好,所以我们就需要思考,如何能够减少工作量,那么我们就需要用到继承,我们创建一个父类,然后再让子类继承。

代码如下:

public class ParentClass 
{
    public string  name;
    public int age;
    public string gender;
    public float height;//注意,访问修饰符要用public或者protected,才能被子类访问,比如 
                        //private就不能被子类访问,前面有具体写过5种访问修饰符。
    
}

public class ZhangSan:ParentClass 
{
    
    public ZhangSan ()
    {
        name = "张三";
        age = 18;
        gender = "男";
        height = 170;
    }
}

public class LiSi:ParentClass 
{
   
    public LiSi ()
    {
        name = "李四";
        age = 20;
        gender = "男";
        height = 175;
    }
}

这个代码是不是就看着好多了,我们也可以在父类里面添加一些函数,(不过要注意访问修饰符),这样也可以在子类继承下来,是不是方便了许多。不过c#里面一个类只能继承一个父类,没有多重继承,即一个类继承多个类,比如现在有A,B,C三个类。

我们可以写:A:B(代表A继承于B)

但是不能够写:A:B,C(代表A继承于B,C)


封装

什么是封装?其实就是不将具体的方法告诉用户,而是只是让用户直接调用得到结果。

比如说:一个洗衣机,你不需要了解它的运行方式,你只是需要放进去衣服,把水和洗衣粉放进去,按下按钮就可以了,而不是要具体的去了解里面的运作原理。

接下来写一个代码,关于计算一个面积,我们不需要知道里面的是如何运行的,我们只是需要输入参数,然后得到结果,就是这样,这就是封装。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Data
{
    public int length=0;
    public int width=0;
    public int height=0;
    public int area=0;
}

public class Rectangle:Data //长方形
{
    public int CalculateArea()
    {
        area = length * width;
        return area;
    }
}

public class Triangle : Data //三角形
{
    public int CalculateArea()
    {
        area = (length * height )/2;
        return area;
    }
}
public class Area : MonoBehaviour
{
    int rectangleArea;
    int triangleArea;
    public Rectangle rectangle;
    public Triangle triangle;
    void Start()
    {
        rectangle = new Rectangle();
        rectangle.length = 5;
        rectangle.width = 3;
        rectangleArea = rectangle.CalculateArea();
        Debug.Log("长方形的面积为:3*5=" + rectangleArea);

        triangle = new Triangle();
        triangle.length = 5;
        triangle.height = 2;
        triangleArea = triangle.CalculateArea();
        Debug.Log("三角形的面积等于:(2*5)/2=" + triangleArea);
    }

    
}

上面就是结合了一个继承和封装,(不过封装的用法很基础),但是原理是这样的,我们只是需要提交参数 ,然后原理我们不需要知道,其实就和一个黑盒是一样的,我们不需要知道黑盒里面是干什么的,我们只是需要知道传入参数,然后得到结果。对,其实和chatGPT,文心一言这类ai类似,我们只是提出问题,然后他们解答,至于他们怎么运行代码,查找数据我们并不关心。

多态

定义:同一个接口,使用不同的实例表现出不同的功能。

多态分为静态多态和动态多态。

静态多态:在还没有运行的时候已经绑定好了方法,也就是说我们在运行前就知道某个函数要执行的是什么功能。

动态多态:在运行的时候,根据实例的对象不同,执行的功能不同。也就是说运行前我们并不知道要执行什么功能。

定义看起来很抽象,我也是这样认为的,所以还是先结合代码来看看:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class Data1
{
    public int length=0;
    public int width=0;
    public int height=0;
    public int area=0;
}

public class Rectangle:Data1 //长方形
{
    public int CalculateArea()
    {
        area = length * width;
        return area;
    }
}

public class Triangle : Data1 //三角形
{
    public int CalculateArea()
    {
        area = (length * height )/2;
        return area;
    }
}
public class Area : MonoBehaviour
{
    int rectangleArea;
    int triangleArea;
    public Rectangle rectangle;
    public Triangle triangle;
    void Start()
    {
        rectangle = new Rectangle();
        rectangle.length = 5;
        rectangle.width = 3;
        rectangleArea = rectangle.CalculateArea();
        Debug.Log("长方形的面积为:3*5=" + rectangleArea);

        triangle = new Triangle();
        triangle.length = 5;
        triangle.height = 2;
        triangleArea = triangle.CalculateArea();
        Debug.Log("三角形的面积等于:(2*5)/2=" + triangleArea);
    }

    
}

在这里面,rectangleArea = rectangle.CalculateArea();

                  triangleArea = triangle.CalculateArea();

我们都清楚是调用了那个函数,并且可以通过进入函数去看怎么实现的。

这就叫做静态多态。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class Data
{
    public string name;
    public int age;
    public string gender;
    
    public virtual void Show()
    {
        Debug.Log("这是某某某的身份信息");
    }

}
public class ZhangSan: Data
{
    
    public ZhangSan ()
    {
        name = "张三";
        age = 18;
        gender = "男";
        
    }
    public override void Show()
    {
        Debug.Log("这是" + name + "的身份信息");
    }
}

public class LiSi: Data
{
   
    public LiSi ()
    {
        name = "李四";
        age = 20;
        gender = "男";
        
    }
    public override void Show()
    {
        Debug.Log("这是" + name + "的身份信息");
    }
}

public class InputData: MonoBehaviour
{
    public LiSi liSi;
    public ZhangSan zhangSan;
    private void Start()
    {
        liSi = new LiSi();
        zhangSan = new ZhangSan();
        Data data1 = liSi;
        Data data2 = zhangSan;
        data1.Show();
        data2.Show();
    }
}

这里面, Data data1 = liSi;
 Data data2 = zhangSan;
 data1.Show();
 data2.Show();

这最后的输出是哪个我们就不清楚,我们通过data1和data2进入show的函数,看到的也是,

public virtual void Show()
{
    Debug.Log("这是某某某的身份信息");
}

这个函数,所以在运行后我们才了解具体是绑定的什么函数。

这就是动态多态。

(关于动态多态里的virtual和override的函数,后面会有详细的介绍,现在可以大概了解就是,子类里面如果出现了override 相同函数名,那么就可以覆盖原函数,如果没有覆盖,那么结果就是原来父类的virtual函数的实现)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值