Unity 变量修饰符 之protected ,internal,const , readonly, static

news2024/9/21 14:52:40

文章目录

  • protected
  • internal
  • const
  • readonly
  • static

在这里插入图片描述

protected

当在Unity中使用C#编程时,protected是一种访问修饰符,用于控制类成员(字段、方法、属性等)的可见性和访问权限。protected修饰的成员可以在当前类内部、派生类(子类)内部以及同一命名空间中的其他类中访问,但在类的外部是不可见的。以下是更详细的说明和示例:

特性和用法:

  • protected修饰符允许成员在继承关系中被继承和访问。
  • protected成员可以在子类中被重写(方法)或扩展(字段和属性)。
  • protected成员不允许直接在类外部访问,但可以在继承的子类中通过基类的实例进行访问。

示例:

// 基类(父类)
public class Animal
{
    protected string species; // 只在当前类及其子类中可见

    public Animal(string species)
    {
        this.species = species;
    }

    protected void MakeSound()
    {
        Debug.Log("Animal makes a sound");
    }
}

// 派生类(子类)
public class Dog : Animal
{
    public Dog() : base("Dog")
    {
        // 子类可以访问基类的受保护字段和方法
        species = "Canine";
        MakeSound(); // 调用基类的受保护方法
    }

    public void Bark()
    {
        Debug.Log("Dog barks");
    }
}

// 在其他类中使用
public class GameManager
{
    void Start()
    {
        // 在这里不能直接访问Animal类的protected成员
        // Animal animal = new Animal("Generic Animal");
        // animal.species = "Unknown"; // 错误!无法访问

        Dog dog = new Dog();
        // 可以访问基类中的protected字段和方法
        dog.species = "Domestic Dog"; // 合法,因为是在子类中访问
        dog.MakeSound(); // 合法,因为是在子类中访问

        dog.Bark(); // 调用子类的公共方法
    }
}

在这个示例中,Animal类作为基类(父类),拥有一个protected字段species和一个protected方法MakeSound()Dog类作为派生类(子类),继承了Animal类,并能够访问基类的protected成员。Dog类还定义了自己的公共方法Bark()

GameManager类中,我们不能直接访问Animal类的protected成员,但可以通过Dog类的实例来访问。这展示了protected修饰符在继承关系中的作用,允许子类访问基类的受保护成员,但不允许在类外部直接访问。

internal

在C#编程语言以及在Unity游戏开发中,internal是一种访问修饰符,用于控制类成员的可见性和访问权限。internal修饰的成员可以在同一个程序集(assembly)内的任何类中访问,但在程序集之外是不可见的。下面是更详细的介绍和示例:

特性和用法:

  • internal修饰符用于声明类内部的成员,这些成员可以在同一个程序集中的其他类中访问,但在程序集外部不可见。
  • internal成员对于实现模块内的细节和隐藏数据非常有用,同时又不会暴露给程序集之外的代码。

示例:

假设你正在开发一个Unity游戏,包含以下几个脚本文件:

  1. Player.cs
using UnityEngine;

public class Player : MonoBehaviour
{
    internal int playerScore; // 在同一个程序集内的其他类中可见

    internal void UpdateScore(int points)
    {
        playerScore += points;
    }
}
  1. GameManager.cs
using UnityEngine;

public class GameManager : MonoBehaviour
{
    void Start()
    {
        Player player = new Player();
        player.UpdateScore(10); // 在同一个程序集内的类中可以访问internal方法和字段
        Debug.Log("Player score: " + player.playerScore);
    }
}

在这个示例中,Player类和GameManager类都在同一个程序集(Unity项目)内。Player类中的字段playerScore和方法UpdateScore()被声明为internal,因此它们可以在同一个程序集中的其他类中访问,比如在GameManager类中。

然而,如果我们尝试在程序集之外的类中访问playerScoreUpdateScore(),就会引发编译错误。

总结起来,internal修饰符在Unity开发中用于控制类成员的可见性,确保这些成员只在同一个程序集内可见。这对于隐藏内部细节、实现模块化以及防止未授权访问非常有用。

const

在C#编程语言以及在Unity游戏开发中,const是一个关键字,用于声明常量。常量是一种在程序运行期间不能被修改的值,它们在声明时必须被初始化,并且一旦初始化后,就不能再更改。下面是更详细的介绍和示例:

常量特性和用法:

  • const关键字用于声明常量,一旦声明并初始化,其值在程序的整个生命周期内保持不变。
  • 常量必须在声明时进行初始化,并且只能在声明语句中初始化。
  • 常量只能包含基本数据类型(如整数、浮点数、布尔值)以及字符串类型。
  • 常量在编译时进行值的替换,这有助于提高代码的性能。

示例:

public class Constants
{
    public const int MaxPlayerHealth = 100;
    public const float Gravity = 9.81f;
    public const string GameTitle = "My Awesome Game";
}

public class Player : MonoBehaviour
{
    private int health = Constants.MaxPlayerHealth;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            health -= 10;
            Debug.Log("Player health: " + health);
        }
    }
}

在这个示例中,Constants类定义了三个常量:MaxPlayerHealthGravityGameTitle。这些常量在声明时进行了初始化,并且它们在整个程序运行期间保持不变。

Player类中,我们使用Constants.MaxPlayerHealth来初始化玩家的健康值,并在每次按下空格键时减少玩家的健康值。因为MaxPlayerHealth是一个常量,其值在编译时就已经被确定,并且在运行时不会被修改。

总之,const关键字用于声明常量,这些常量在程序运行期间保持不变。常量适用于需要使用固定值的情况,如最大值、常用常数等。在Unity开发中,常量可以用于避免魔术数值、提高代码可读性以及确保某些值不会被错误地修改。

readonly

在C#编程语言中,readonly是一个关键字,用于声明只读字段。只读字段是在声明时初始化,之后不能再修改其值。与之相反,const用于声明编译时常量,而readonly用于在运行时只允许初始化一次的字段。以下是更详细的介绍和示例:

readonly特性和用法:

  • readonly关键字用于声明只读字段,这些字段必须在声明时或在构造函数中初始化,之后不能再修改。
  • readonly字段通常用于在类的实例生命周期内保持不变的值,但允许在构造函数中根据需要进行初始化。
  • const不同,readonly字段的值是在运行时确定的,可以根据对象的状态来初始化。

示例:

public class Circle
{
    public readonly float Radius; // 只读字段

    public Circle(float radius)
    {
        Radius = radius; // 在构造函数中初始化只读字段
    }

    // 错误!无法在类外部赋值给只读字段
    // public void UpdateRadius(float newRadius)
    // {
    //     Radius = newRadius;
    // }
}

public class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle(5.0f);
        Console.WriteLine("Circle radius: " + circle.Radius); // 输出:5

        // 错误!无法在类外部修改只读字段的值
        // circle.Radius = 10.0f;
    }
}

在这个示例中,Circle类定义了一个只读字段Radius,它在构造函数中进行了初始化。一旦初始化后,就无法再修改Radius的值。在Program类中,我们创建了一个Circle对象,通过只读字段Radius来存储圆的半径,并在输出中显示了半径的值。

需要注意的是,readonly字段在声明时或在构造函数中初始化后,就不能再在其他地方修改。这对于确保一些值在对象的生命周期内保持不变非常有用,同时也允许在构造函数中初始化基于特定条件的值。

static

在C#编程语言中,static是一个关键字,用于声明静态成员、方法和类。静态成员与特定实例无关,它们在整个应用程序的生命周期中保持不变。静态成员可以通过类名直接访问,无需创建类的实例。以下是更详细的介绍和示例:

static特性和用法:

  • static关键字用于声明静态成员,这些成员与类关联,而不是与类的实例(对象)关联。
  • 静态成员在内存中只有一份副本,无论创建多少个类的实例,它们的值都是相同的。
  • 静态成员在整个应用程序的生命周期中保持不变,可以在不创建类的实例的情况下访问。

静态方法的特点:

  • 静态方法可以直接通过类名调用,无需创建类的实例。
  • 静态方法内部不能访问实例成员,因为它们没有与特定实例关联。
  • 静态方法通常用于不依赖于实例状态的操作,如数学函数、工具方法等。

静态字段的特点:

  • 静态字段是与类关联的字段,所有类的实例共享同一个字段。
  • 静态字段通常用于保存全局共享的状态,如计数器、配置值等。

示例:

public class MathUtils
{
    public static int Add(int a, int b)
    {
        return a + b;
    }
}

public class Counter
{
    private static int count; // 静态字段

    public static void Increment()
    {
        count++;
    }

    public static int GetCount()
    {
        return count;
    }
}

public class Program
{
    static void Main(string[] args)
    {
        int sum = MathUtils.Add(5, 3); // 调用静态方法
        Console.WriteLine("Sum: " + sum);

        Counter.Increment(); // 调用静态方法
        Console.WriteLine("Count: " + Counter.GetCount()); // 输出:1
    }
}

在上面的示例中,MathUtils类定义了一个静态方法Add(),可以通过类名直接调用。Counter类定义了一个静态字段count和两个静态方法,用于计数器的增加和获取。在Program类中,我们调用了MathUtils.Add()静态方法和Counter类的静态方法来展示静态成员的使用。

总之,static关键字在C#中用于声明静态成员,这些成员在整个应用程序的生命周期中保持不变,无需创建类的实例即可访问。静态成员在全局共享状态、提供工具函数等方面具有重要作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

大数据背景和概念

一、背景 1.岗位现状 大数据在一线互联网已经爆发了好多年,2015年-2020年(国内互联网爆发期)那时候的大数据开发,刚毕业能写Hive SQL配置个离线任务、整个帆软报表都20K起步。如果做到架构师,50K跑不掉。现在市场回归…

字符串旋转(2)

题目要求: 写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。 例如: 给定s1 AABCD和s2 BCDAA,返回1。给定s1abcd和s2ACBD,返回0。AABCD左旋一个字符得到ABCDAAABCD左旋两个字符得到BCDAAAABCD右旋一个…

Stm32学习记录之中断

1、前言 该系列文章用于记录个人学习stm32单片机的过程,欢迎指导讨论~。 2、中断知识点梳理 中断 { N V I C ( 内嵌向量中断控制器 ) { 中断向量表 优先级 { 抢占优先级 响应优先级 自然优先级 优先级分组 E X T I ( 外部中断 ) { 触发方式 { 上边沿 下边沿 双边沿 …

wazuh安装、Rootkit原理解析与检测实践

目录 1.wazuh 1)什么是wazuh 2)安装wazuh 方法一:仓库安装(跟着官方文档走) 方法二:虚拟机OVA安装 2.Rootkit原理解析与检测实践 Rootkit主要分为以下2种 解压并编译这个文件 利用chkrootkit检查rootk…

看了这么多热闹,AI帮助你解决实际问题了吗?

经历了近两个月的日更之后,这个星期发文频率有所下降,日更需要花费更多的时间精力,而这恰恰是一个人忙起来之后无法保证的。后续发文频率稍做调整,内容会继续保持更新。 前几日小米发布会(雷老板2023年度演讲&#xff…

EndNote-文献管理工具【安装篇】

下载:(文末附安装包,建议使用这一个,官网都需要付费) 打开安装包,双击: 安装完了之后不要直接运行,因为EndNote软件少了一个类型的软件:GB/T17714。 因此我们需要把这个…

实现两个栈模拟队列

实现两个栈模拟队列 思路:可以想象一下左手和右手,两个栈:stack1(数据所在的栈) ,stack2(临时存放)。 入队:需要将入队 num 加在 stack1 的栈顶即可; 出队&am…

plt绘制箱型图+散点图

import numpy as np import matplotlib.pyplot as plt# 创建示例数据 np.random.seed(1) data [np.random.normal(0, std, 100) for std in range(1, 4)]# 绘制箱型图 plt.boxplot(data, patch_artistTrue,zorder0)# 添加数据点的散点图,并设置参数以避免重叠 for …

[四次挥手]TCP四次挥手握手由入门到精通(知识精讲)

⬜⬜⬜ 🐰🟧🟨🟩🟦🟪(*^▽^*)欢迎光临 🟧🟨🟩🟦🟪🐰⬜⬜⬜ ✏️write in front✏️ 📝个人主页:陈丹宇jmu &am…

Pytorch的torch.utils.data中Dataset以及DataLoader等详解

在我们进行深度学习的过程中,不免要用到数据集,那么数据集是如何加载到我们的模型中进行训练的呢?以往我们大多数初学者肯定都是拿网上的代码直接用,但是它底层的原理到底是什么还是不太清楚。所以今天就从内置的Dataset函数和自定…

【Go】Go 文本匹配 - 正则表达式基础与编程中的应用 (8000+字)

正则表达式(Regular Expression, 缩写常用regex, regexp表示)是计算机科学中的一个概念,很多高级语言都支持正则表达式。 目录 何为正则表达式 语法规则 普通字符 字符转义 限定符 定位符 分组构造 模式匹配 regexp包 MatchString…

websocker无法注入依赖

在公司中准备用websocker统计在线人数,在WebSocketServer使用StringRedisTemplate保存数据到redis中去,但是在保存的时候显示 StringRedisTemplate变量为null 详细问题 2023-08-20 10:37:14.109 ERROR 28240 --- [nio-7125-exec-1] o.a.t.websocket.po…

【AI】文心一言的使用

一、获得内测资格: 1、点击网页链接申请:https://yiyan.baidu.com/ 2、点击加入体验,等待通过 二、获得AI伙伴内测名额 1、收到短信通知,点击链接 网页Link:https://chat.baidu.com/page/launch.html?fa&sourc…

LeetCode_Java_2236. 判断根结点是否等于子结点之和

2236. 判断根结点是否等于子结点之和 给你一个 二叉树 的根结点 root,该二叉树由恰好 3 个结点组成:根结点、左子结点和右子结点。 如果根结点值等于两个子结点值之和,返回 true ,否则返回 false 。 示例1 输入:roo…

【CMake保姆级教程】CMake的使用

文章目录 前言CMake的使用注释注释行注释块 CMake操作共处一室VIP 包房 前言 在上节课我们已经讲了CMake的安装和简单使用,本节课我们来讲解CMake的命令和他的含义 CMake的使用 CMake支持大写、小写、混合大小写的命令。如果在编写CMakeLists.txt文件时使用的工具…

vue3中的router和useRouter的区别

结论:从vue-router的官方文档中发现,useRouter需要在setup中使用,而router可以在任何组件中使用。二者是等价的,适用场景不同。 问题:使用useRouter创建的实例,未能成功调用方法push()。会报错:…

gdb 常用命令

gdb 常用命令 文章目录 gdb 常用命令gdb 调试一般步骤常用命令infostep、next、continue、finish、untilexaminebreakinfo 、enable、disable和delete命令 backtrace和framebacktraceframe listprintwhatis和ptypethreadnext、stepreturn、finishuntiljumpdisassembleset args …

攻防世界-can_has_stdio?

原题 解题思路 这使用的是brainfuck语言,语言介绍如下:Brainfuck详解。 使用网站解码即可:CTF在线工具。

《HeadFirst设计模式(第二版)》第十一章代码——代理模式

代码文件目录: RMI: MyRemote package Chapter11_ProxyPattern.RMI;import java.rmi.Remote; import java.rmi.RemoteException;public interface MyRemote extends Remote {public String sayHello() throws RemoteException; }MyRemoteClient packa…