简体   繁体   English

为什么在受保护的变量上使用构造函数?

[英]Why use a constructor over protected variables?

I'm building some classes within unity to define the mechanics individually, and transition between each for easier and cleaner code.我正在统一内构建一些类来单独定义机制,并在每个类之间进行转换,以获得更简单和更清晰的代码。

What I wanna know, is when should I be using a constructor to pass variables around, and when to use protected variables.我想知道的是,何时应该使用构造函数来传递变量,以及何时使用受保护的变量。 What are the pros and cons of each, and what should I know about them?每种方法的优缺点是什么,我应该了解它们吗? Also what should I lean towards, like what's practical?还有我应该倾向于什么,比如什么是实用的?

Previously I'd pass these variables into the PlayerState constructor, then in my classes that extend from my PlayerState would follow suit.以前我会将这些变量传递给 PlayerState 构造函数,然后在从我的 PlayerState 扩展的类中也会效仿。 But if they're protected variables I don't need to pass them into the constructor to access them, and I was wondering what should I do?但是如果它们是受保护的变量,我不需要将它们传递给构造函数来访问它们,我想知道我应该怎么做? using UnityEngine;使用 UnityEngine;

The new way I'm doing it:我这样做的新方法:

public class PlayerState
{
    //protected Core Core;
    protected Player player;
    protected PlayerStateMachine StateMachine;
    protected PlayerData playerData;
    private string currentAnimation;
    protected float StartTime; // Start time gets set everytime we're in a state, that way we have a reference for how long we've been in any state (good for mechanics)
    protected bool isAnimationFinished;
    protected bool isExitingState; // Very useful, if you run through if/else conditionals in a superState, the substate may still run, and both end up calling a change state. This will stop this from happening

    public PlayerState(string currentAnimation)
    {
        this.currentAnimation = currentAnimation;
    }

    public virtual void Enter() { }
    public virtual void Exit() { }
    public virtual void LogicUpdate() { }
    public virtual void PhysicsUpdate() { }
    public virtual void DoChecks() { }
}

The Old Way:老办法:

public class PlayerState
{
    protected Core Core;
    protected Player player; // protected means private but shared between components that inherit the class
    protected PlayerStateMachine StateMachine;
    protected PlayerData playerData;
    private string currentAnimation;
    protected float StartTime; // Start time gets set everytime we're in a state, that way we have a reference for how long we've been in any state (good for mechanics)
    protected bool isAnimationFinished;
    protected bool isExitingState; // Very useful, if you run through if/else conditionals in a superState, the substate may still run, and both end up calling a change state. This will stop this from happening

    public PlayerState(Player player, PlayerStateMachine stateMachine, PlayerData playerData, string currentAnimation)
    {
        this.player = player;
        this.StateMachine = stateMachine;
        this.playerData = playerData;
        this.currentAnimation = currentAnimation;
        Core = player.Core;
    }


        // So now we code out the functions for each state
    // Every state must have an enter and exit function, as well as an update and fixedUpdate function
    // We're naming the update function as "LogicUpdate", and fixedUpate as "PhysicsUpdate"

    public virtual void Enter() // virtual means this function may be overriden from classes that inherit this class
    {
        DoChecks();
        player.Anim.SetBool(currentAnimation, true);
        StartTime = Time.time;
        isAnimationFinished = false;
        isExitingState = false;
        //Debug.Log("Current Animation: " + currentAnimation);
    }


    public virtual void Exit()
    {
        player.Anim.SetBool(currentAnimation, false);
        isExitingState = true;
    }

The way I applied it to other classes the old way:我以旧方式将其应用于其他类的方式:

public class PlayerGroundedState : PlayerState
{
    protected Vector2 input;
    protected bool jumpInput;
    private bool grabInput;
    private bool dashInput;
    private bool isTouchingGround;
    private bool isTouchingWall;
    protected bool willCollideWithCeiling; 

    public PlayerGroundedState(Player player, PlayerStateMachine stateMachine, PlayerData playerData, string currentAnimation) : base(player, stateMachine, playerData, currentAnimation)
    {
    }


    public override void Enter()
    {
        base.Enter();
        player.JumpState.ResetAmountOfJumpsLeft();
        player.DashState.ResetCanDash();
    }


    public override void Exit()
    {
        base.Exit();
    }

I don't have to pass player into the constructor of PlayerState and PlayerGroundedState to access it if it's protected.如果它受到保护,我不必将 player 传递给 PlayerState 和 PlayerGroundedState 的构造函数来访问它。 What should I do though, which method is the proper way to handle the variables, also which is better for my cpu?但是我该怎么办,哪种方法是处理变量的正确方法,哪种方法对我的 cpu 更好?

This is just a question related to OOP.这只是一个与OOP有关的问题。 Unity is not needed to be considered.不需要考虑统一性。

A constructor let you create an object instance and initialize the members of the object at the same time.构造函数让您可以创建 object 实例并同时初始化 object 的成员。 If there are some immutable members (ie they will never be changed after construction), you may need to initialize them in constructors, and you may add the keyword readonly to the members.如果有一些不可变的成员(即构造后永远不会改变),你可能需要在构造函数中初始化它们,你可以在成员中添加关键字readonly If you don't need to initialize any member with passing parameter(s) when the instance is created, there is no need to have a custom constructor (unless you want to hide the default constructor).如果您不需要在创建实例时使用传递参数初始化任何成员,则不需要自定义构造函数(除非您想隐藏默认构造函数)。

The access modifier protected makes the member accessible only in code in the same class, or in a class that is derived from that class.访问修饰符protected使该成员只能在同一 class 中的代码或从该 class 派生的 class 中的代码中访问。 If you need to access the member in other places, you still need do it via public/internal methods such as setters and getters, or make it public / internal .如果你需要访问其他地方的成员,你仍然需要通过 setter 和 getter 等 public/internal 方法,或者将其设为public / internal

In your case, I think a constructor is needed to initialize the members such as player when a PlayerState instance is created.在您的情况下,我认为在创建PlayerState实例时需要一个构造函数来初始化诸如player之类的成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM