Unity 中的接口和继承
在Unity的游戏开发中,理解面向对象编程的概念,如类、接口、继承和多态性,是非常重要的。本文旨在帮助理解和掌握Unity中接口和继承的概念,以及如何在实际项目中应用这些知识。
类和继承
在C#和Unity中,类是构建应用程序的基本单位。类可以包含数据(字段)和行为(方法)。类之间的一种关系是继承,其中一个类(子类)可以继承另一个类(基类或父类)的成员。
举例说明:
假设我们在制作一个游戏,需要表示不同种类的游戏角色。我们可以定义一个基类 GameCharacter 和两个派生类 Warrior 和 Mage。
基类(父类)示例
public class GameCharacter
{public float Health { get; set; }public float Speed { get; set; }public void Move(){// 实现角色移动的代码}public virtual void Attack(){// 基本攻击行为的实现}
}
在这个基类 GameCharacter 中,我们定义了两个字段 Health 和 Speed,以及两个方法 Move 和 Attack。Attack 方法被标记为 virtual,这意味着它可以在子类中被重写。
子类示例
public class Warrior : GameCharacter
{public float Strength { get; set; }public override void Attack(){// 战士特有的攻击行为的实现}
}public class Mage : GameCharacter
{public float Mana { get; set; }public override void Attack(){// 法师特有的攻击行为的实现}
}
在这两个子类 Warrior 和 Mage 中,我们继承了 GameCharacter 类,并添加了各自特有的属性(Strength 和 Mana)。同时,我们重写了 Attack 方法,以提供与基类不同的行为。
使用继承的优势
- 代码重用:
Warrior和Mage自动继承了GameCharacter的Health、Speed和Move方法。我们不需要在每个类中重复这些代码。 - 扩展性:通过继承,我们可以轻松添加新类型的游戏角色,而无需修改现有代码。
- 多态性:我们可以将
Warrior和Mage的对象视为GameCharacter的对象,这使得我们可以编写更通用的代码来处理不同类型的游戏角色。
继承在C#和Unity开发中是一个非常强大的工具,它使得代码结构更加清晰,易于维护和扩展。通过理解和应用继承,开发者可以有效地构建复杂且灵活的应用程序。
抽象类
抽象类是一种特殊类型的类,不能直接实例化。它通常用作其他类的基类,定义一些公共的功能和接口。子类必须提供抽象成员的具体实现。
举例说明:
假设我们正在开发一个游戏,其中包含多种类型的NPC(非玩家角色)。我们可以创建一个抽象基类来定义所有NPC共有的功能和属性,同时留出一些必须由具体NPC类型实现的抽象成员。
抽象基类示例
public abstract class NPC
{public string Name { get; set; }public float Health { get; set; }public void Speak(){Console.WriteLine("Hello, I am an NPC.");}public abstract void PerformAction(); // 抽象方法
}
在这个例子中,NPC 是一个抽象类,它包含两个属性(Name 和 Health)和一个具体实现的方法 Speak。此外,它还声明了一个抽象方法 PerformAction,该方法没有具体实现,需要由子类提供。
实现抽象基类的子类
public class Villager : NPC
{public override void PerformAction(){Console.WriteLine("The villager is farming.");}
}public class Guard : NPC
{public override void PerformAction(){Console.WriteLine("The guard is patrolling.");}
}
在这两个子类 Villager 和 Guard 中,我们分别实现了抽象基类 NPC 中的 PerformAction 方法。每个子类提供了该方法的具体实现,反映了不同NPC类型的特定行为。
使用抽象类的优势
- 强制实现:抽象类强制子类实现特定的抽象成员,确保子类遵循一定的规范。
- 代码重用:抽象类可以包含非抽象成员(如
Speak方法),这些成员被所有子类共享,减少了代码重复。 - 设计灵活性:通过定义抽象类,我们可以创建出灵活的、可扩展的系统结构,允许开发者后续添加新类型的NPC,而无需修改现有的抽象类代码。
抽象类是面向对象设计中的一个重要概念,它提供了一种强有力的方式来设计灵活且具有可扩展性的程序结构。理解并正确应用抽象类对于创建高效、可维护的C#和Unity应用程序至关重要。
接口
接口是定义一组没有实现的方法的契约。实现接口的类必须提供这些方法的具体实现。接口是实现多态性的一种方式。
举例说明:
假设我们正在开发一个游戏,需要处理不同类型的交互对象,例如玩家可以与之交谈或交易的NPC。
接口示例
public interface IInteractable
{void Interact();void Talk();
}
在这个例子中,IInteractable 是一个接口,它定义了两个方法:Interact 和 Talk。这两个方法没有具体的实现,代表了任何可交互对象应具备的行为。
实现接口的类
public class Merchant : IInteractable
{public void Interact(){Console.WriteLine("Welcome to my shop!");}public void Talk(){Console.WriteLine("Have you seen the latest goods?");}
}public class Villager : IInteractable
{public void Interact(){Console.WriteLine("Nice to meet you!");}public void Talk(){Console.WriteLine("I heard there's a storm coming.");}
}
在这两个类 Merchant 和 Villager 中,我们分别实现了接口 IInteractable 中的 Interact 和 Talk 方法。每个类提供了这些方法的具体实现,反映了不同交互对象的特定行为。
使用接口的优势
- 多态性:接口允许我们使用多态性,即可以用接口类型来引用实现了该接口的任何类的对象。这增加了代码的灵活性。
- 灵活的设计:通过使用接口,我们可以编写更加灵活和可扩展的代码。可以轻松添加新的交互对象类型,而无需修改现有的接口或使用接口的代码。
- 解耦:接口有助于减少类之间的耦合,使得不同的类可以独立变化而不影响其他类。
IInteractable interactable = new Merchant();
interactable.Interact(); // 输出 "Welcome to my shop!"
interactable = new Villager();
interactable.Interact(); // 输出 "Nice to meet you!"
在这个例子中,我们使用 IInteractable 接口来引用 Merchant 和 Villager 的对象。这使我们能够用同样的方式处理不同类型的交互对象,而不关心它们具体是哪个类的实例。
接口是C#和Unity编程中实现多态性和灵活设计的关键工具。通过定义和实现接口,开发者可以创建出可互操作、易于维护和扩展的程序结构。
多态性
多态性是面向对象编程的一个核心概念,它允许你将一个类的对象视为其父类或接口的对象,并调用在父类或接口中声明的方法。在运行时,会执行该对象的类中对这些方法的具体实现。
举例说明:
假设我们正在开发一个动物园模拟器游戏,其中包含多种不同的动物。每种动物都会以其独特的方式发出声音。我们可以使用多态性来表示这些不同的行为。
父类和接口定义
首先,我们定义一个基类 Animal 和一个方法 MakeSound,然后定义一个接口 IPlayable 与一个方法 Play。
public abstract class Animal
{public abstract void MakeSound();
}public interface IPlayable
{void Play();
}
子类实现
接着,我们创建几个继承自 Animal 并实现 IPlayable 接口的子类,每个子类都有自己的 MakeSound 和 Play 方法实现。
public class Dog : Animal, IPlayable
{public override void MakeSound(){Console.WriteLine("Bark!");}public void Play(){Console.WriteLine("The dog is fetching the ball.");}
}public class Cat : Animal, IPlayable
{public override void MakeSound(){Console.WriteLine("Meow!");}public void Play(){Console.WriteLine("The cat is chasing a laser pointer.");}
}
多态性的应用
现在我们可以编写一个接受 Animal 类型和 IPlayable 接口类型对象的代码,并调用它们的方法。在运行时,将调用实际对象类型的方法实现。
Animal myDog = new Dog();
Animal myCat = new Cat();
IPlayable playfulDog = myDog as IPlayable;
IPlayable playfulCat = myCat as IPlayable;myDog.MakeSound(); // 输出 "Bark!"
myCat.MakeSound(); // 输出 "Meow!"playfulDog.Play(); // 输出 "The dog is fetching the ball."
playfulCat.Play(); // 输出 "The cat is chasing a laser pointer."
在这个例子中,myDog 和 myCat 虽然被声明为 Animal 类型,但它们分别指向 Dog 和 Cat 的实例。因此,当调用 MakeSound 方法时,执行的是 Dog 和 Cat 类中各自的 MakeSound 方法实现。同样,尽管 playfulDog 和 playfulCat 被声明为 IPlayable 接口类型,但它们执行的是各自类中的 Play 方法实现。
这个例子展示了多态性如何使得我们能够以通用的方式处理不同类型的对象,同时保持每个对象类型特有的行为。这是面向对象编程中提高代码灵活性和可重用性的重要手段。
相关文章:
Unity 中的接口和继承
在Unity的游戏开发中,理解面向对象编程的概念,如类、接口、继承和多态性,是非常重要的。本文旨在帮助理解和掌握Unity中接口和继承的概念,以及如何在实际项目中应用这些知识。 类和继承 在C#和Unity中,类是构建应用程序…...
C++区间覆盖(贪心算法)
假设有n个区间,分别是:[l1,r1], [l2,r2], [l3,r3].....[ln,rn] 从这n个区间中选出某些区间,要求这些区间满足两两不相交,最多能选出多少个区间呢? 基本思路: 按照右端点从小到大排序,再比较左端…...
Python with Office 054 - Work with Word - 7-9 插入图像 (3)
近日详细学习了寒冰老师的很好的书《让Python遇上Office》,总结了系列视频。 这个是其中的一集:如何在Word中插入图像,我会陆续分享其他的视频并加上相应说明 https://www.ixigua.com/7319498175104942643?logTage9d15418663166a05d10...
Nodejs前端学习Day4_fs文件系统模块基础应用之成绩转换
君子应有龙蛇之变,处于木雁之间 文章目录 前言一、fs文件系统模块1.1 判断文件是否读取成功1.2 向指定的文件中写入内容1.2.1 fs.writeFile的语法格式1.2.2 fs.readFile和fs.writeFile的运用——成绩转换 总结 前言 Day3fs开了点头 一、fs文件系统模块 1.1 判断文…...
五、Kotlin 函数进阶
1. 高阶函数 1.1 什么是高阶函数 以下 2 点至少满足其一的函数称为高阶函数: 形参列表中包含函数类型的参数 //参数 paramN 可以是:函数引用、函数类型变量、或 Lambda 表达式。 fun funName(param1: Type1, param2: Type2, ... , paramN: (p1: T1, p2…...
重温《深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)》 –– 学习笔记(一)
第一部分:走近Java 第1章:走近Java 1.1 Java的技术体系 SUN 官方所定义的 Java 技术体系包括:Java程序设计语言、Java虚拟机、Class文件格式、Java API类库、第三方(商业机构和开源社区)Java类库。 其中࿰…...
定向减免!函数计算让轻量 ETL 数据加工更简单,更省钱
作者:澈尔、墨飏 业内较为常见的高频短时 ETL 数据加工场景,即频率高时延短,一般均可归类为调用密集型场景。此场景有着高并发、海量调用的特性,往往会产生高额的计算费用,而业内推荐方案一般为攒批处理,业…...
git checkout和git switch的区别
git checkout 和 git switch 是 Git 中用于切换分支的命令,但它们在某些方面有一些区别。需要注意的是,git switch 是在 Git 2.23 版本引入的,它提供了一种更直观的分支切换方式。 git checkout: 分支切换: 在 Git 2.…...
故障树分析蒙特卡洛仿真程序(附MATLAB完整代码)
故障树是一种特殊的倒立树状逻辑因果关系图,它用事件符号、逻辑门符号和转移符号描述系统中各种事件之间的因果关系,通过对引起系统故障的各种因素进行逻辑因果分析,确定导致故障发生的各种可能的原因,并通过定性和定量分析找出系…...
数据结构-线性表
文章目录 数据结构—线性表1.线性表的定义和基本操作线性表的定义线性表的特点线性表的基本操作 2.线性表的顺序存储和链式存储表示顺序存储链式存储单链表循环链表双向链表 数据结构—线性表 1.线性表的定义和基本操作 线性表的定义 定义:线性表是具有相同数据类…...
java金额数字转中文
java金额数字转中文 运行结果: 会进行金额的四舍五入。 工具类源代码: /*** 金额数字转为中文*/ public class NumberToCN {/*** 汉语中数字大写*/private static final String[] CN_UPPER_NUMBER {"零", "壹", "贰",…...
Ubuntu findfont: Font family ‘SimHei‘ not found.
matplotlib中文乱码显示 当我们遇到这样奇怪的问题时, 结果往往很搞笑 尝试1不行 Stopping Jupyter Installing font-manager: sudo apt install font-manager Cleaning the matplotlib cache directory: rm ~/.cache/matplotlib -fr Restarting Jupyter. 尝试2 This work fo…...
mysql小知识
什么是sql语句的子查询 SQL语句的子查询是指在一个SQL语句中嵌套另一个SQL语句。子查询可以嵌套在主查询的FROM子句、WHERE子句、HAVING子句、SELECT子句或INSERT语句中。 子查询可以返回一个结果集,这个结果集可以被主查询使用。子查询通常用于获取需要在主查询中使…...
Unity中URP下逐顶点光照
文章目录 前言一、之前额外灯逐像素光照的数据准备好后,还有最后的处理二、额外灯的逐顶点光照1、逐顶点额外灯的光照颜色2、inputData.vertexLighting3、surfaceData.albedo 前言 在上篇文章中,我们分析了Unity中URP下额外灯,逐像素光照中聚…...
Spring Boot3整合Druid(监控功能)
目录 1.前置条件 2.导依赖 错误依赖: 正确依赖: 3.配置 1.前置条件 已经初始化好一个spring boot项目且版本为3X,项目可正常启动。 作者版本为3.2.2 初始化教程: 新版idea创建spring boot项目-CSDN博客https://blog.csdn…...
使用Gin框架,快速开发高效的Go Web应用程序
推荐 海鲸AI-GPT4.0国内站点:https://www.atalk-ai.com 前言 在当今的软件开发领域,Go语言以其简洁的语法和出色的性能逐渐成为开发者们的新宠。而Gin框架,则是Go语言中最受欢迎的Web框架之一,它以高性能和易用性著称。本文将带你…...
【Unity】【游戏开发】Pico打包后项目出现运行时错误如何Debug
【背景】 开发过程中的报错可以通过控制台查看,但是PICO项目这类依赖特定设备环境的应用往往存在打包后在设备端发生运行时错误。这时如何能查看到Debug信息呢? 【分析】 Pico也是安卓系统,所以这个问题就可以泛化为Unity有哪些在安卓端运…...
一种解决常用存储设备无法被电脑识别的方法
一、通用串行总线控制器描述 通用串行总线(Universal Serial Bus,简称USB),是连接电脑与设备的一种序列总线标准,也是一种输入输出(I/O)连接端口的技术规范,广泛应用于个人电脑和移动…...
Spark运行架构以及容错机制
Spark运行架构以及容错机制 1. Spark的角色区分1.1 Driver1.2 Excuter 2. Spark-Cluster模式的任务提交流程2.1 Spark On Yarn的任务提交流程2.1.1 yarn相关概念2.1.2 任务提交流程 2.2 Spark On K8S的任务提交流程2.2.1 k8s相关概念2.2.2 任务提交流程 3. Spark-Cluster模式的…...
短剧APP小程序源码 全开源短视频系统源码/h5/app/小视频系统
主要功能介绍: 小剧场短剧影视小程序源码 全开源 带支付收益等模式 付费短剧小程序源码 多平台小程序支持 项目功能介绍 支持无限滑动 高性能滑动 预加载 视频预览 支持剧情介绍,集合壁纸另外仿抖音滑动效果 支持会员模式,支持用户单独购买等等多功能 本系统&…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
搭建DNS域名解析服务器(正向解析资源文件)
正向解析资源文件 1)准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2)服务端安装软件:bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...
MySQL JOIN 表过多的优化思路
当 MySQL 查询涉及大量表 JOIN 时,性能会显著下降。以下是优化思路和简易实现方法: 一、核心优化思路 减少 JOIN 数量 数据冗余:添加必要的冗余字段(如订单表直接存储用户名)合并表:将频繁关联的小表合并成…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...
