Constructor Method Nedir ? Kullanımı ve Özellikleri

Fatih İzgi
7 min readAug 10, 2021

--

Bir önceki yazımızda bahsettiğimiz gibi nesne üretirken belirli bir kural takip etmekteyiz. Kendi örneğimiz üzerinden bu formülün kullanımını hatırlayalım :

User user = new User();

Yukarıdaki formülde kullandığımız User() yapısı Constructor olarak adlandırılır. Constructor yapısını anlamak için bir önceki yazıda verilen örnek üzerinden ilerleyelim. Daha önceki yazıyı okumayanlar için problem özeti :

Projede, bir sosyal medya uygulamasındaki kullanıcının profil sayfası üzerine kullanıcı bilgilerini yerleştirmek istiyoruz (Şimdilik bu işlemleri sadece ekrana bastırma olarak gerçekleştireceğiz. Ancak gerçekten bir web sitesi veya mobil uygulama geliştirirken de nesne kullanma mantığı örnekteki gibi olacaktır. Veri tabanından nesne verileri çekilir ve nesnelerin özellikleri ekrana yerleştirilir). Kullanıcının kullanıcı adı, yaşadığı ülke, yaş ve doğum tarihi özellikleri bulunsun. Ayrıca, kullanıcının profilin görüntülendiği gün eğer kullanıcının doğum günü ise doğum tarihinin yanında “Bugün Doğum Günü” bilgisi yazdırılsın. Ayrıca kullanıcı adının boş olup olunmadığı da kontrol edilsin ve buna göre ekrana bilgi bastırılsın. Tahmin edileceği üzere burada üreteceğimiz nesne “kullanıcı” nesnesidir. Dolayısıyla bir Kullanıcı sınıfına ihtiyacımız vardır. Daha sonra Main/Test sınıfımız içerisinde bu nesneyi üreterek bilgilerine erişmeye çalışacağız.

CONSTRUCTOR

Tasarlanan sınıftan nesne üretilmesi anında çalışan metoddur. Yani bir nesne oluşturduğumuzda ilk olarak Constructor Method çalışır. Nesneleri sınıflardan ürettiğimize göre bu yapının sınıf içerisinde olduğunu tahmin edebiliriz. Dolayısıyla, her sınıfta mutlaka bir Constructor bulunduğunu söyleyebiliriz. Ayrıca Constructor, nesne oluşturmak için kullanıldığından dolayı böyle bir isme sahiptir. Constructor kelimesinin Türkçe karşılıklarına baktığımızda inşaatçı, yapıcı, yapılandırıcı gibi anlamlarına geldiğini görmekteyiz. Biz de yazılım dünyasında bu kavramı Yapıcı Metot olarak bilmekteyiz.

Peki nerde bu metot ?

Constructor metodun nesne oluşturmak için kullanıldığını ve bir nesne oluşturulduğunda ilk olarak çağırılan metot olduğunu söyledik. Daha önceki yazılarda verilen örneklerde ise böyle bir metot oluşumuna rastlamadık. Bunun sorunun cevabı ise derleyicide gizli. Eğer biz sınıf içerisinde kendimiz bir Constructor oluşturmazsak derleyici bu işlemi bizim yerimize gerçekleştirir. Yani kendisi default olarak bir Constructor yapısı oluşturur.

Peki kendimiz nasıl oluştururuz ?

Constructor metot, nesnelerin üretileceği sınıf içerisinde oluşturulur. Başına “public” anahtar kelimesi(elbette her zaman değil, genellikle) gelir ve metod ismine sınıfın ismi verilir. Kendi örneğimiz üzerinden inceleyecek olursak :

public User(){}

Öncelikle bu yapının nesne üretimi sırasında çalışan ilk metot olduğunu ispatlayalım ve böylece bir Constructor örneği de incelemiş olalım :

Output :

Constructor Method Çalıştırıldı

Görüldüğü üzere, aslında biz Main içerisinde sadece bir nesne ürettik ve başka hiçbir işlem gerçekleştirmedik. Sadece nesne oluşturma sonucunda ise ekrana “Constructor Method Çağırıldı” yazısı bastırıldı. Anlaşıldığı gibi, nesne üretildiği anda Constructor metot çalışır.

DEFAULT CONSTRUCTOR

Yukarıda bahsettiğimiz gibi, yazılımcının herhangi bir Constructor oluşturmaması üzerine derleyicinin kendi oluşturduğu hazır, default olan Constructor metottur. Sınıf içerisinde gözükmez ancak arka planda mutlaka bulunur. Herhangi bir parametre almaz ve herhangi bir işlem gerçekleştirmez. Yalnızca, oluşturulacak olan nesnenin özelliklerine varsayılan değerler atar. Örneğin :

Output :

Kullanıcı Adı : null

Kullanıcı Yaşı : 0

Görüldüğü gibi, biz nesnenin özelliklerine herhangi bir değer vermemiş olmamıza rağmen Java, String tipindeki name değişkenine “null” ve int tipindeki age değişkenine “0” değerini atadı.

Dikkat edilmesi gereken nokta : Eğer sınıf içerisine parametreli bir Constructor yazarsak, daha önce var olan Default Constructor metodu sınıftan kaybolur. Yani, parametreli bir Constructor yazdıktan sonra Main sınıf içerisinde User user = new User(); gibi bir işlem gerçekleştirmek istersek Java hata verecektir. Eğer sınıfta default olarak bir Constructor bulunmaya devam etsin istiyorsak, yeniden parametresiz bir Constructor yazmamız gerekir.

PARAMETRESİZ CONSTRUCTOR

Herhangi bir parametre almayan Constructor metottur. Default Constructor’dan farklı olarak içerisinde işlemler gerçekleştirmek mümkündür. Örneğin :

Output :

Parametresiz Constructor Çalıştırıldı

Görüldüğünü gibi Constructor herhangi bir parametre almadı. Nesne oluşturma anında çağırıldı ve içerisindeki ekrana yazı bastırma işlemini gerçekleştirdi.

PARAMETRELİ CONSTRUCTOR

Parametre alan Constructor yapısıdır. Örneğin :

Görüldüğü gibi nesne oluşturma işlemi sırasında kullandığımız Constructor metoda iki adet parametre gönderdik. Metot, parametreleri kullandı ve bu sayede ekrana kullanıcı bilgilerini bastırdı. Bir nesne oluştururken genellikle Parametreli Constructor kullanılır.

CONSTRUCTOR KULLANIMI

Bir sınıf içerisinde Constructor oluşturmamızın ilk nedenlerinden bir tanesi oluşturulacak olan nesneye ait özelliklere değerler atamaktır. Sınıf içerisinde parametreli bir Constructor oluşturulur ve parametre olarak da nesne özelliklerine atanacak olan değerler gönderilir. Constructor, parametre olarak aldığı değerleri nesne özelliklerine atar. Böylece nesneler yapılandırılmış, inşa edilmiş olur. Constructor metot genellikle nesne özelliklerine değer atama amacıyla kullanılsa da elbette içerlerinde başka işlemler gerçekleştirmek mümkündür. Örneğin her nesne oluşturma işleminde Constructor çalıştırıldığını göz önüne alırsak, bu metot sayesinde oluşturulan toplam nesne sayısını hesaplayabiliriz. Kendi örnek projemiz üzerinde devam edelim :

Output :

Kullanıcı245

Türkiye

23

02.06.1998

Görüldüğü gibi nesneye atanmasını istediğimiz değerleri Constructor metot’a parametre olarak gönderdik. Metot, kendi içerisinde bu değerleri nesne özelliklerine atadı. Böylece, Main içerisindeki tek bir satırda bir nesneyi tamamen oluşturmuş olduk. İstediğimiz zaman bu nesne özelliklerine erişebiliriz.

Avantaj : Constructor kullanmak yerine nesnenin sahip olduğu özelliklere ayrı ayrı değerler vermemiz de mümkün ancak bir sınıfta onlarca değişken olabilir. Bu durumda herhangi bir özelliğe değer ataması yapmayı unutabiliriz. Bu durumda da programın çalışmama ihtimali veya hatalı çalışma ihtimali yüksektir. Constructor kullanımı, herhangi bir özelliğe değer atamayı unutmamıza izin vermez. Ayrıca, Constructor kullanımı ile yazılan kod miktarı azaldı. Böylece hem daha toplu gözüken bir yazılım elde edildi hem de zamandan tasarruf sağlanıldı.

Yukarıda Constructor metot ile bir nesneyi tamamen yapılandırmayı gördük ancak göze çarpan bir detay var. Constructor içerisine gönderdiğimiz parametreler p1,p2,p3 ve p4 gibi karışık, net ve anlaşılır olmayan isimlendirmelere sahip. Temiz kod yazmak için pek tercih edilebilecek bir yöntem değil. Bunların yerine name, country, age ve birthDate değişkenlerini çağrıştıran parametre isimleri kullanmak daha doğru olacaktır. Örneğin, name değişkenine atanacak değerin ismi userName olabilir. Bununla beraber, bir projede onlarca, belki yüzlerce sınıf olabileceğini ve buna bağlı olarak yüzlerce, belki binlerce değişken olabileceğini unutmamak gerekir. Proje geliştirme zaten yoğun bir süreçtir. Yetmez gibi her defasında uygun parametre ismi düşünmekle uğraşırsak işin içinden çıkamayız. Bu yüzden bir gelenek olarak, değişken ismi ile birebir aynı parametreler göndeririz. Örneğin :

Gördüğünüz gibi çok daha anlaşılır ve net bir kodlama gerçekleştirmiş olduk ve böylece dikkat sebebi ile hata yapma riskini neredeyse tamamen ortadan kaldırdık. Peki bu Constructor ile bir nesne oluşturursak ve nesne özelliklerini ekrana bastırırsak ne olur ? Biz parametre olarak sırasıyla “Kullanıcı245”, “Türkiye”, 23, “02.06.1998” değerlerini göndersek bile nesneye ait değerler default değerler olacaktır. Yani örneğin, kullanıcı adı null, yaş ise 0 değerine sahip olacaktır çünkü Construcor yapısında değişken ismi ve atanan değer(parametre) ismi birbiri ile aynı. Bu karmaşanın sebebi ise içeride işlem yaptığımız değişkenlerin “local değişken” olması. Yani aslında parametre olarak gönderdiğimiz “Kullanıcı245” değerine yine parametreden alınan “Kullanıcı245” değerini atıyoruz(a=a gibi bir işlem gerçekleştiriyoruz). Nihayetinde nesneye ait olan değişkenlere herhangi bir değer atanmış olmuyor. Bu istenmeyen bir durumdur ve bu noktada yardımımıza “this” anahtar kelimesi yetişiyor.

THIS KULLANIMI

This anahtar kelimesinin kullanımı ile birlikte mevcut sınıfa ait özelliklere erişim sağlanır. Örneğin this.name yazıldığı zaman User sınıfı içerisindeki name değişkenine erişilmiş olur. Aynı şekilde sınıf içerisindeki metotlara (ve dolayısıyla Constructor metotlara da ) erişim mümkündür. Bu sayede herhangi bir hata oluşturmadan nesne oluşturma işlemini tamamlayabiliriz :

Output :

Kullanıcı245

Türkiye

23

02.06.1998

“this” anahtarının kullanımı ile nesneye ait olan değişkenlere eriştik ve bu değişkenlere, parametre olarak gönderilen değerleri atadık. Bu sayede doğru ve anlaşılır bir kodlamayı da tamamlamış olduk.

BİRDEN FAZLA CONSTRUCTOR

Constructor metotlar en nihayetinde bir metottur. Bu sebeple Constructor yapılarında Overloading işlemi gerçekleştirmek mümkündür. Yani, bir sınıf içerisinde hepsi aynı isimde, birden fazla Constructor kullanabiliriz. Dikkat edilmesi gereken nokta, nesne oluştururken doğru Constructor metotu seçmemiz gerektiğidir. Örneğin :

Görüldüğü gibi User sınıfı birden fazla Constructor içeriyor. Main sınıf içerisinde iki farklı Constructor metotu kullanarak iki farklı nesne üretildi. İlk üretilen nesne, parametre olarak gönderilen değeri nesne değişkenlerine atadı, ikinci üretilen nesne ise henüz bir değere sahip değil ancak oluşturulurken ekrana yazı bastırılmasını sağladı.

Üzerine düşünelim : Varsayalım ki bir sınıf içerisinde iki farklı Constructor tanımlıyoruz. Bu Constructor metotlardan bir tanesi parametre olarak String tipinde “name” ve String tipinde “country” parametrelerini alıyor. Diğeri ise String tipinde “country” ve String tipinde “birthDate” parametrelerini alıyor. Görevleri ise aldığı parametreler doğrultusunda nesne oluşturulurken ekrana bilgi bastırmak olsun. Yani aşağıdaki gibi bir yapı elde ettik :

Bu sınıftan bir nesne üretmek istersek ne olur ? Elbette Java, hata verecektir. Bunun sebebi ise metotlarda bulunan parametreler. Hem parametre sayıları aynı, hem aynı tipteler, hem de aynı sırada dizilmişler. Birincisinde 2 String yan yana iken ikincisinde de durum aynı. Bu durumda Java hangisinin çalıştırılacağını bilemez ve program doğal olarak hata verir(java.lang.ExceptionInInitializerError, Uncompilable source code — constructor User(java.lang.String,java.lang.String) is already defined in class User). Eğer bu şekilde bir yapı kullanmak ve hata almamak istiyorsak Builder Design Pattern kullanımı gereklidir. Builder, bir tasarım desenidir ve bu problemin çözümünü içerir. Bu tarz bir problemin projelerde karşınıza çıkması muhtemeldir. Dilerseniz bu yapıyı araştırabilirsiniz.

(Not : İlk yazımızda bahsettiğimiz gibi OOP mantığını iyi kavramak Tasarım Desenleri gibi diğer konuların anlaşılmasında büyük kolaylık sağlar. Eğer OOP dünyasına henüz yeni adım attıysanız Builder gibi bir tasarım desenini kavramanız zor olabilir. Bu konuda acele etmemeniz daha doğru olacaktır.)

Peki iç içe Constructor kullanımı mümkün mü ?

Elbette mümkündür. Yani bir Constructor içerisinde başka bir Constructor metotu çağırabiliriz. Örneğin :

Görüldüğü gibi değişkenlere değere atma yaparken iki farklı Constructor kullandık ve bunlar birbiri içerisinde yuvalanmış şekilde çalıştı. Bir Constructor, bir başka Constructor’u çağırdı.

İlginç bir bilgi : this() ile bir başka Constructor çağıracaksak ilk olarak bu işlemi gerçekleştirmeliyiz. Yani örnekteki this(name) satırını, en sona alırsak Java hata verir. (java.lang.RuntimeException: Uncompilable source code — call to this must be first statement in constructor)

CONSTRUCTOR OLUŞTURMA KURALLARI

1- Constructor mutalaka “public” olarak tanımlanmalıdır. Yani metot “public” anahtar kelimesi ile başlamalıdır. (Not : Singleton Design Pattern konusunu incelediğinizde Constructor yapısının private olarak tanımlandığını göreceksiniz ve bu istisnai bir durumdur. Bu konuda yukarıdaki uyarı yine geçerlidir. Eğer OOP dünyasında yeniyseniz lütfen acele etmeyin. Şimdilik, “public” tanımlamanız sizin için yeterli olacaktır.)

2- Constructor metot ismi ile sınıf ismi birebir aynı olmak zorundadır. User isimli bir sınıftaki tüm Constructor metotlar da “User” ismine sahip olmalıdır.

3- Constructor metotlar herhangi bir değer döndüremezler. Yani “return String;” gibi bir ifadeyi Constructor içerisinde görmeniz mümkün değildir. (Return Type bulunmaz)

PROJE

Constructor kavramının ne olduğu, nasıl oluşturulduğu, kullanım şekilleri ve tasarım kuralları konuları tamamlandı. Kendi projemiz üzerinden bu kavramı inceleyelim.

Güncelleme : Kendi problemimize ekstradan “Tasarlanan sosyal medya uygulamasına kayıtlı kaç kullanıcı bulunmaktadır ? “ gibi bir soru ekleyelim ve Constructor ile bu soruya da cevap arayalım. Ayrıca “user” nesnesi, kendi bilgilerini görüntüleme davranışına da sahip olsun. Projenin tamamını incelemeye başlayabiliriz :

Output :

Kullanıcı Adı : Kullanıcı245
Kullanıcı Ülke : Türkiye
Kullanıcı Yaşı : 23
Doğum Tarihi : 02.06.1998

Kullanıcı Adı : User245
Kullanıcı Ülke : England
Kullanıcı Yaşı : 22
Doğum Tarihi : 11.03.1999

Kullanıcı Adı : Usuario245
Kullanıcı Ülke : España
Kullanıcı Yaşı : 40
Doğum Tarihi : 14.10.1980

Toplam Kullanıcı Sayısı : 3

--

--