Menu
CoddyTech

情報隠蔽

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

情報隠蔽は、private変数よりもさらに一歩進んだ考え方です。クラスを使うコードは、そのpublicメソッドが何をするかだけに依存し、クラスがデータをどのように保存しているかには依存しません。そうすれば、そのコードに手を加えずに保存方法を変更できます。

# inventory.gd
class_name Inventory
extends RefCounted

var _counts: Dictionary = {}

func add(item: String, amount: int) -> void:
	_counts[item] = _counts.get(item, 0) + amount

func count(item: String) -> int:
	return _counts.get(item, 0)

func remove(item: String, amount: int) -> bool:
	if count(item) < amount:
		return false
	_counts[item] -= amount
	return true

main.gd は add()、count()、remove() を呼び出し、Dictionary を見ることはありません。後で Inventory が代わりにスロットの Array を保持するようになっても、変更されるのは inventory.gd だけです。

配列または辞書を返すゲッターには注意してください。GDScriptはこれらの値を参照渡しします。呼び出し元が受け取るのはコピーではなく、オブジェクト自身の配列であり、クラスのメソッドを通さずに変更できます。

# quest_log.gd
var _quests: Array[String] = ["Find the key"]

func get_quests() -> Array[String]:
	return _quests
# main.gd
var journal := QuestLog.new()
var quests := journal.get_quests()
quests.append("Skip the boss")
print(journal.get_quests()) # ["Find the key", "Skip the boss"]

代わりにコピーを返します。duplicate()は同じ要素を持つ新しいArrayを作成するため、それへの変更はオブジェクトの外部にとどまります。

func get_quests() -> Array[String]:
	return _quests.duplicate()

Dictionary、または他のArrayを保持するArrayには、duplicate(true)を使います。内側のArrayとDictionaryもコピーされます。

challenge icon

チャレンジ

簡単

playlist.gd に Playlist クラスを書いてください。曲のタイトルをプライベートな Array _songs に保持し、ほかのコードからは次のメソッドだけを使用します。

  • add(title) はタイトルを追加し、true を返します。タイトルがすでにプレイリストにある場合は何も変更せず、false を返します。
  • remove(title) はタイトルを削除して true を返します。タイトルがない場合は false を返します。
  • count() は曲数を返します。
  • get_titles() は、追加された順にタイトルのコピーを返します。

用意されたコードはコマンド数を読み取り、1行につき1つのコマンド(add Blue Sky または remove Blue Sky)を読み込んで、結果を出力します。最後に get_titles() から Array を取得し、Intruder を追加して逆順にしてから、曲数とタイトルを出力します。これらの変更がプレイリストに影響してはいけません。コマンドが add Blue Sky、add Rain、add Blue Sky の場合、次のように出力されます。

Added: Blue Sky
Added: Rain
Already in the playlist: Blue Sky
Songs: 2
Blue Sky, Rain

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

自分で試してみよう

extends Node

func _ready():
	# 提供された入出力コード:そのままにしてください
	var playlist := Playlist.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ", true, 1)
		var title := parts[1]
		if parts[0] == "add":
			if playlist.add(title):
				print("Added: " + title)
			else:
				print("Already in the playlist: " + title)
		elif playlist.remove(title):
			print("Removed: " + title)
		else:
			print("Not found: " + title)
	# 取得したリストを変更しようとするコード
	var titles := playlist.get_titles()
	titles.append("Intruder")
	titles.reverse()
	print("Songs: %d" % playlist.count())
	print(", ".join(playlist.get_titles()))
quiz icon腕試し

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

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

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