덕 타이핑
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은 프로그램이 실행되기 전에 잘못된 메서드 이름을 찾아내지만, 덕 타이핑을 사용하면 해당 줄이 실행될 때에야 알게 됩니다. 몇 가지 메서드를 공유하는 서로 관련 없는 클래스의 객체에 사용하세요.
챌린지
쉬움폭발은 피해를 입을 수 있는 주변의 모든 것을 손상시킵니다. 객체들은 공통 부모 클래스를 공유하지 않습니다. 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())
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러