Verse’te, başka bir sınıfın tanımını, bu sınıfa alan ve yöntemler ekleyerek veya bu sınıfın alan ve yöntemlerini değiştirerek genişleten bir sınıf oluşturabilirsin. Buna genellikle alt sınıf oluşturma veya devralma denir, çünkü bir sınıf diğer sınıftan tanımlar devralır.
Bir alt sınıf oluşturma örneği olarak sınıf tasarlayıcı cihazına bakalım. Sınıf Tasarlayıcı cihazıyla, oyuncu karakterleri için, tank veya saniye başına hasar (Damage per Second, DPS) karakteri gibi, bir karakter sınıfına özgü öznitelik ve envanterleri tanımlamana imkan tanıyan karakter sınıfları oluşturabilirsin.
![]() |
![]() |
| Sınıf Tasarlayıcı cihazıyla oluşturulmuş DPS karakter sınıfı | Sınıf Tasarlayıcı cihazıyla oluşturulmuş tank karakter sınıfı |
Verse’te, bir tank sınıfı ile dps sınıfını şu şekilde oluşturabilirsin:
tank := class():
StartingShields : int
MaxShields : int
AllowOvershield : logic
DamageReduction : int
dps := class():
StartingShields : int
MaxShields : int
AllowOvershield : logic
MovementMultiplier : float
Bu iki sınıftaki bazı alanlar aynı olduğundan sınıfların paylaştığı özellik ve davranışları içeren bir üst sınıf kullanarak tekrarı azaltabilirsin. Bu üst sınıfa player_character adını verelim ve tank ile dpsi onun alt sınıfları yapalım:
player_character := class():
StartingShields : int
MaxShields : int
AllowOvershield : logic
dps := class(player_character):
MovementMultiplier : float
tank := class(player_character):
DamageReduction : int
tank ve dps sınıfları player_characterın alt sınıfları olduğundan bunlar otomatik olarak player_character sınıfının alanlarını ve yöntemlerini devralırlar, dolayısıyla yalnızca bu sınıfta nelerin üst sınıftakinden farklı olduğunu belirlemen yeterlidir.
Örneğin, dps sınıfı yalnızca Movement Multiplier alanını, tank sınıfı ise yalnızca DamageReduction alanını eklemektedir. Bu düzen, iki sınıfın paylaştığı davranışları sonradan değiştirmek istemen halinde faydalıdır çünkü söz konusu davranışları yalnızca üst sınıfta değiştirmen gerekir.
Verse ile, tank ve dps alt sınıflarını birbirinden ayırt etmek için bunlara yöntemler eklemek suretiyle daha fazla değişiklik ekleyebilirsin.
Alt sınıf oluşturmanın bir başka faydalı etkisi de bir üst sınıf ile onun alt sınıfları arasındaki ilişkiyi kullanabilecek olmandır. Devralma nedeniyle, bir tank örneği özelleştirilmiş bir player_character, aynı şekilde bir dps örneği de özelleştirilmiş bir player_character olup buna [is-a ilişkisi adı verilir. tank ile dpsin her ikisi de aynı üst sınıfın alt sınıfları olduğundan ve paylaştıkları üst sınıflarından farklı şekillerde ayrıldıklarından tankın dps ile bir ilişkisi yoktur.
Geçersiz Kılma Belirleyicisi
Başlangıç değerleri olan sınıf örnekleri oluşturmak için yaygın olarak kullanılan uygulamalardan biri, örnekleri oluşturan bir işleve sahip olmaktır. Örneğin:
CreateDPSPlayerCharacter() : dps =
return dps{StartingShields := 0, MaxShields := 0, AllowOvershield := false, MovementMultiplier := 1.9}
CreateTankPlayerCharacter() : tank =
return tank{StartingShields := 100, MaxShields := 200, AllowOvershield := true, DamageReduction := 50}
CreateTankPlayerCharacter() ve CreateDPSPlayerCharacter() işlevleri, uygun başlangıç değerleri olan örnekleri oluşturur. Alternatif olarak, üst sınıftan alanları geçersiz kılabilir ve başlangıç değerleri atayabilirsin, böylece bir örnek oluştururken çok fazla başlangıç değeri belirtmen gerekmez.
Örneğin, önceki bölümde yer alan tank sınıfı, alanlardaki geçersiz kılmalarla şu şekilde görünebilir:
tank := class(player_character):
StartingShields<override> : int = 100
MaxShields<override> : int = 200
AllowOvershield<override> : logic = true
DamageReduction : int = 50
CreateTankPlayerCharacter() : tank =
return tank{}
Alt sınıftaki yöntemleri de geçersiz kılabilirsin. Bunun sonucunda geçersiz kılma yönteminin kullanılabildiği her yerde bu yöntemi kullanabilirsin. Bu özelliğin anlamı şudur:
- Yöntem en azından geçersiz kılınan yöntem tarafından kabul edilen herhangi bir bağımsız değişkeni kabul etmelidir. Bu nedenle parametre türü, geçersiz kılınan fonksiyonun parametre türünün bir üst türü olmalıdır.
- Yöntem, geçersiz kılınan yöntemin alamayacağı bir değer döndürmemelidir. Bu nedenle dönüş türü, geçersiz kılınan yöntemin dönüş türünün bir alt türü olmalıdır.
- Yöntem, geçersiz kılınan yöntemden daha fazla efekte sahip olmamalıdır. Bu nedenle efekt belirticisi, geçersiz kılınan yöntemin efekt belirticisinin bir alt türü olmalıdır.
Super
Self’e benzer şekilde, alan ve yöntemlerin üst sınıf uygulamalarına erişmek için (super:)ı kullanabilirsin. (super:)ı kullanabilmek için, alan veya yöntemin üst sınıf tanımında uygulanmış olması gerekir.
pet := class():
Sound : string
Speak() : void =
Log(Sound)
cat := class(pet):
Sound<override> : string = "Meow"
Speak<override>() : void =
(super:)Speak() # "Meow" Çıktı Günlüğünde görünür
Log("Purr") # "Purr" Çıktı Günlüğünde görünür
Bir Alt Sınıf Gövdesinde Blok İfadeleri
Bir alt sınıf gövdesindeki tüm block ifadeleri, üst sınıf gövdesinde belirlenen block ifadelerinden sonra yürütülecektir. Örneğin, aşağıdaki kodda, MrSnuffles adlı cat sınıfının örneği oluşturulduğunda, önce Speak(), ardından Purr() yürütülür.
pet := class():
Speak() : void =
...
block:
Speak()
cat := class(pet):
Purr() : void =
...
block:
Purr()
MrSnuffles := cat{}
Soyut Belirleyici
Bir sınıf veya sınıf yöntemi abstract belirleyiciye sahip olduğunda, sınıfın bir örneğini oluşturamazsın. Soyut sınıfların, kısmi uygulamalı bir üst sınıf veya ortak bir arayüz olarak kullanılması amaçlanmıştır. Bu anlayış, bir üst sınıfın örneklerine sahip olmanın mantıklı olmadığı, ancak özellikleri ve davranışları benzer sınıflar genelinde tekrar etmek istemediğin durumlar için faydalıdır.
Aşağıdaki örnekte, evcil hayvan soyut bir kavram olduğundan evcil hayvan sınıfının bir örneği yeterince belirli değildir, ancak bir evcil kedi veya evcil köpek mantıklıdır, dolayısıyla bu alt sınıflar soyut olarak işaretlenmez.
pet := class<abstract>():
Speak() : void
cat := class(pet):
Speak() : void =
...
dog := class(pet):
Speak() : void =
...

