Menu
CoddyTech

パブリックメンバーとプライベートメンバー

CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 26/65。

カプセル化とは、オブジェクトがデータとそのデータを変更するメソッドをまとめて保持し、他のコードがどのメンバーを使用できるかを決めることです。他のコード向けのメンバーが、そのオブジェクトのインターフェースを構成します。

GDScriptにはpublicやprivateキーワードはありません。すべてのメンバーに外部からアクセスできます。Godotのスタイルガイドでは、先頭にアンダースコアを付けてprivateなメンバーを示します。

# bank_account.gd
class_name BankAccount
extends RefCounted

var owner_name: String
var _balance: int = 0
var _history: Array[String] = []

func _init(holder: String) -> void:
	owner_name = holder

func deposit(amount: int) -> void:
	_balance += amount
	_record("deposit %d" % amount)

func get_balance() -> int:
	return _balance

func _record(entry: String) -> void:
	_history.append(entry)

owner_name、deposit()、get_balance()は公開されているため、main.gdから使用します。_balance、_history、_record()は非公開です。これらを使用するのはbank_account.gd内のコードだけです。

# main.gd
var account := BankAccount.new("Ada")
account.deposit(50)
account.deposit(20)
print(account.owner_name) # Ada
print(account.get_balance()) # 70

アンダースコアは慣例であって、ロックではありません。main.gd内のaccount._balance = 1000000は、エラーなしで実行されます。それでも慣例には従いましょう。_balanceを変更するのがそのクラスだけであれば、残高が間違っている原因はbank_account.gd内のメソッドに限られるため、確認すべきファイルはそれだけです。

GDScriptにもprotectedレベルはありません。サブクラスはプライベートなものも含め、すべてのメンバーを継承するため、BankAccountをextendsするSavingsAccountは、自身のメソッド内で_balanceを使用できます。

_init()や_ready()などのGodotの仮想メソッドも、アンダースコアで始まります。Godotがこれらを呼び出すので、自分のプライベートメソッドに同じ名前を付けないでください。

challenge icon

チャレンジ

簡単

hero.gd の Hero クラスを完成させてください。公開メンバーは hero_name、gain_xp()、get_xp()、get_level() です。それ以外は非公開です。

  • 非公開変数 _xp(初期値は 0)と _level(初期値は 1)を追加します。
  • 非公開メソッド _update_level() を追加します。このメソッドは _level を 1 + _xp / 100(整数除算)に設定します。
  • gain_xp(amount) は amount を _xp に加算し、_update_level() を呼び出します。レベルが上がった場合は true、そうでない場合は false を返します。
  • get_xp() と get_level() は非公開の値を返します。

提供されているコードは、ヒーローの名前、続いてXPの量がいくつ続くかを読み取り、その後、各行から量を1つずつ読み取ります。各量の処理後、gain_xp() が true を返した場合は Level up! の行を出力し、その後にヒーローの状態を出力します。Ada と量 40、70、250 の場合、次のように出力されます。

Ada: 40 XP, level 1
Level up! Ada is now level 2
Ada: 110 XP, level 2
Level up! Ada is now level 4
Ada: 360 XP, level 4

コードは hero.gd に記述してください。main.gd には提供された入出力コードがあり、編集できません。

自分で試してみよう

extends Node

func _ready():
	# 用意された入出力コード:そのままにしてください
	var hero := Hero.new(OS.read_string_from_stdin())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var amount := int(OS.read_string_from_stdin())
		if hero.gain_xp(amount):
			print("Level up! %s is now level %d" % [hero.hero_name, hero.get_level()])
		print("%s: %d XP, level %d" % [hero.hero_name, hero.get_xp(), hero.get_level()])
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: GDScriptオンラインコンパイラ