Menu
CoddyTech

Sanal Metotlara Giriş

Coddy'nin GDScript Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 31 / 65.

Python'da __init__ ve __str__ gibi sihirli metotlar vardır; bunları dil sizin için çağırır. Godot'taki karşılığı sanal metottur: adı sabit olan, alt çizgiyle başlayan ve sınıfınızda tanımladığınız, Godot'un da doğru zamanda çağırdığı bir metot. Şimdiye kadar ikisini kullandınız:

  • _init(), new() nesneyi oluşturduğunda, new()'e verilen argümanlarla çalışır.
  • _ready(), bir düğüm sahne ağacına girdiğinde çalışır; main.gd burada başlar.

Diğerleri arasında, bir nesne yazdırıldığında çağrılan _to_string(), bir for döngüsünün nesne üzerinde gezinmesini sağlayan yineleyici yöntemleri (her ikisi de sonraki derslerde) ve motordan olaylar alan _notification() bulunur. Bunlardan biri olan NOTIFICATION_PREDELETE, nesne silinmeden hemen önce gelir:

# torch.gd
class_name Torch
extends RefCounted

var label: String

func _init(new_label: String = "Torch") -> void:
	label = new_label
	print(label, " lit")

func _notification(what: int) -> void:
	if what == NOTIFICATION_PREDELETE:
		print(label, " burned out")
# main.gd
var torch := Torch.new("Hall torch") # Koridor meşalesi yandı
torch = null # Koridor meşalesi söndü

Bir RefCounted nesnesi, artık hiçbir değişken ona başvurmadığı anda silinir; bu nedenle torch = null bildirimi hemen gönderir. _init() içindeki varsayılan değer, new() işlevinin bağımsız değişkenini isteğe bağlı hâle getirir: Torch.new(), Torch adlı bir meşale oluşturur.

Python ayrıca + için __add__ ve == için __eq__ gibi operatörler için sihirli metotlar kullanır. GDScript'te operatör aşırı yüklemesi yoktur: potion_a + potion_b bir hatadır. Bunun yerine bir metot yazın:

# potion.gd
class_name Potion
extends RefCounted

var power: int

func _init(start_power: int) -> void:
	power = start_power

func combined(other: Potion) -> Potion:
	return Potion.new(power + other.power)

potion_a.combined(potion_b) yeni bir iksir döndürür ve her iki özgün iksiri de değiştirmeden bırakır. İki nesne arasındaki ==, değerlerinin eşleşip eşleşmediğini değil, her iki tarafın da aynı nesne olup olmadığını kontrol eder: Potion.new(5) == Potion.new(5) sonucu false olur. Değerleri karşılaştırmanız gerektiğinde equals(other) gibi bir yöntem yazın.

challenge icon

Görev

Kolay

counter.gd dosyasında Counter sınıfını yaz:

  • _init(start = 0, step_size = 1), başlangıç değerini value değişkenine ve adım büyüklüğünü step değişkenine kaydeder. Varsayılan değerler zaten imzada bulunduğundan Counter.new(), Counter.new(5) ve Counter.new(5, 2) ifadelerinin tümü çalışır.
  • tick(), step değerini value değerine ekler.
  • plus(other), GDScript'in tanımlamanıza izin vermediği + operatörünün yerine geçer: her iki değerin toplamına eşit değere ve bu sayacın adımına sahip yeni bir Counter döndürür. Sayaçların hiçbiri değişmez.
  • equals(other), her iki sayacın da değeri aynı olduğunda true döndürür.

Sağlanan kod, sayaçları a ve b oluşturan iki satırı (boş bir satır, START veya START STEP) ve ardından a ile b'ye kaç kez tik uygulanacağını belirten bir satırı okur. Her iki sayacı, toplamlarını, değerlerinin eşit olup olmadığını ve a == b olup olmadığını yazdırır. 5, 2 3 ve 3 1 satırları için şu çıktıyı verir:

a: 8 (step 1)
b: 5 (step 3)
a plus b: 13 (step 1)
same value: false
same object: false

Kodunu counter.gd dosyasına yaz. main.gd, sağlanan giriş/çıkış kodunu içerir ve düzenlenemez.

Kendin dene

extends Node

func _ready():
	# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
	var a := make_counter(OS.read_string_from_stdin())
	var b := make_counter(OS.read_string_from_stdin())
	var ticks := OS.read_string_from_stdin().split(" ")
	for i in int(ticks[0]):
		a.tick()
	for i in int(ticks[1]):
		b.tick()
	print("a: %d (step %d)" % [a.value, a.step])
	print("b: %d (step %d)" % [b.value, b.step])
	var total := a.plus(b)
	print("a plus b: %d (step %d)" % [total.value, total.step])
	print("same value: %s" % a.equals(b))
	print("same object: %s" % (a == b))

func make_counter(line: String) -> Counter:
	var parts := line.split(" ", false)
	if parts.is_empty():
		return Counter.new()
	if parts.size() == 1:
		return Counter.new(int(parts[0]))
	return Counter.new(int(parts[0]), int(parts[1]))
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online GDScript derleyicisi