Giriş: Nesne Yönelimli Programlama
Nesne Yönelimli Programlama (Object-Oriented Programming, OOP), yazılım geliştirmede yaygın olarak kullanılan bir programlama paradigmasıdır. OOP, verileri ve davranışları bir araya getirerek "nesneler" oluşturmayı ve bu nesneler arasındaki etkileşimleri düzenlemeyi amaçlar.
JavaScript, başlangıçta prototip tabanlı bir dil olarak tasarlanmıştı, ancak ES6 (ECMAScript 2015) ile birlikte, diğer OOP dillerindekine benzer sınıf sözdizimi eklendi. Bu, JavaScript'te nesne yönelimli programlamayı daha tanıdık ve erişilebilir hale getirdi.
Bu derste, JavaScript'te nesne yönelimli programlamanın temellerini, sınıfların nasıl tanımlandığını ve kullanıldığını, kalıtım, kapsülleme ve polimorfizm gibi OOP kavramlarını öğreneceğiz.
JavaScript'te OOP'nin Evrimi
JavaScript'te nesne yönelimli programlama yaklaşımı zaman içinde evrim geçirmiştir. İşte bu evrimin kısa bir tarihçesi:
1. Nesne Literalleri
JavaScript'te en temel nesne oluşturma yöntemi, nesne literalleridir. Bu, özellikleri ve metodları doğrudan tanımlayan basit bir sözdizimi sunar.
const ogrenci = {
ad: "Ahmet",
soyad: "Yılmaz",
yas: 20,
dersler: ["Matematik", "Fizik", "Programlama"],
tamAd: function() {
return this.ad + " " + this.soyad;
},
derseKayitOl: function(ders) {
this.dersler.push(ders);
return `${this.tamAd()}, ${ders} dersine kaydoldu.`;
}
};
console.log(ogrenci.tamAd());
console.log(ogrenci.derseKayitOl("Kimya"));
console.log(ogrenci.dersler);
2. Kurucu Fonksiyonlar
Benzer nesnelerin birden fazla örneğini oluşturmak için, JavaScript'te geleneksel olarak kurucu fonksiyonlar kullanılır. Bu fonksiyonlar, new
anahtar kelimesi ile çağrıldığında yeni bir nesne örneği oluşturur.
function Ogrenci(ad, soyad, yas) {
this.ad = ad;
this.soyad = soyad;
this.yas = yas;
this.dersler = [];
this.tamAd = function() {
return this.ad + " " + this.soyad;
};
}
Ogrenci.prototype.derseKayitOl = function(ders) {
this.dersler.push(ders);
return `${this.tamAd()}, ${ders} dersine kaydoldu.`;
};
const ogrenci1 = new Ogrenci("Ahmet", "Yılmaz", 20);
const ogrenci2 = new Ogrenci("Ayşe", "Kaya", 22);
console.log(ogrenci1.tamAd());
console.log(ogrenci2.tamAd());
console.log(ogrenci1.derseKayitOl("Matematik"));
console.log(ogrenci2.derseKayitOl("Fizik"));
3. ES6 Sınıfları
ES6 ile birlikte, JavaScript'e sınıf sözdizimi eklendi. Bu, aslında kurucu fonksiyonlar ve prototip kalıtımı üzerine inşa edilmiş bir sözdizimsel şekerdir (syntactic sugar), ancak daha temiz ve anlaşılır bir kod yazmanıza olanak tanır.
class Ogrenci {
constructor(ad, soyad, yas) {
this.ad = ad;
this.soyad = soyad;
this.yas = yas;
this.dersler = [];
}
tamAd() {
return this.ad + " " + this.soyad;
}
derseKayitOl(ders) {
this.dersler.push(ders);
return `${this.tamAd()}, ${ders} dersine kaydoldu.`;
}
}
const ogrenci1 = new Ogrenci("Ahmet", "Yılmaz", 20);
const ogrenci2 = new Ogrenci("Ayşe", "Kaya", 22);
console.log(ogrenci1.tamAd());
console.log(ogrenci2.tamAd());
console.log(ogrenci1.derseKayitOl("Matematik"));
console.log(ogrenci2.derseKayitOl("Fizik"));
Not: ES6 sınıfları, JavaScript'in prototip tabanlı kalıtım modelini değiştirmez, sadece daha temiz bir sözdizimi sunar. Arka planda, sınıflar hala kurucu fonksiyonlar ve prototip kalıtımı kullanır.
ES6 Sınıfları Detaylı İnceleme
ES6 sınıfları, JavaScript'te nesne yönelimli programlama için daha temiz ve anlaşılır bir sözdizimi sunar. Bu bölümde, ES6 sınıflarının temel özelliklerini ve kullanım şekillerini detaylı olarak inceleyeceğiz.
1. Sınıf Tanımlama ve Kurucu
Bir sınıf, class
anahtar kelimesi ile tanımlanır ve genellikle bir kurucu metod (constructor
) içerir. Kurucu, sınıfın yeni bir örneği oluşturulduğunda otomatik olarak çağrılır.
Temel Sınıf Yapısı
Araba
- marka: String
- model: String
- yil: Number
- renk: String
+ constructor(marka, model, yil, renk)
+ bilgileriGoster(): String
+ calistir(): String
class Araba {
constructor(marka, model, yil, renk) {
this.marka = marka;
this.model = model;
this.yil = yil;
this.renk = renk;
this.hiz = 0;
}
bilgileriGoster() {
return `${this.marka} ${this.model} (${this.yil}), ${this.renk}`;
}
calistir() {
return `${this.marka} ${this.model} çalıştırıldı.`;
}
hizlan(artis) {
this.hiz += artis;
return `Hız ${this.hiz} km/s'ye yükseltildi.`;
}
yavasla(azalis) {
this.hiz = Math.max(0, this.hiz - azalis);
return `Hız ${this.hiz} km/s'ye düşürüldü.`;
}
}
const araba1 = new Araba("Toyota", "Corolla", 2020, "Beyaz");
console.log(araba1.bilgileriGoster());
console.log(araba1.calistir());
console.log(araba1.hizlan(50));
console.log(araba1.yavasla(20));
2. Statik Metodlar ve Özellikler
Statik metodlar ve özellikler, sınıfın kendisine ait olup, sınıfın örneklerine (instance) ait değildir. Bunlara, sınıf adı üzerinden erişilir.
class MathUtils {
static PI = 3.14159;
static topla(a, b) {
return a + b;
}
static cikar(a, b) {
return a - b;
}
static carp(a, b) {
return a * b;
}
static bol(a, b) {
if (b === 0) throw new Error("Sıfıra bölme hatası!");
return a / b;
}
static daireAlani(yaricap) {
return this.PI * yaricap * yaricap;
}
}
console.log(MathUtils.topla(5, 3));
console.log(MathUtils.cikar(10, 4));
console.log(MathUtils.carp(2, 3));
console.log(MathUtils.bol(10, 2));
console.log(MathUtils.daireAlani(5));
console.log(MathUtils.PI);
const math = new MathUtils();
Not: Statik özellikler (static fields), ES2022'de standartlaştırıldı. Daha eski tarayıcılarda veya Node.js sürümlerinde, statik özellikleri sınıf tanımının dışında tanımlamanız gerekebilir: MathUtils.PI = 3.14159;
3. Getter ve Setter Metodları
Getter ve setter metodları, sınıf özelliklerine erişimi ve değişikliği kontrol etmenize olanak tanır. Bu, kapsülleme (encapsulation) ilkesini uygulamanın bir yoludur.
class Kisi {
constructor(ad, soyad, yas) {
this._ad = ad;
this._soyad = soyad;
this._yas = yas;
}
get ad() {
return this._ad;
}
get soyad() {
return this._soyad;
}
get tamAd() {
return `${this._ad} ${this._soyad}`;
}
get yas() {
return this._yas;
}
set ad(yeniAd) {
if (yeniAd.length < 2) {
throw new Error("Ad en az 2 karakter olmalıdır.");
}
this._ad = yeniAd;
}
set soyad(yeniSoyad) {
if (yeniSoyad.length < 2) {
throw new Error("Soyad en az 2 karakter olmalıdır.");
}
this._soyad = yeniSoyad;
}
set yas(yeniYas) {
if (yeniYas < 0 || yeniYas > 120) {
throw new Error("Geçersiz yaş değeri.");
}
this._yas = yeniYas;
}
}
const kisi = new Kisi("Ahmet", "Yılmaz", 30);
console.log(kisi.ad);
console.log(kisi.soyad);
console.log(kisi.tamAd);
console.log(kisi.yas);
kisi.ad = "Mehmet";
kisi.yas = 35;
console.log(kisi.tamAd);
console.log(kisi.yas);
try {
kisi.yas = 150;
} catch (error) {
console.error(error.message);
}
İpucu: JavaScript'te, özel (private) özellikleri belirtmek için genellikle özellik adının başına alt çizgi (_
) eklenir. Bu sadece bir konvansiyondur ve gerçek bir erişim kısıtlaması sağlamaz. ES2022'den itibaren, gerçek özel alanlar için #
öneki kullanılabilir.
4. Özel Alanlar (Private Fields)
ES2022 ile birlikte, JavaScript'e gerçek özel alanlar eklendi. Özel alanlar, #
öneki ile tanımlanır ve sınıf dışından erişilemez.
class BankaHesabi {
#hesapNo;
#bakiye;
#pin;
constructor(hesapNo, baslangicBakiye, pin) {
this.#hesapNo = hesapNo;
this.#bakiye = baslangicBakiye;
this.#pin = pin;
}
hesapBilgileri() {
return {
hesapNo: this.#hesapNo,
bakiye: this.#bakiye
};
}
paraYatir(miktar) {
if (miktar <= 0) {
throw new Error("Geçersiz miktar.");
}
this.#bakiye += miktar;
return `${miktar} TL yatırıldı. Yeni bakiye: ${this.#bakiye} TL`;
}
paraCek(miktar, pin) {
if (pin !== this.#pin) {
throw new Error("Geçersiz PIN.");
}
if (miktar <= 0) {
throw new Error("Geçersiz miktar.");
}
if (miktar > this.#bakiye) {
throw new Error("Yetersiz bakiye.");
}
this.#bakiye -= miktar;
return `${miktar} TL çekildi. Yeni bakiye: ${this.#bakiye} TL`;
}
pinDegistir(eskiPin, yeniPin) {
if (eskiPin !== this.#pin) {
throw new Error("Geçersiz PIN.");
}
if (yeniPin.length !== 4 || isNaN(yeniPin)) {
throw new Error("PIN 4 haneli bir sayı olmalıdır.");
}
this.#pin = yeniPin;
return "PIN başarıyla değiştirildi.";
}
}
const hesap = new BankaHesabi("123456789", 1000, "1234");
console.log(hesap.hesapBilgileri());
console.log(hesap.paraYatir(500));
console.log(hesap.paraCek(200, "1234"));
try {
console.log(hesap.paraCek(2000, "1234"));
} catch (error) {
console.error(error.message);
}
try {
console.log(hesap.paraCek(100, "4321"));
} catch (error) {
console.error(error.message);
}
try {
console.log(hesap.#bakiye);
} catch (error) {
console.error("Özel alanlara dışarıdan erişilemez.");
}
Uyarı: Özel alanlar (# önekli) nispeten yeni bir özelliktir ve eski tarayıcılarda desteklenmeyebilir. Geniş tarayıcı desteği için, Babel gibi bir transpiler kullanabilir veya geleneksel alt çizgi (_) konvansiyonunu tercih edebilirsiniz.
Kalıtım (Inheritance)
Kalıtım, nesne yönelimli programlamanın temel kavramlarından biridir. Bir sınıfın, başka bir sınıfın özelliklerini ve metodlarını miras almasına olanak tanır. JavaScript'te kalıtım, extends
anahtar kelimesi ile sağlanır.
Kalıtım Örneği
Arac
- marka: String
- model: String
- yil: Number
+ constructor(marka, model, yil)
+ bilgileriGoster(): String
extends
Otomobil
- kapiSayisi: Number
- yakitTuru: String
+ constructor(marka, model, yil, kapiSayisi, yakitTuru)
+ bilgileriGoster(): String (override)
class Arac {
constructor(marka, model, yil) {
this.marka = marka;
this.model = model;
this.yil = yil;
}
bilgileriGoster() {
return `${this.marka} ${this.model} (${this.yil})`;
}
calistir() {
return `${this.marka} ${this.model} çalıştırıldı.`;
}
}
class Otomobil extends Arac {
constructor(marka, model, yil, kapiSayisi, yakitTuru) {
super(marka, model, yil);
this.kapiSayisi = kapiSayisi;
this.yakitTuru = yakitTuru;
}
bilgileriGoster() {
const temelBilgi = super.bilgileriGoster();
return `${temelBilgi}, ${this.kapiSayisi} kapılı, ${this.yakitTuru}`;
}
bagajAc() {
return `${this.marka} ${this.model} bagajı açıldı.`;
}
}
class Motosiklet extends Arac {
constructor(marka, model, yil, motorHacmi) {
super(marka, model, yil);
this.motorHacmi = motorHacmi;
}
bilgileriGoster() {
const temelBilgi = super.bilgileriGoster();
return `${temelBilgi}, ${this.motorHacmi}cc`;
}
stunYap() {
return `${this.marka} ${this.model} ile stunt yapılıyor!`;
}
}
const arac = new Arac("Genel", "Taşıt", 2020);
const otomobil = new Otomobil("Toyota", "Corolla", 2020, 4, "Benzin");
const motosiklet = new Motosiklet("Honda", "CBR", 2021, 1000);
console.log(arac.bilgileriGoster());
console.log(otomobil.bilgileriGoster());
console.log(motosiklet.bilgileriGoster());
console.log(arac.calistir());
console.log(otomobil.calistir());
console.log(motosiklet.calistir());
console.log(otomobil.bagajAc());
console.log(motosiklet.stunYap());
console.log(otomobil instanceof Otomobil);
console.log(otomobil instanceof Arac);
console.log(otomobil instanceof Motosiklet);
Çoklu Kalıtım ve Mixin'ler
JavaScript, doğrudan çoklu kalıtımı desteklemez (bir sınıf yalnızca bir sınıftan miras alabilir). Ancak, mixin'ler kullanarak benzer bir işlevsellik elde edebilirsiniz. Mixin'ler, sınıflara ek özellikler ve metodlar eklemek için kullanılan nesnelerdir.
const canSwimMixin = {
swim() {
return `${this.constructor.name} yüzüyor.`;
}
};
const canFlyMixin = {
fly() {
return `${this.constructor.name} uçuyor.`;
}
};
class Animal {
constructor(name) {
this.name = name;
}
eat() {
return `${this.name} yemek yiyor.`;
}
}
class Bird extends Animal {
constructor(name) {
super(name);
}
}
class Fish extends Animal {
constructor(name) {
super(name);
}
}
class Duck extends Animal {
constructor(name) {
super(name);
}
}
Object.assign(Bird.prototype, canFlyMixin);
Object.assign(Fish.prototype, canSwimMixin);
Object.assign(Duck.prototype, canFlyMixin, canSwimMixin);
const bird = new Bird("Serçe");
const fish = new Fish("Balık");
const duck = new Duck("Ördek");
console.log(bird.eat());
console.log(bird.fly());
console.log(fish.eat());
console.log(fish.swim());
console.log(duck.eat());
console.log(duck.fly());
console.log(duck.swim());
Polimorfizm (Polymorphism)
Polimorfizm, farklı sınıfların aynı metod adlarını kullanarak farklı davranışlar sergilemesine olanak tanır. JavaScript'te polimorfizm, genellikle metod geçersiz kılma (method overriding) ile uygulanır.
class Sekil {
constructor() {
if (this.constructor === Sekil) {
throw new Error("Sekil sınıfı soyuttur, doğrudan örneği oluşturulamaz.");
}
}
alan() {
throw new Error("Alt sınıflar alan() metodunu uygulamalıdır.");
}
cevre() {
throw new Error("Alt sınıflar cevre() metodunu uygulamalıdır.");
}
bilgileriGoster() {
return `Alan: ${this.alan()}, Çevre: ${this.cevre()}`;
}
}
class Dikdortgen extends Sekil {
constructor(genislik, yukseklik) {
super();
this.genislik = genislik;
this.yukseklik = yukseklik;
}
alan() {
return this.genislik * this.yukseklik;
}
cevre() {
return 2 * (this.genislik + this.yukseklik);
}
bilgileriGoster() {
return `Dikdörtgen - ${super.bilgileriGoster()}, Genişlik: ${this.genislik}, Yükseklik: ${this.yukseklik}`;
}
}
class Daire extends Sekil {
constructor(yaricap) {
super();
this.yaricap = yaricap;
}
alan() {
return Math.PI * this.yaricap * this.yaricap;
}
cevre() {
return 2 * Math.PI * this.yaricap;
}
bilgileriGoster() {
return `Daire - ${super.bilgileriGoster()}, Yarıçap: ${this.yaricap}`;
}
}
class Ucgen extends Sekil {
constructor(a, b, c) {
super();
this.a = a;
this.b = b;
this.c = c;
}
alan() {
const s = (this.a + this.b + this.c) / 2;
return Math.sqrt(s * (s - this.a) * (s - this.b) * (s - this.c));
}
cevre() {
return this.a + this.b + this.c;
}
bilgileriGoster() {
return `Üçgen - ${super.bilgileriGoster()}, Kenarlar: ${this.a}, ${this.b}, ${this.c}`;
}
}
function sekilBilgileriniGoster(sekil) {
if (!(sekil instanceof Sekil)) {
throw new Error("Parametre bir Sekil örneği olmalıdır.");
}
return sekil.bilgileriGoster();
}
const dikdortgen = new Dikdortgen(5, 3);
const daire = new Daire(4);
const ucgen = new Ucgen(3, 4, 5);
console.log(sekilBilgileriniGoster(dikdortgen));
console.log(sekilBilgileriniGoster(daire));
console.log(sekilBilgileriniGoster(ucgen));
try {
const sekil = new Sekil();
} catch (error) {
console.error(error.message);
}
Not: JavaScript'te, Java veya C# gibi dillerdeki gibi gerçek soyut sınıflar veya arayüzler (interfaces) yoktur. Ancak, yukarıdaki örnekte gösterildiği gibi, hata fırlatma ve metod geçersiz kılma ile benzer bir davranış elde edebilirsiniz.
Kapsülleme (Encapsulation)
Kapsülleme, bir sınıfın iç durumunu (özelliklerini) gizleyerek, yalnızca kontrollü bir arayüz (metodlar) aracılığıyla erişime izin verme ilkesidir. JavaScript'te kapsülleme, özel alanlar, closure'lar veya konvansiyonlar (alt çizgi öneki) kullanılarak uygulanabilir.
1. Özel Alanlar ile Kapsülleme
class Kullanici {
#ad;
#soyad;
#email;
#sifre;
constructor(ad, soyad, email, sifre) {
this.#ad = ad;
this.#soyad = soyad;
this.#email = this.#emailDogrula(email) ? email : throw new Error("Geçersiz e-posta adresi.");
this.#sifre = this.#sifreDogrula(sifre) ? sifre : throw new Error("Geçersiz şifre.");
}
#emailDogrula(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
#sifreDogrula(sifre) {
return sifre.length >= 8;
}
get ad() {
return this.#ad;
}
get soyad() {
return this.#soyad;
}
get tamAd() {
return `${this.#ad} ${this.#soyad}`;
}
get email() {
return this.#email;
}
set ad(yeniAd) {
if (yeniAd.length < 2) {
throw new Error("Ad en az 2 karakter olmalıdır.");
}
this.#ad = yeniAd;
}
set soyad(yeniSoyad) {
if (yeniSoyad.length < 2) {
throw new Error("Soyad en az 2 karakter olmalıdır.");
}
this.#soyad = yeniSoyad;
}
set email(yeniEmail) {
if (!this.#emailDogrula(yeniEmail)) {
throw new Error("Geçersiz e-posta adresi.");
}
this.#email = yeniEmail;
}
sifreDegistir(eskiSifre, yeniSifre) {
if (eskiSifre !== this.#sifre) {
throw new Error("Mevcut şifre yanlış.");
}
if (!this.#sifreDogrula(yeniSifre)) {
throw new Error("Yeni şifre en az 8 karakter olmalıdır.");
}
this.#sifre = yeniSifre;
return "Şifre başarıyla değiştirildi.";
}
bilgileriGoster() {
return {
ad: this.#ad,
soyad: this.#soyad,
email: this.#email
};
}
girisYap(email, sifre) {
if (email === this.#email && sifre === this.#sifre) {
return "Giriş başarılı.";
} else {
return "E-posta veya şifre yanlış.";
}
}
}
const kullanici = new Kullanici("Ahmet", "Yılmaz", "ahmet@example.com", "12345678");
console.log(kullanici.tamAd);
console.log(kullanici.email);
kullanici.ad = "Mehmet";
console.log(kullanici.tamAd);
console.log(kullanici.bilgileriGoster());
console.log(kullanici.girisYap("ahmet@example.com", "12345678"));
console.log(kullanici.girisYap("ahmet@example.com", "yanlissifre"));
console.log(kullanici.sifreDegistir("12345678", "yenisifre123"));
try {
kullanici.email = "gecersiz-email";
} catch (error) {
console.error(error.message);
}
try {
console.log(kullanici.#sifre);
} catch (error) {
console.error("Özel alanlara dışarıdan erişilemez.");
}
2. Closure ile Kapsülleme
Özel alanlar henüz desteklenmeyen ortamlarda, closure'lar kullanarak kapsülleme sağlayabilirsiniz.
function createKullanici(ad, soyad, email, sifre) {
let _ad = ad;
let _soyad = soyad;
let _email = email;
let _sifre = sifre;
function emailDogrula(email) {
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return regex.test(email);
}
function sifreDogrula(sifre) {
return sifre.length >= 8;
}
return {
getAd: function() {
return _ad;
},
getSoyad: function() {
return _soyad;
},
getTamAd: function() {
return `${_ad} ${_soyad}`;
},
getEmail: function() {
return _email;
},
setAd: function(yeniAd) {
if (yeniAd.length < 2) {
throw new Error("Ad en az 2 karakter olmalıdır.");
}
_ad = yeniAd;
},
setSoyad: function(yeniSoyad) {
if (yeniSoyad.length < 2) {
throw new Error("Soyad en az 2 karakter olmalıdır.");
}
_soyad = yeniSoyad;
},
setEmail: function(yeniEmail) {
if (!emailDogrula(yeniEmail)) {
throw new Error("Geçersiz e-posta adresi.");
}
_email = yeniEmail;
},
sifreDegistir: function(eskiSifre, yeniSifre) {
if (eskiSifre !== _sifre) {
throw new Error("Mevcut şifre yanlış.");
}
if (!sifreDogrula(yeniSifre)) {
throw new Error("Yeni şifre en az 8 karakter olmalıdır.");
}
_sifre = yeniSifre;
return "Şifre başarıyla değiştirildi.";
},
bilgileriGoster: function() {
return {
ad: _ad,
soyad: _soyad,
email: _email
};
},
girisYap: function(email, sifre) {
if (email === _email && sifre === _sifre) {
return "Giriş başarılı.";
} else {
return "E-posta veya şifre yanlış.";
}
}
};
}
const kullanici = createKullanici("Ahmet", "Yılmaz", "ahmet@example.com", "12345678");
console.log(kullanici.getTamAd());
console.log(kullanici.getEmail());
kullanici.setAd("Mehmet");
console.log(kullanici.getTamAd());
console.log(kullanici.bilgileriGoster());
console.log(kullanici.girisYap("ahmet@example.com", "12345678"));
Alıştırmalar
- Bir
Hesap
sınıfı oluşturun. Bu sınıf, hesap numarası, sahibi ve bakiye gibi özelliklere sahip olmalıdır. Para yatırma, para çekme ve bakiye sorgulama gibi metodlar ekleyin. Özel alanlar kullanarak kapsülleme uygulayın. Hesap
sınıfından miras alan VadesizHesap
ve VadeliHesap
alt sınıfları oluşturun. VadeliHesap
sınıfı, vade süresi ve faiz oranı gibi ek özelliklere sahip olmalıdır. Her iki sınıf için de para çekme işlemini farklı şekilde uygulayın (polimorfizm).- Bir
Banka
sınıfı oluşturun. Bu sınıf, hesapları yönetmeli ve hesap açma, hesap kapatma, para transferi gibi işlemleri gerçekleştirmelidir. - Bir
Sekil
sınıfı ve bu sınıftan miras alan Dikdortgen
, Daire
ve Ucgen
sınıfları oluşturun. Her sınıf, alan ve çevre hesaplama metodlarını uygulamalıdır. Statik bir metod ekleyerek, iki şeklin alanını karşılaştıran bir fonksiyon yazın. - Bir
Canli
sınıfı ve bu sınıftan miras alan Hayvan
ve Bitki
sınıfları oluşturun. Hayvan
sınıfından miras alan Memeli
, Kus
ve Balik
sınıfları oluşturun. Her sınıf için uygun özellikler ve metodlar ekleyin. Mixin'ler kullanarak CanYuzen
ve CanUcan
gibi yetenekler ekleyin.
Bu derste, JavaScript'te nesne yönelimli programlamanın temellerini ve ES6 sınıflarını inceledik:
- JavaScript'te OOP'nin Evrimi: Nesne literalleri, kurucu fonksiyonlar ve ES6 sınıfları.
- ES6 Sınıfları:
class
anahtar kelimesi, constructor
metodu, sınıf metodları, statik metodlar ve özellikler, getter ve setter metodları, özel alanlar. - Kalıtım (Inheritance):
extends
anahtar kelimesi, super
anahtar kelimesi, metod geçersiz kılma (method overriding), mixin'ler. - Polimorfizm (Polymorphism): Farklı sınıfların aynı metod adlarını kullanarak farklı davranışlar sergilemesi.
- Kapsülleme (Encapsulation): Özel alanlar, closure'lar ve konvansiyonlar ile veri gizleme ve kontrollü erişim.
ES6 sınıfları, JavaScript'te nesne yönelimli programlama için daha temiz ve anlaşılır bir sözdizimi sunar. Ancak, arka planda hala JavaScript'in prototip tabanlı kalıtım modeli kullanılır.
Nesne yönelimli programlama, kodunuzu daha modüler, yeniden kullanılabilir ve bakımı kolay hale getirmenize yardımcı olur. Özellikle büyük ve karmaşık uygulamalarda, OOP prensiplerini uygulamak, kodunuzu daha iyi organize etmenize ve yönetmenize olanak tanır.
Bir sonraki derste, modern JavaScript'in diğer önemli özelliklerinden biri olan hata yönetimi ve asenkron programlama konularını daha derinlemesine inceleyeceğiz.