13. Sınıflar

Burada ECMAScript 6 sınıflarını tanıtıyoruz. Öncelikle, fonksiyonların zaten sınıflar olarak kullanılabileceğini gösteriyoruz.
13.1. [class-00] betiği
Aşağıdaki komut dosyası, fonksiyonların alışılmadık bir kullanımını göstermektedir. Burada fonksiyonlar nesne olarak kullanılmaktadır.
''use strict';
// bir işlev nesne olarak kullanılabilir
// boş bir kabuk
function f() {
}
// dışarıdan özellikler atanan
f.prop1 = "val1";
f.show = function () {
console.log(this.prop1);
}
// f işlevinin kullanımı
f.show();
// bir sınıf gibi çalışan g işlevi
function g() {
this.prop2 = "val2";
this.show = function () {
console.log(this.prop2);
}
}
// [new] ile fonksiyonun örneklenmesi
new g().show();
Açıklamalar
- 5-7. satırlar: f işlevinin gövdesi hiçbir özellik tanımlamaz;
- 9-12. satırlar: f işlevine dışarıdan özellikler atanır;
- 14. satır: f fonksiyonunun (nesnesinin) kullanımı. [f()] değil, sadece [f] yazıldığına dikkat edin. Burada bir nesnenin gösterimi kullanılmaktadır;
- satır 17-22: [g] fonksiyonu, sanki özellikleri ve yöntemleri olan bir sınıfmış gibi tanımlanıyor;
- 24. satır: [g] işlevi, [new g()] tarafından örneklenir;
Çalıştırma sonuçları
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-00.js"
val1
val2
ES6, artık sınıflar elde etmek için işlevlerden geçmek zorunda kalmamamızı sağlayan sınıf kavramını getirmiştir.
13.2. [class-01] komut dosyası
[class-01] komut dosyası, [Personne] sınıfını sunar:
// sınıf
class Personne {
// yapıcı
constructor(nom, prénom, âge) {
this.nom = nom;
this.prénom = prénom;
this.âge = âge;
}
// alıcı ve ayarlayıcılar
get nom() {
return this._nom;
}
set nom(value) {
this._nom = value;
}
get prénom() {
return this._prénom;
}
set prénom(value) {
this._prénom = value;
}
get âge() {
return this._âge;
}
set âge(value) {
this._âge = value;
}
// toString'ten JSON'e
toString() {
return JSON.stringify(this);
}
}
// sınıf çağrısı
function main() {
const personne = new Personne("Poirot", "Hercule", 66);
console.log("personne=", personne.toString(), typeof (personne), personne instanceof (Personne));
}
// main çağrısı
main();
Açıklamalar
- 2. satır: [class] anahtar sözcüğü bir sınıfı belirtir;
- 5-9. satırlar: [constructor] anahtar sözcüğü, sınıfın oluşturucusunu belirtir. En fazla bir tane olabilir. Sınıfın bir örneğini oluşturmak ve başlatmak için kullanılır. [nom, prénom, âge] özelliklerinin tanımlanmadığına dikkat edin;
- 11-36. satırlar: sınıfın özellikleri. Burada, 4. sayfadaki nesneler bölümünde (4) daha önce gördüğümüz unsurlar yer almaktadır. Yalnızca sözdizimi farklıdır;
- 41. satır: [Personne] türünde bir nesnenin oluşturulması. Bundan sonra [personne] nesnesi, bir literal nesne gibi kullanılır. [typeof (personne)]'in değeri "object"tir ve [personne instanceof (Personne)] ifadesi doğrudur. Dolayısıyla, bir sınıf örneğinin tam türünü belirlemek mümkündür;
Çalıştırma sonuçları
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-01.js"
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66} object true
13.3. [class-02] komut dosyası
Bu komut dosyası, [extends] anahtar sözcüğüyle bir sınıftan miras alınabileceğini göstermektedir.
Öncelikle, [Personne] sınıfını bir [Personne.js] modülünde izole ediyoruz:
// sınıf
class Personne {
// yapıcı
constructor(nom, prénom, âge) {
this.nom = nom;
this.prénom = prénom;
this.âge = âge;
}
// alıcı ve ayarlayıcılar
get nom() {
return this._nom;
}
set nom(value) {
this._nom = value;
}
get prénom() {
return this._prénom;
}
set prénom(value) {
this._prénom = value;
}
get âge() {
return this._âge;
}
set âge(value) {
this._âge = value;
}
// toString'ten JSON'e
toString() {
return JSON.stringify(this);
}
}
// sınıfın dışa aktarımı
export default Personne;
- 39. satır: Komut dosyalarının bu sınıfı içe aktarabilmesi için [Personne] sınıfını dışa aktarıyoruz;
[class-02] komut dosyası, [Personne] sınıfından türetilen [Enseignant] sınıfını oluşturur:
// ithalatlar
import Personne from './Personne';
// sınıf
class Enseignant extends Personne {
// yapıcı
constructor(nom, prénom, âge, discipline) {
super(nom, prénom, âge);
this.discipline = discipline;
}
// alıcı ve ayarlayıcılar
get discipline() {
return this._discipline;
}
set discipline(value) {
this._discipline = value;
}
}
// sınıf çağrısı
function main() {
const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}
// main çağrısı
main();
Açıklamalar
- 2. satır: [class-02] ile aynı klasörde bulunan [Personne.js] modülünden [Personne] sınıfı içe aktarılır;
- 5. satır: [Enseignant] sınıfı, [extends] anahtar sözcüğüyle [Personne] sınıfını genişletir (bu sınıftan miras alır): bu sınıfa, ilgili getter/setter yöntemleriyle birlikte [_discipline] özelliğini ekler;
- 8-11. satırlar: [Enseignant] sınıfının oluşturucusu, sınıfın dört özelliğini başlatmak için dört değer alır;
- 9. satır: [super] anahtar sözcüğü, üst sınıf olan [Personne] sınıfının oluşturucusunu çağırır; bu da [_nom, _prénom, _âge] özelliklerini başlatır;
- 10. satır: [Enseignant] sınıfına ait olan [_discipline] özelliği başlatılır;
- 14-19. satırlar: [_discipline] özelliğinin getter ve setter yöntemleri;
- 25. satır: [Enseignant] türünde bir nesne oluşturulur;
- 26. satır: [enseignant.toString()] yöntemi kullanılır. [Enseignant] sınıfında bu yöntem yoktur. Bu durumda, otomatik olarak üst sınıfının yöntemi kullanılır. Bu yöntem, [JSON.stringify(this)] ifadesini, burada [this]'in bir [Enseignant] nesnesi olacağı ve bir [Personne] nesnesi olmayacağı şekilde işler. Buna nesne yönelimli programlamada sınıf polimorfizmi denir. Nesne yönelimli bir dil olmayan JavaScript için oldukça büyük bir kavramdır. Yine de JavaScript burada kendisinden beklenen şeyi yapar: bir öğretmeni doğru şekilde görüntüler;
Çalıştırma sonuçları şöyledir:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-02.js"
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true
- 2. satır: JavaScript, [enseignant] değişkeninin [Enseignant] türünde olduğunu doğru bir şekilde tanır;
13.4. [class-03] komut dosyası
[class-03] komut dosyası, bir alt sınıfın üst sınıfının özelliklerini ve yöntemlerini yeniden tanımlayabileceğini göstermektedir. Burada, üst sınıfın [toString] yöntemini yeniden tanımlıyoruz:
// ithalatlar
import Personne from './Personne';
// sınıf
class Enseignant extends Personne {
// yapıcı
constructor(nom, prénom, âge, discipline) {
super(nom, prénom, âge);
this.discipline = discipline;
}
// alıcı ve ayarlayıcılar
get discipline() {
return this._discipline;
}
set discipline(value) {
this._discipline = value;
}
// toString'in yeniden tanımlanması
toString() {
return "[Enseignant]" + JSON.stringify(this);
}
}
// sınıfın çağrılması
function main() {
const enseignant = new Enseignant("Poirot", "Hercule", 66, "détective");
console.log("enseignant=", enseignant.toString(), typeof (enseignant), enseignant instanceof Enseignant);
}
// main işlevinin çağrılması
main();
Çalıştırma sonuçları şöyledir:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-03.js"
enseignant= [Enseignant]{"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object true
13.5. [class-04] komut dosyası
[class-04] komut dosyası, polimorfizmin işleyişini bir kez daha göstermektedir: Bir fonksiyonun [Personne] türünde bir biçimsel parametre beklediği yerde, [Enseignant] gibi türetilmiş bir tür geçirilebilir. Nitekim, türetme sayesinde [Enseignant] türü, [Personne] türünün tüm özelliklerine sahiptir.
Öncelikle, [Enseignant] türünü [Enseignant.js] modülüne ayırıyoruz:
// ithalatlar
import Personne from './Personne';
// sınıf
class Enseignant extends Personne {
// yapıcı
constructor(nom, prénom, âge, discipline) {
super(nom, prénom, âge);
this.discipline = discipline;
}
// alıcı ve ayarlayıcılar
get discipline() {
return this._discipline;
}
set discipline(value) {
this._discipline = value;
}
}
// sınıfın dışa aktarımı
export default Enseignant;
- 24. satır: [Enseignant] sınıfı, diğer komut dosyalarının bu sınıfı içe aktarabilmesi için dışa aktarılır;
[class-04] betiği şu şekildedir:
// ithalatlar
import Enseignant from './Enseignant';
import Personne from './Personne';
// bir kişiyi parametre olarak kabul eden işlev
function show(personne) {
// her durumda
console.log("paramètre=", personne.toString(), typeof (personne));
// Kişi örneği
if (personne instanceof Personne) {
console.log("personne=", personne.toString());
}
// Öğretmen nesnesi
if (personne instanceof Enseignant) {
console.log("enseignant=", personne.toString());
}
}
// bir öğretmenle show çağrısı
show(new Enseignant("Poirot", "Hercule", 66, "détective"));
show(new Personne("Marple", "Miss", 70));
- 6. satır: [show] işlevi, [Personne] türünü veya bunun türevlerini bekler;
- 8. satır: parametrenin dizesi ve türü görüntülenir. Burada [object] değerini göreceğiz;
- 10-16. satırlar: Bunun bir [Personne] türü mü yoksa bir [Enseignant] türü mü olduğunu belirleyebiliriz. Dolayısıyla kod, parametrenin gerçek türüne göre uyarlanabilir;
Çalıştırma sonuçları şöyledir:
[Running] C:\myprograms\laragon-lite\bin\nodejs\node-v10\node.exe -r esm "c:\Data\st-2019\dev\es6\javascript\classes\class-04.js"
paramètre= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"} object
personne= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
enseignant= {"_nom":"Poirot","_prénom":"Hercule","_âge":66,"_discipline":"détective"}
paramètre= {"_nom":"Marple","_prénom":"Miss","_âge":70} object
personne= {"_nom":"Marple","_prénom":"Miss","_âge":70}
- 4. ve 6. satırlar: JavaScript, sınıf örneklerinin türünü doğru bir şekilde tanıyor;