[英]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.