Unity游戏开发学习之封装,继承,多态

面试点:

封装,继承,多态
值和引用类型的区别
什么是抽象类
什么是接口
抽象和接口的区别
什么是委托
重写和重载的区别

 

封装,继承,多态

封装:

将类里面的成员变量的方法私有化,如果外界要访问,向外界提供一个统一访问的方法

 

比如:

public class Person

{

private int age;

 

public void SetAge(int value)

{

if(value<0&&value<100)

{ 这里就叫做封装

age = value;

}

}

}

 

变量尽量写成私有,不知道是公开还是私有,也写成私有,如果外界要访问尽量不要直接写成public,写成public是为了方便和展示到unity属性面板上,正常状态下,我们的首选都是私有的,如果外界要访问,我们就给他一个Set方法,如果外界要获得,可以给他一个Get方法

 

 

 

 

 

 

 

public class Person

{

private int age;

 

public void SetAge(int value)

{

if(value<0&&value<100)

{ 这里就叫做封装

age = value;

}

}

 

public int GetAge()

{

return age;

}

}

 

虽然写了很多,但是其实还是操作age这一个变量,但安全性会提高

 

因为这种需求太多了,所哟C#提供了属性

 

 

public int Age

{

set; 这个就叫做属性

get;

}

 

如果外界不需要set我们可以只写一个get,如果外界不需要get我们可以只写一个set。

对于属性和上面的方法来说,都叫做封装.

 

我们刚才举例了将类里面成员进行封装的方法,类里面的方法也可以进行封装,我们来举例说明

比如:

 

private void Eat(int age)

{

Console.WriteLine(“我的年龄是”+age):

}

这个时候我们可以在这个方法的内部调用这个方法,但是我们不希望把他改成public,因为如果我对外界提供了public方法以后,那么实际上我的age已经有了,如果外界直接调用这个方法,,那么外界就可以给我传进来一个age,造成修改了age.

 

 

我们可以这样写:

将刚才的方法写成private ,然后写一个新的方法:

public void NewFunc() //外界专门访问的方法

{

Eat(age);

}

private void Eat(int age)

{

Console.WriteLine(“我的年龄是”+age):

}

这样做的好处是,我不会把参数暴露给外界,外界将不能修改age。

 

 

写一个方法,我们发现这个方法有很多参数,但有一些参数我们是不希望暴露给外界的,再写一个方法不给他参数,然后我们将这个方法暴露给外界写成public,这样就是一个对方法的封装

 

 

在C#中,是谁在帮助我们封装,其实就是前面的这些关键字,private和public.

 

 

封装的好处是什么?

减少耦合(其实就是两个对象之间调用的关系更加简单了)。

防止外界进行修改。

 

 

实现方式:

编写public方法进行私有变量或方法的封装

属性

 

 

 

 

 

继承:

创建新的类(派生类/子类),可以继承现有类(基类/父类)的特性,并且还可以进行修改和扩充.

 

比如说有一个类

public class LaoWang

{

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

 

后面我们在写一个类

public class XiaoWang : LaoWang

{

}

哪怕这个类里面什么都不写,但是他已经可以用LaoWang里面的变量和方法.

这个就是一个继承

C#的特性是单继承(只能有一个父类,可以有多个继承)

 

拥有一切父类的特性,可以调用一切父类里面的方法吗?取决于前面的修饰符,public可以调用,如果父类里面的方法或变量为private则不可被调用。

 

对于protected来说,在子类里面可以正常访问,但在外界不可访问,而public在外界也可以被访问。比如外界拿到了XiaoWang(XiaoWang xw = New XiaoWang();),想要调用xw.Play();

这时,如果LaoWang是protected则不可被调用,public则可以被调用。

protected class LaoWang

{

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

 

 

public class XiaoWang : LaoWang

{

public XiaoWang()

{

Play();

}

}

 

 

 

public class LaoWang

{

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public new void Play()

{

Console.WriteLine(“我要打游戏”);

}

}

这样叫做覆盖,但这样其实是不好的,所以一般情况下,你如果想覆盖,不要用new这个关键字,可以用重写

public class LaoWang

{

public virtual void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public override void Play()

{

Console.WriteLine(“我要打游戏”);

}

}

在父类的方法加上virtual,这样就是告诉子类,我这个方法是可以被覆盖的

加上virtual的方法我们叫做虚方法,所有的虚方法是可以被重写的.

 

 

有时我们希望保留父类的方法,并且还有自己的方法

public class LaoWang

{

public virtual void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public override void Play()

{

base.Play();

Console.WriteLine(“我要打游戏”);

}

}

可以通过base来保留父类的方法.

 

public class LaoWang

{

//构造方法(在实例化的时候被调用)

public LaoWang()

{

Console.WriteLinr(“我是老王”);

}

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public XiaoWang()

{

Console.WriteLine(“我是小王”);

}

}

当我们new小王的时候,“我是小王”这句话会打印,“我是老王”这句话会打印吗?

会打印,并且会先调用父类的方法,然后才会调用子类的方法

 

 

 

public class LaoWang

{

//构造方法(在实例化的时候被调用)

public LaoWang()

{

Console.WriteLinr(“我是老王”);

}

public LaoWang(int age)

{

Console.WriteLine(“我是老王,我今年”+age);

}

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public XiaoWang()

{

Console.WriteLine(“我是小王”);

}

public XiaoWang(int age)

{

Console.WriteLine(“我是小王,我今年”+age);

}

}

现在我们使用XiaoWang xw = new XiaoWang(20);

会先调用父类的LaoWang()方法,然后调用XiaoWang(int age)方法,所以无论子类的构造方法写成什么样,他调的永远都是父类默认的构造方法。

 

如果你希望去调用父类带参数的构造方法,需要使用到下面的方法:

public class LaoWang

{

//构造方法(在实例化的时候被调用)

public LaoWang()

{

Console.WriteLinr(“我是老王”);

}

public LaoWang(int age)

{

Console.WriteLine(“我是老王,我今年”+age);

}

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

}

public class XiaoWang : LaoWang

{

public XiaoWang()

{

Console.WriteLine(“我是小王”);

}

public XiaoWang(int age) : base(age)

{

Console.WriteLine(“我是小王,我今年”+age);

}

}

 

既然我们说到了重写,那我们就来说一下重载,以此来分辨两个的区别

一个类里面不能同时出现两个同名的方法,但是可以出现同名的方法参数个数是不同的。

public class LaoWang

{

//构造方法(在实例化的时候被调用)

public LaoWang()

{

Console.WriteLinr(“我是老王”);

}

public void Play()

{

Console.WriteLine(“我要去喝酒”);

}

public void Play(string name)

{

}

}

这样的方式就叫做重载

 

 

 

 

多态:

父类类型可以接收子类对象,以至于调用同样的方法产生不同的结果。

接口也是实现多态的一种方式。

 

假如现在有一个游戏里面NPC的类

public class NPC
{

public virtual void Say()

{

}

}

这个NPC父类说话我们不实现如何东西,因为我们不会直接去创建NPC,每个NPC都有 不同的说话方式

接下来写两个子类

public class ChaoShen:NPC

{

public override void Say()

{

Console.WriteLine(“超神:123456”);

}

}

public class XiaoBai:NPC

{

public override void Say()

{

Console.WriteLine(“小白:789456”);

}

}

接下来我们都将他俩实例化出来

ChaoShen cs = new ChaoShen();

XiaoBai xb = new XiaoBai();

所谓的多态是什么,多态就是指我们可以用它的父类的变量接收子类的对象,小白和超神的父类都是NPC,所以我们可以这样写:

NPC npc1 = xb;

NPC noc2 = cs;

这个东西就叫做多态

既然他们俩都是npc,就可以把他们俩放在一个数组里,正常情况下,他们俩类型不同,不能放在一个数组里,这时候就应用到多态性了:

NPC[] npcs = new NPC[] {xb.cs};

foreach (NPC npc in npcs)

{

npc.Say();

}

原文链接:https://blog.csdn.net/weixin_41644677/article/details/91905551

posted @   gaifa_gafin  阅读(219)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 什么是nginx的强缓存和协商缓存
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
   
点击右上角即可分享
微信分享提示