JavaScript, bir nesne yönelimli programlama (OOP) dili olarak kullanılabilir. OOP, bir programlama yöntemi olarak, gerçek dünya nesnelerinin benzetimini kullanarak, kod yazmayı kolaylaştırır. Bu yazıda, JavaScript'te OOP temellerini inceleyeceğiz.
JavaScript'te temel nesne yönelimli programlama (OOP) terimleri şunlardır:
JavaScript'te her şey bir nesnedir. Nesneler, anahtar-değer çiftleri olarak tanımlanır ve özellikleri ve metotları içerebilir. Örneğin, aşağıdaki kod, bir "Araba" nesnesi oluşturur ve "renk" ve "hız" özelliklerini ve "hızlandır" metodunu içerebilir
let araba = {
renk: "siyah",
hız: 0,
};
console.log(araba.renk); // "siyah"
console.log(araba.hız); // 0
console.log(araba.hız); // 10
Bu kod bloğunda, nesne literaller kullanılarak oluşturuldu. Bu nesnenin özellikleri (renk, hız) anahtar-değer çiftleri olarak tanımlandı. Özellikleri kullanarak nesnenin durumunu sorgulayabilir ve metotları çağırarak nesnenin davranışlarını değiştirebiliriz. Bu kod bloğunda, araba adında bir nesne oluşturuldu. Bu nesnenin renk özelliği "siyah" ve hız özelliği 0'dır.
JavaScript'te nesneler içinde bulunan özelliklere "property" denir. Propertyler, nesnenin özellikleri, bilgileri, durumları gibi bilgileri saklar. Örnek olarak;
let araba = {
renk: "siyah",
hız: 0,
};
console.log(araba.renk); // "siyah"
console.log(araba.hız); // 0
Bu örnekte, araba nesnesinin içinde "renk" ve "hız" adında iki property tanımlanmıştır. Bu propertyler araba nesnenin rengini ve hızını saklamaktadır. Örnekte gösterildiği gibi console.log(araba.renk) ve console.log(araba.hız) ile bu propertylerin değerlerine erişebiliriz. Bu örnekte gösterildiği gibi, propertyler nesnelerin içinde bulunan özelliklerdir ve nesnelerin özellikleri, bilgileri, durumları gibi bilgileri saklamak için kullanılır.
Nesnelerin içinde bulunan işlevlerdir. Methodlar, nesnenin özellikleri ile etkileşim kurabilecek ve nesnenin davranışlarını belirleyebilecektir. Örnek olarak;
let araba = {
renk: "siyah",
hız: 0,
hızlandır: function() {
this.hız += 10;
}
};
araba.hızlandır();
console.log(araba.hız); // 10
Bu örnekte, araba nesnesinin içinde "hızlandır" adında bir method tanımlanmıştır. Bu method, araba nesnenin "hız" özelliğini artırmak için kullanılmıştır. araba.hızlandır() methodunun çağrılması sonucunda araba nesnenin hızı 10 arttırılmıştır. Bu örnekte gösterildiği gibi, methodlar nesnelerin özellikleri ile etkileşim kurarak nesnenin davranışlarını belirleyebilir. Methodlar nesnelerin içinde bulunan işlevlerdir ve nesnelerin davranışlarını belirleyebilmek için kullanılır.
JavaScript'de Constructor, bir sınıfın yeni bir örneği oluşturulduğunda çağırılan bir metoddur. Constructor metodu, nesnenin özelliklerinin veya diğer özelliklerinin başlangıç değerlerini ayarlar.
JavaScript'te ES5 versiyonunda sınıflar function ve prototype kullanarak tanımlanır. Constructor fonksiyonu, sınıfın tanımlandığı function içerisinde tanımlanır. Örnek olarak :
function Araba(renk) {
this.renk = renk;
this.hız = 0;
}
Araba.prototype.hızlandır = function() {
this.hız += 10;
};
let araba = new Araba("siyah");
console.log(araba.renk); // "siyah"
console.log(araba.hız); // 0
Bu örnekte, Araba sınıfının constructor fonksiyonu ile renk ve hız özellikleri tanımlanmıştır. Sonrasında Araba.prototype.hızlandır = function() { this.hız += 10;}
ile hızlandır metodu sınıfın prototype'ına eklenmiştir.
Son olarak let araba = new Araba("siyah");
ile nesne oluşturuldu. Bu nesnenin renk özelliği siyah ve hız özelliği 0 olarak tanımlanmıştır.
JavaScript'te ES6 versiyonunda class yapısı kullanılarak oluşturulduğunda, constructor metodu ilk olarak çalışır. Constructor metodu, sınıf içerisinde nesnenin özelliklerinin tanımlanmasını sağlar. Örneğin, aşağıdaki kod bloğunda "Araba" sınıfının constructor metodu ile renk özelliği tanımlanmıştır:
class Araba {
constructor(renk) {
this.renk = renk;
}
}
let araba = new Araba("siyah");
console.log(araba.renk); // "siyah"
ES6 ile gelen bir yapıdır. Sınıflar, nesnelerin oluşturulması için kullanılan bir şablon olarak düşünülebilir. Sınıflar, özellikleri ve metotları içerebilir ve nesneler oluşturulduğunda bu özellikleri ve metotları kullanır. Aşağıdaki kod, bir "Araba" sınıfı oluşturur ve "hızlandır" metodunu sınıfa ekler:
class Araba {
constructor(renk) {
this.renk = renk;
this.hız = 0;
}
hızlandır() {
this.hız += 10;
}
}
let araba = new Araba("siyah");
console.log(araba.renk); // "siyah"
console.log(araba.hız); // 0
araba.hızlandır();
console.log(araba.hız); // 10
Bu kod bloğunda, "Araba" sınıfı class anahtar sözcüğü ile tanımlanmıştır. Sınıf içerisinde constructor metodu ile renk ve hız özellikleri tanımlanmıştır ve hızlandır metodu ile hız özelliğine 10 eklenir. Ayrıca bir araba nesnesi oluşturuldu ve "siyah" renk değeri ile başlatıldı. Oluşturulduğunda, araba nesnesi "Araba" sınıfının metotlarını ve özelliklerini kullanabilecektir. Bu örnekte, sınıf yapısı kullanılarak Araba nesnesi oluşturuldu. Bu nesnenin renk ve hız özellikleri tanımlandı ve hızlandır metodu ile hız özelliğine 10 eklendi.
Bu örnekte class yapısı kullanılarak oluştuturulan nesnenin özellikleri ve metotları kullanılabilir hale getirildi.
Bu örnekte, Araba nesnesi oluşturulduğunda constructor metodu çalıştı ve "siyah" renk değeri ile araba nesnesinin renk özelliği tanımlandı. Constructor metodu, sınıf içerisinde nesnenin özelliklerinin tanımlanmasını sağlar ve nesnenin oluşturulduğunda ilk olarak çalışır. Bu sayede nesnenin özellikleri tanımlanmış ve kullanılabilir hale gelir.
JavaScript'te bir sınıfın bir nesnesi olarak oluşturulmasına "instantiation" denir. Instantiation ile sınıfın özellikleri ve metotları kullanılabilir hale gelir. Örnek olarak;
class Araba {
constructor(renk) {
this.renk = renk;
this.hız = 0;
}
hızlandır() {
this.hız += 10;
}
}
let araba = new Araba("siyah");
console.log(araba.renk); // "siyah"
console.log(araba.hız); // 0
araba.hızlandır();
console.log(araba.hız); // 10
Bu örnekte, Araba sınıfı tanımlanmıştır. Bu sınıfın constructor metodu ile renk özelliği tanımlanmıştır. Ve hızlandır() methodu ile hız özelliği arttırılmıştır. Sonrasında let araba = new Araba("siyah"); ile nesne oluşturuldu. Bu nesnenin renk özelliği siyah ve hız özelliği 0 olarak tanımlanmıştır.
Bu örnekte gösterildiği gibi, instantiation ile bir sınıfın bir nesnesi oluşturuldu. Bu nesne kullanılarak sınıfın özellikleri ve metotları kullanılabilir hale geldi.
Bir sınıfın başka bir sınıftan kalıtım almasıdır. Bu sayede sınıf, kalıtım aldığı sınıfın metotlarını ve özelliklerini kullanabilir. JavaScript'te class yapısı ile kalıtım yapmak için "extends" anahtar sözcüğü kullanılır. Örneğin, aşağıdaki kod bloğunda "Araba" sınıfı "MotorluAraba" sınıfından kalıtım almıştır ve "motor" özelliği eklenmiştir:
class Araba {
constructor(renk) {
this.renk = renk;
}
}
class MotorluAraba extends Araba {
constructor(renk, motor) {
super(renk);
this.motor = motor;
}
}
let araba = new MotorluAraba("siyah", "V8");
console.log(araba.renk); // "siyah"
console.log(araba.motor); // "V8"
Bu kod bloğunda, "MotorluAraba" sınıfı "Araba" sınıfından kalıtım almıştır ve "motor" özelliği eklenmiştir. "Araba" sınıfının özellikleri ve metotları "MotorluAraba" sınıfı tarafından kullanılabilir hale gelir. Bu sayede "Araba" sınıfının yazılması ve bakımı daha kolay hale gelir. Ayrıca "super" anahtar sözcüğü ile kalıtım alınan sınıfın constructor metodu çağırılır ve kalıtım alınan sınıfın özellikleri tanımlanabilir.
Bu örnekte, Araba sınıfı tanımlanmış ve MotorluAraba sınıfı Araba sınıfından kalıtım almıştır. Bu sayede MotorluAraba sınıfı Araba sınıfının özelliklerini ve metotlarını kullanabildi. Ayrıca MotorluAraba sınıfına motor özelliği eklendi. Bu kalıtım sayesinde MotorluAraba sınıfının yazılması ve bakımı daha kolay hale geldi.
Nesnelerin özelliklerinin ve metotlarının dışarıdan erişilmemesi için kullanılan yapıdır. Bu sayede nesnenin özellikleri ve metotları güvenli bir şekilde kullanılabilir. JavaScript'te encapsulation, "private" ve "public" anahtar sözcükleri ile uygulanabilir. Örneğin, aşağıdaki kod bloğunda "Araba" sınıfı "renk" özelliği için "private" ve "hızlandır" metodu için "public" tanımlaması yapılmıştır:
class Araba {
#renk;
constructor(renk) {
this.#renk = renk;
}
getRenk() {
return this.#renk;
}
setRenk(renk) {
this.#renk = renk;
}
hızlandır() {
this.hız += 10;
}
}
let araba = new Araba("siyah");
console.log(araba.getRenk()); // "siyah"
araba.setRenk("kırmızı");
console.log(araba.getRenk()); // "kırmızı"
araba.hızlandır();
Bu örnekte, Araba sınıfı oluşturuldu ve renk özelliği için private tanımlaması yapıldı. Bu sayede renk özelliği sadece sınıf içerisinde kullanılabilir hale geldi. Ayrıca hızlandır metodu public tanımlandı ve dışarıdan erişilebilir hale geldi. Bu encapsulation yapısı ile nesnenin özellikleri ve metotları güvenli bir şekilde kullanılabilir ve dışarıdan erişilmesi engellenir.
JavaScript'de Polymorphism (çok biçimlilik), aynı metodun farklı tipte nesneler için farklı işlevler yerine getirebildiği bir kavramdır. Bu sayede, kodun daha esnek ve genel olarak kullanılabilir hale gelmesi sağlanır.
JavaScript'de polymorphism için "overriding" ve "overloading" gibi yöntemler kullanılabilir.
Overriding: Bir sınıfın alt sınıfı, alt sınıfın ihtiyacına göre aynı isimli bir metodu farklı bir şekilde tanımlayabilir. Bu sayede, alt sınıfın metodu üst sınıfın metodunu geçersiz kılar ve kullanıcının beklentilerine göre daha uygun bir işlev yerine getirir.
class Shape {
draw() {
console.log("Şekil çiziliyor.");
}
}
class Circle extends Shape {
draw(radius) {
console.log(`${radius} radiuslu bir daire çiziliyor.`);
}
}
let shape = new Shape();
let circle = new Circle();
shape.draw(); // "Şekil çiziliyor."
circle.draw(5); // "5 radiuslu bir daire çiziliyor."
Overloading: Aynı metod adı ile farklı parametre sayısı veya tipi ile metodlar tanımlanabilir. Bu sayede metodun farklı ihtiyaçlar için farklı işlevler yerine getirebildiği gibi, kodun daha okunaklı ve anlaşılır hale gelir. JavaScript dilinde bu özellik yer almaz ancak yazılımcılar kendileri bu yöntemi kullanabilir. Örnek olarak:
class Calculator {
add(a, b) {
return a + b;
}
add(a, b, c) {
return a + b + c;
}
}
let calculator = new Calculator();
console.log(calculator.add(1, 2)); // Output: 3
console.log(calculator.add(1, 2, 3)); // Output: 6
JavaScript polymorphism özellikleri ile, kodun daha esnek ve genel olarak kullanılabilir hale gelmesi sağlanır. Bu sayede kodun okunaklılığı ve anlaşılırlığı arttırılır.
Sınıfların, nesnelerin oluşturulduğu sınıfın sadece gerekli olan özelliklerini ve metotlarını göstermesidir. Örnek olarak;
class Database {
constructor(data) {
this._data = data;
}
getData() {
return this._data;
}
setData(value) {
this._data = value;
}
}
class DataController extends Database {
constructor(data) {
super(data);
}
getData() {
return "Data: " + super.getData();
}
}
let dataController = new DataController("Database Data");
console.log(dataController.getData()); // "Data: Database Data"
Bu örnekte, Database sınıfı içerisinde sadece _data özelliği ve getData ve setData metotları tanımlanmıştır. DataController sınıfı ise bu sınıftan kalıtım almıştır ve sadece getData metodunu kendine özgü olarak tanımlamıştır. Bu özellikle, sadece gerekli olan özellikleri ve metotları göstererek sınıflar arasındaki bağımlılığı azaltmıştır.
Abstraction, sınıfların sadece gerekli olan özelliklerini ve metotlarını göstermesi ile elde edilen bir yapıdır. Bu sayede kodun okunabilirliği ve anlaşılabilirliği arttırılır. Bu yapı ile sınıflar arasında daha az bağımlılık oluşur ve sadece gerekli olan özellikler ve metotlar kullanılır.
Bu terimler JavaScript'te OOP kavramlarının temelini oluşturur ve nesne yönelimli programlamada sıklıkla kullanılır.