İçeriğe geç
Educora
İleri18 dk13 / 27

Sınıflar ve kalıtım

Aynı yapıdaki nesneleri sınıflarla oluştur: yapıcı, metotlar, `extends` ile kalıtım, gizli alanlar, getter'lar ve statik metotlar.

Kendini test et
Bu derste öğreneceklerin
  • constructor ve metotları olan bir sınıf yazıp new ile örnekler oluşturmak
  • extends ve super ile bir sınıfı genişletmek ve metodu yeniden tanımlamak
  • # gizli alanları, getter/setter'ları ve static metotları kullanmak

Bir bankanın binlerce müşterisi vardır ve her hesabın yapısı aynıdır: sahibi, bakiyesi, para yatırma ve çekme işlemleri. Her hesap nesnesini elle yazmak hem uzun sürer hem de hataya açıktır. Sınıf (class), nesneler için bir plandır: yapıyı bir kez tarif eder, sonra ondan istediğin kadar nesne oluşturursun.

Sınıf, yapıcı ve metotlar

Sınıf class anahtar kelimesiyle tanımlanır ve adı büyük harfle başlar. Özel constructor metodu her yeni nesne oluşturulduğunda kendiliğinden çağrılır ve nesnenin özelliklerini belirler. this, oluşturulan o nesneyi gösterir. Nesneler new operatörüyle oluşturulur; bir sınıftan oluşturulan nesneye örnek (instance) denir.

JavaScript
class BankAccount {
  constructor(owner, balance = 0) {
    this.owner = owner;
    this.balance = balance;
  }

  deposit(amount) {
    this.balance += amount;
    return this.balance;
  }

  describe() {
    return `${this.owner}: ${this.balance} AZN`;
  }
}

const aysel = new BankAccount('Aysel', 100);
const murad = new BankAccount('Murad');

aysel.deposit(50);
console.log(aysel.describe());
console.log(murad.describe());
console.log(aysel instanceof BankAccount);
▸ Beklenen çıktı
Aysel: 150 AZN
Murad: 0 AZN
true
İki örneğin metotları ortak, verileri ise ayrıdır: Aysel'in hesabındaki işlem Murad'ın bakiyesini etkilemez.

Kalıtım: extends ve super

Birikim hesabı normal bir hesabın yapabildiği her şeyi yapar, üstelik faiz de kazanır. Kodu tekrarlamamak için yeni sınıfı extends ile eskisinden türetiriz: üst sınıfın tüm metotlarını miras alır. Alt sınıfın yapıcısında önce super(...) çağrılmalıdır; bu, üst sınıfın yapıcısını çalıştırır. Aynı adlı bir metot üst sınıfın metodunu geçersiz kılar (override), super.describe() ise üst sınıfın sürümünü çağırır.

JavaScript
class BankAccount {
  constructor(owner, balance = 0) {
    this.owner = owner;
    this.balance = balance;
  }
  deposit(amount) { this.balance += amount; }
  describe() { return `${this.owner}: ${this.balance} AZN`; }
}

class SavingsAccount extends BankAccount {
  constructor(owner, balance, rate) {
    super(owner, balance);
    this.rate = rate;
  }
  addInterest() { this.deposit((this.balance * this.rate) / 100); }
  describe() { return `${super.describe()} (savings, ${this.rate}%)`; }
}

const leyla = new SavingsAccount('Leyla', 1000, 5);
leyla.addInterest();
console.log(leyla.describe());
console.log(leyla instanceof BankAccount);
▸ Beklenen çıktı
Leyla: 1050 AZN (savings, 5%)
true
Etkileşimli
Simülasyon yükleniyor…
Leyla addInterest() metodunu yılda bir kez çağırsaydı 1000 manatı 10 yılda nasıl büyürdü? Faizi ve süreyi değiştir.

Gizli alanlar, getter'lar ve statik metotlar

  • # ile başlayan alan gizlidir: ona yalnızca sınıfın içinden erişilebilir. Dışarıda home.#celsius yazmak bir sözdizimi hatasıdır.
  • get ve set metotları özellik gibi okunur ve yazılır, ama arkalarında kod çalışır; örneğin değeri kontrol eder.
  • static bir metot örneğe değil sınıfın kendisine aittir ve şöyle çağrılır: Thermostat.fromFahrenheit(68).
JavaScript
class Thermostat {
  #celsius = 20;

  get celsius() { return this.#celsius; }
  set celsius(value) {
    if (value < 5 || value > 30) {
      throw new RangeError('Temperature must be between 5 and 30');
    }
    this.#celsius = value;
  }
  get fahrenheit() { return (this.#celsius * 9) / 5 + 32; }
  static fromFahrenheit(f) {
    const t = new Thermostat();
    t.celsius = Math.round(((f - 32) * 5) / 9);
    return t;
  }
}

const home = new Thermostat();
home.celsius = 25;
console.log(home.celsius, home.fahrenheit);
try { home.celsius = 40; } catch (error) { console.log(error.name, '-', error.message); }
console.log(Thermostat.fromFahrenheit(68).celsius);
▸ Beklenen çıktı
25 77
RangeError - Temperature must be between 5 and 30
20
Setter yanlış değeri kabul etmez: 40 derece yasaktır, bu yüzden sıcaklık 25 olarak kalır.

Kendi hata sınıfın

Kalıtımın çok yararlı bir kullanımı kendi hata türlerini oluşturmaktır. Yerleşik Error sınıfını genişletip bir name verdiğinde, catch bloğunda hatanın türünü instanceof ile tam olarak belirleyebilir ve beklenen hataları beklenmeyenlerden kolayca ayırabilirsin.

JavaScript
class ValidationError extends Error {
  constructor(message) {
    super(message);
    this.name = 'ValidationError';
  }
}

function register(age) {
  if (age < 13) {
    throw new ValidationError('Too young to register');
  }
  return 'Welcome!';
}

for (const age of [16, 10]) {
  try {
    console.log(register(age));
  } catch (error) {
    if (error instanceof ValidationError) {
      console.log(`${error.name}: ${error.message}`);
    } else {
      throw error;
    }
  }
}
▸ Beklenen çıktı
Welcome!
ValidationError: Too young to register
TerimAnlamı
classnesneler için plan
newsınıftan yeni bir örnek oluşturur
constructoryeni örneğin özelliklerini belirler
extends / superkalıtım ve üst sınıfa erişim
#fieldyalnızca sınıfın içinde görünen alan
staticörneğe değil sınıfa ait metot
Alıştırma

Rectangle sınıfını tamamla: yapıcı width ve height değerlerini saklasın, area() ise alanı döndürsün. Sonra Rectangle'dan türeyen Square sınıfını yaz: yapıcısı tek bir side alıp super'i çağırsın.

Alıştırma · JavaScript
class Rectangle {
  constructor(width, height) {
    // save width and height
  }

  area() {
    // return the area
  }
}

class Square extends Rectangle {
  // constructor(side) → call super
}

const rect = new Rectangle(3, 4);
const square = new Square(5);
console.log(rect.area(), square.area());
console.log(square instanceof Rectangle);
console.log(square);
▸ Beklenen çıktı
12 25
true
Square { width: 5, height: 5 }

Önemli noktalar

  • Sınıf nesneler için bir plandır; örnekler new ile oluşturulur.
  • constructor özellikleri belirler, this o örneği gösterir.
  • extends kalıtım sağlar; alt sınıfın yapıcısında önce super() çağrılır.
  • # alanları gizlidir, get/set bir özelliği denetler, static sınıfın kendisine aittir.
  • Error sınıfını genişleterek kendi hata türlerini oluşturabilirsin.

Kendini test et

10 soru. Her doğru cevap XP kazandırır.

1 / 10
Bir sınıftan yeni örnek hangi operatörle oluşturulur?