Menu
CoddyTech

Duck Typing

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GDScript di Coddy. Pelajaran 22 dari 65.

Duck typing memperhatikan apa yang bisa dilakukan sebuah object, bukan class yang dimilikinya. Jika object tersebut memiliki method yang kamu panggil, pemanggilan itu akan berhasil. Istilah ini berasal dari ungkapan, "jika sesuatu berenang seperti bebek dan berkwek seperti bebek, berarti itu bebek".

Kedua class ini tidak memiliki parent yang sama, tetapi keduanya memiliki swim() dan 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!"

Parameter tanpa tipe dapat menerima object apa pun. Fungsi memanggil method-nya, lalu setiap object menjalankan implementasinya sendiri:

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!

Overriding membutuhkan class induk yang sama, sedangkan duck typing tidak. Dengan parameter bertipe thing: Duck, meneruskan Robot akan menghasilkan parse error.

Jika sebuah object tidak memiliki method tersebut, pemanggilan itu menghentikan fungsi dengan error seperti Invalid call. Nonexistent function 'quack'. Periksa terlebih dahulu dengan has_method(), yang menerima nama method sebagai String:

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

Harganya: dengan tipe data, Godot menemukan nama method yang salah sebelum program dijalankan; dengan duck typing, kamu baru mengetahuinya saat baris tersebut dijalankan. Gunakan ini untuk object dari class yang tidak berkaitan tetapi memiliki beberapa method yang sama.

challenge icon

Tantangan

Mudah

Ledakan merusak semua hal di sekitarnya yang bisa menerima damage. Object-object tersebut tidak memiliki parent class yang sama. player.gd dan rock.gd sudah selesai: Player memiliki take_damage(amount) dan status(), sedangkan Rock hanya memiliki status().

  • Di crate.gd, beri Crate variabel broken yang dimulai dengan nilai false, method take_damage(amount) yang merusak peti saat jumlah damage mencapai 10 atau lebih, dan status() yang mengembalikan Crate: broken atau Crate: intact.
  • Di explosion.gd, tulis fungsi statis hit_all(things, amount). Fungsi ini memanggil take_damage(amount) pada setiap object di dalam Array yang memiliki method tersebut, lalu mengembalikan jumlah object yang terkena.

Kode yang disediakan membaca satu baris nama object (player, crate atau rock), lalu jumlah ledakan berikutnya dan damage dari setiap ledakan. Kode ini mencetak jumlah object yang terkena setiap ledakan, lalu status setiap object. Untuk player crate rock dan ledakan dengan damage 5 dan 20, kode ini mencetak:

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

Tulis kodemu di crate.gd dan explosion.gd. main.gd berisi kode input/output yang disediakan dan tidak boleh diedit.

Coba sendiri

extends Node

func _ready():
	# Kode input/output yang disediakan: biarkan apa adanya
	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 iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler GDScript online