簡體   English   中英

為什么在受保護的變量上使用構造函數?

[英]Why use a constructor over protected variables?

我正在統一內構建一些類來單獨定義機制,並在每個類之間進行轉換,以獲得更簡單和更清晰的代碼。

我想知道的是,何時應該使用構造函數來傳遞變量,以及何時使用受保護的變量。 每種方法的優缺點是什么,我應該了解它們嗎? 還有我應該傾向於什么,比如什么是實用的?

以前我會將這些變量傳遞給 PlayerState 構造函數,然后在從我的 PlayerState 擴展的類中也會效仿。 但是如果它們是受保護的變量,我不需要將它們傳遞給構造函數來訪問它們,我想知道我應該怎么做? 使用 UnityEngine;

我這樣做的新方法:

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() { }
}

老辦法:

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;
    }

我以舊方式將其應用於其他類的方式:

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();
    }

如果它受到保護,我不必將 player 傳遞給 PlayerState 和 PlayerGroundedState 的構造函數來訪問它。 但是我該怎么辦,哪種方法是處理變量的正確方法,哪種方法對我的 cpu 更好?

這只是一個與OOP有關的問題。 不需要考慮統一性。

構造函數讓您可以創建 object 實例並同時初始化 object 的成員。 如果有一些不可變的成員(即構造后永遠不會改變),你可能需要在構造函數中初始化它們,你可以在成員中添加關鍵字readonly 如果您不需要在創建實例時使用傳遞參數初始化任何成員,則不需要自定義構造函數(除非您想隱藏默認構造函數)。

訪問修飾符protected使該成員只能在同一 class 中的代碼或從該 class 派生的 class 中的代碼中訪問。 如果你需要訪問其他地方的成員,你仍然需要通過 setter 和 getter 等 public/internal 方法,或者將其設為public / internal

在您的情況下,我認為在創建PlayerState實例時需要一個構造函數來初始化諸如player之類的成員。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM