Menu
CoddyTech

덕 타이핑

Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 22번째.

덕 타이핑은 객체가 어떤 클래스에 속하는지가 아니라 무엇을 할 수 있는지를 중요하게 여깁니다. 호출하려는 메서드가 객체에 있으면 호출이 작동합니다. 이 이름은 "오리처럼 헤엄치고 오리처럼 꽥꽥거리면 오리다"라는 말에서 유래했습니다.

이 두 클래스는 공통 부모 클래스가 없지만, 둘 다 swim()과 quack()을 가지고 있습니다:

# duck.gd
class_name Duck
extends RefCounted

func swim() -> String:
	return "Duck swimming"

func quack() -> String:
	return "Quack!"
# robot.gd
class_name Robot
extends RefCounted

func swim() -> String:
	return "Robot swimming with propellers"

func quack() -> String:
	return "Robot sound: BEEP BEEP!"

타입이 지정되지 않은 매개변수는 모든 객체를 허용합니다. 함수는 메서드를 호출하고, 각 객체는 자체적으로 메서드를 실행합니다:

func make_it_swim_and_quack(thing) -> void:
	print(thing.swim())
	print(thing.quack())
make_it_swim_and_quack(Duck.new())
make_it_swim_and_quack(Robot.new())
Duck swimming
Quack!
Robot swimming with propellers
Robot sound: BEEP BEEP!

오버라이딩에는 공통 부모 클래스가 필요하지만, 덕 타이핑에는 필요하지 않습니다. 매개변수가 thing: Duck으로 타입 지정되어 있으므로 Robot을 전달하면 구문 분석 오류가 발생합니다.

객체에 메서드가 없으면, 호출은 Invalid call. Nonexistent function 'quack'과 같은 오류를 내며 함수를 중단합니다. 먼저 메서드 이름을 String으로 받는 has_method()로 확인하세요:

var things := [Duck.new(), Rock.new()]
for thing in things:
	if thing.has_method("quack"):
		print(thing.quack())
	else:
		print("This one cannot quack")
Quack!
This one cannot quack

단점: 타입을 사용하면 Godot은 프로그램이 실행되기 전에 잘못된 메서드 이름을 찾아내지만, 덕 타이핑을 사용하면 해당 줄이 실행될 때에야 알게 됩니다. 몇 가지 메서드를 공유하는 서로 관련 없는 클래스의 객체에 사용하세요.

challenge icon

챌린지

쉬움

폭발은 피해를 입을 수 있는 주변의 모든 것을 손상시킵니다. 객체들은 공통 부모 클래스를 공유하지 않습니다. player.gd와 rock.gd는 완성되어 있습니다. Player에는 take_damage(amount)와 status()가 있고, Rock에는 status()만 있습니다.

  • crate.gd에서 Crate에 처음에 false인 broken 변수를 추가하고, 피해량이 10 이상일 때 상자를 부수는 take_damage(amount) 메서드와 Crate: broken 또는 Crate: intact을 반환하는 status()를 구현하세요.
  • explosion.gd에서 정적 메서드 hit_all(things, amount)를 작성하세요. Array에 있는 객체 중 해당 메서드를 가진 모든 객체에 take_damage(amount)를 호출하고, 명중한 객체의 수를 반환합니다.

제공된 코드는 객체 이름(player, crate 또는 rock)이 적힌 한 줄을 읽은 다음, 이어질 폭발 횟수와 각 폭발의 피해량을 읽습니다. 각 폭발이 명중한 객체의 수를 출력한 다음, 모든 객체의 상태를 출력합니다. player crate rock와 피해량이 5와 20인 폭발을 입력하면 다음과 같이 출력됩니다.

Explosion 1 hit 2 objects
Explosion 2 hit 2 objects
Player: 75 HP
Crate: broken
Rock: solid

코드는 crate.gd와 explosion.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

extends Node

func _ready():
	# 제공된 입출력 코드: 그대로 유지하세요
	var things := []
	for word in OS.read_string_from_stdin().split(" "):
		if word == "player":
			things.append(Player.new())
		elif word == "crate":
			things.append(Crate.new())
		else:
			things.append(Rock.new())
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var hits := Explosion.hit_all(things, int(OS.read_string_from_stdin()))
		print("Explosion %d hit %d objects" % [i + 1, hits])
	for thing in things:
		print(thing.status())
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 GDScript 컴파일러