Varsayılan yapıcı Java'dır. İnşaatçılara neden ihtiyaç duyulur? Parametreleri Java'da değere göre geçirme

Yapıcı, amacı bir sınıfın örneğini oluşturmak olan, yönteme benzer bir yapıdır. Tasarımcının özellikleri:
  • Kurucunun adı sınıfın adıyla eşleşmelidir (geleneksel olarak ilk harf büyük yazılır, genellikle bir isimdir);
  • Her sınıfta bir yapıcı vardır. Siz bir tane yazmasanız bile, Java derleyicisi boş olacak ve üst sınıf kurucuyu çağırmaktan başka hiçbir şey yapmayan varsayılan bir kurucu oluşturacaktır.
  • Yapıcı bir yönteme benzer ancak bir yöntem değildir, sınıfın bir üyesi bile sayılmaz. Bu nedenle bir alt sınıfta devralınamaz veya geçersiz kılınamaz;
  • Yapıcılar miras alınmaz;
  • Bir sınıfta birden fazla kurucu bulunabilir. Bu durumda yapıcıların aşırı yüklendiği söylenir;
  • Bir sınıf bir kurucu tanımlamıyorsa, derleyici koda otomatik olarak parametresiz bir kurucu ekler;
  • Bir yapıcının dönüş türü yoktur, geçersiz tür bile olamaz; eğer bir geçersiz tür döndürülürse, sınıf adıyla çakışmasına rağmen artık bir yapıcı değil, bir yöntemdir.
  • Bir yapıcıda return ifadesine izin verilir, ancak yalnızca boştur ve herhangi bir dönüş değeri yoktur;
  • Yapıcı erişim değiştiricilerin kullanımına izin verir; değiştiricilerden birini ayarlayabilirsiniz: genel, korumalı, özel veya değiştiricisiz.
  • Bir yapıcının soyut, nihai, yerel, statik veya senkronize değiştiricileri olamaz;
  • this anahtar sözcüğü aynı sınıftaki başka bir kurucuya atıfta bulunur. Kullanılırsa, ona yapılan çağrı yapıcının ilk satırı olmalıdır;
  • Super anahtar sözcüğü ana sınıfın yapıcısını çağırır. Kullanılırsa, ona yapılan referans yapıcının ilk satırı olmalıdır;
  • Kurucu, ata sınıfın süper yapıcısına (argümanlı veya argümansız) bir çağrı yapmazsa, derleyici, ata sınıfın yapıcısını argümansız çağırmak için otomatik olarak kod ekler;

Varsayılan kurucu

Her sınıfta bir yapıcı vardır. Siz yazmasanız bile Java derleyicisi varsayılan bir kurucu oluşturacaktır. Bu yapıcı boştur ve üst sınıf yapıcıyı çağırmaktan başka bir şey yapmaz. Onlar. eğer şunu yazarsanız: public class Örnek ( ) o zaman bu şunu yazmaya eşdeğerdir: public class Örnek ( Örnek () ( süper ; )) Bu durumda, ata sınıfı açıkça belirtilmez ve varsayılan olarak tüm Java sınıfları Object'i devralır. sınıf olduğundan Object sınıfının yapıcısı çağrılır. Bir sınıf parametreleri olan bir kurucu tanımlıyorsa ancak parametreleri olmayan aşırı yüklenmiş bir kurucu yoksa, kurucuyu parametreler olmadan çağırmak bir hatadır. Ancak Java'da sürüm 1.5'ten beri değişken uzunluklu argümanlara sahip yapıcıların kullanılması mümkündür. Ve eğer değişken uzunluklu bir argümana sahip bir kurucu varsa, o zaman varsayılan kurucuyu çağırmak bir hata olmayacaktır. Değil çünkü değişken uzunluk argümanı boş olabilir. Örneğin, aşağıdaki örnek derlenmeyecektir, ancak değişken uzunluklu bir argümanla yapıcının açıklamasını kaldırırsanız, derleme ve yürütme başarılı olacak ve kod satırıyla sonuçlanacaktır DefaultDemo dd = new DefaultDemo() ; DefaultDemo(int ... v) yapıcısı çağrılacaktır. Doğal olarak bu durumda JSDK 1.5'i kullanmak gerekir. Dosya DefaultDemo.java class DefaultDemo ( DefaultDemo (String s) ( System.out.print ( "DefaultDemo(String)" ) ; ) /* DefaultDemo(int ... v) ( System.out.println("DefaultDemo(int ...)"); ) */ public static void main (String args) ( DefaultDemo dd = new DefaultDemo () ; )) Yapıcıya yorum yapılmadığında program çıktısının sonucu: DefaultDemo (int . . ) Ancak, genel durumda hiçbir kurucu tanımlanmadığında herhangi bir sınıfta, varsayılan kurucu değişikliği otomatik olarak gerçekleştiğinden, varsayılan kurucu çağrısı (parametreler olmadan) gerekli olacaktır.

Bir nesne oluştururken sırayla aşağıdaki eylemler gerçekleştirilir:
  • Nesne sınıfı, programda halihazırda kullanılan sınıflar arasında aranır. Eğer orada değilse programın kullanabileceği tüm kataloglarda ve kütüphanelerde aranır. Bir dizinde veya kitaplıkta bir sınıf keşfedildiğinde, sınıfın statik alanları oluşturulur ve başlatılır. Onlar. Her sınıf için statik alanlar yalnızca bir kez başlatılır.
  • Nesne için bellek ayrılır.
  • Sınıf alanları başlatılıyor.
  • Sınıf yapıcısı yürütülür.
  • Oluşturulan ve başlatılan nesneye bir bağlantı oluşturulur. Bu referans, nesneyi oluşturan ifadenin değeridir. Java.lang.Class sınıfının newInstance() yöntemi çağrılarak da bir nesne oluşturulabilir. Bu durumda parametre listesi olmayan bir yapıcı kullanılır.

Oluşturucuların aşırı yüklenmesi

Aynı sınıfın yapıcıları aynı ada ve farklı imzaya sahip olabilir. Bu özelliğe kombinasyon veya aşırı yükleme denir. Bir sınıfın birden fazla yapıcısı varsa, yapıcının aşırı yüklenmesi söz konusudur.

Parametreli Oluşturucular

Bir yapıcının imzası, parametrelerin sayısı ve türlerinin yanı sıra yapıcı parametreleri listesindeki türlerinin sırasıdır. İade türü dikkate alınmaz. Yapıcı herhangi bir parametre döndürmez. Bu ifade bir bakıma Java'nın aşırı yüklenmiş yapıcılar veya yöntemler arasında nasıl ayrım yaptığını açıklamaktadır. Java, aşırı yüklenmiş yöntemleri dönüş türlerine göre değil, giriş parametresi türlerinin sayısına, türlerine ve sırasına göre ayırır. Bir kurucu void tipini bile döndüremez, aksi takdirde sınıf adına benzese de normal bir yönteme dönüşecektir. Aşağıdaki örnek bunu göstermektedir. Dosya VoidDemo.java sınıfı VoidDemo ( /** * Bu bir kurucudur */ VoidDemo () ( System.out.println ("Oluşturucu" ) ; ) void VoidDemo () ( System.out.println ("Yöntem" ) ; ) public static void main (String s ) ( VoidDemo m = new VoidDemo () ; ) ) Sonuç olarak program çıktısı verecektir: Yapıcı Bu bir kez daha yapıcının dönüş parametreleri olmayan bir yöntem olduğunu kanıtlar. Ancak bir kurucu için üç değiştiriciden birini belirleyebilirsiniz: genel, özel veya korumalı. Örnek artık şöyle görünecek: Dosya VoidDemo2.java sınıfı VoidDemo2 ( /** * Bu bir kurucudur */ public VoidDemo2 () ( System.out.println ("Oluşturucu" ) ; ) /** * Ve bu, * sınıfının ismiyle benzerliğine rağmen, void dönüş tipine sahip olduğundan, zaten normal bir yöntemdir */ Private void VoidDemo2 () ( System.out.println ( "Yöntem" ) ; ) public static void main (String s ) ( VoidDemo2 m = new VoidDemo2 () ; )) Yapıcıda bir return ifadesi yazılmasına izin verilir, ancak yalnızca boş, herhangi bir dönüş değeri olmadan. Dosya ReturnDemo.java sınıfı ReturnDemo ( /** * Yapıcı * return operatörünün parametresiz kullanılmasına izin verir. */ public ReturnDemo () ( System.out.println ( "Oluşturucu" ) ; return ; ) public static void main (String s ) ( ReturnDemo r = new ReturnDemo () ; ))

Değişken uzunluklu argümanlarla parametrelendirilmiş yapıcılar

Java SDK 1.5, uzun zamandır beklenen bir aracı kullanıma sundu: yapıcılar ve yöntemler için değişken uzunluklu argümanlar. Daha önce değişken sayıda belge iki uygunsuz yöntemle işleniyordu. Bunlardan ilki, maksimum argüman sayısının az bir sayı ile sınırlı olmasını ve önceden bilinmesini sağlamak için tasarlandı. Bu durumda, yönteme iletilen bağımsız değişkenler listesinin her sürümü için bir tane olacak şekilde yöntemin aşırı yüklenmiş sürümlerini oluşturmak mümkündü. İkinci yöntem önceden bilinmeyenler için tasarlanmıştır ve çok sayıda argümanlar. Bu durumda argümanlar bir diziye yerleştirildi ve bu dizi yönteme aktarıldı. Değişken uzunluklu argümanlar çoğunlukla değişken başlatmalarla sonraki manipülasyonlarda yer alır. Beklenen yapıcı veya yöntem bağımsız değişkenlerinden bazılarının yokluğunu varsayılan değerlerle değiştirmek uygundur. Değişken uzunluk argümanı bir dizidir ve bir dizi olarak ele alınır. Örneğin, değişken sayıda argüman içeren bir Checking sınıfının yapıcısı şu şekilde görünecektir: class Checking ( public Checking (int . . n) ( ) ) Karakter birleşimi... derleyiciye değişken sayıda argümanın gerekli olduğunu söyler. kullanılacak ve bu argümanlar, referans değeri n değişkeninde yer alan bir dizide saklanacaktır. Yapıcı, hiç argüman olmaması dahil, farklı sayıda argümanla çağrılabilir. Argümanlar otomatik olarak bir diziye yerleştirilir ve n'den iletilir. Hiçbir argüman yoksa dizinin uzunluğu 0'dır. Değişken uzunluk argümanlarının yanı sıra parametre listesi zorunlu parametreleri de içerebilir. Bu durumda, değişken sayıda argüman içeren bir parametrenin mutlaka parametre listesinde sonuncu olması gerekir. Örneğin: class Checking ( public Checking (String s, int . . n) ( )) Çok belirgin bir sınırlama, değişken uzunluklu parametrelerin sayısıyla ilgilidir. Parametre listesinde yalnızca bir değişken uzunluklu parametre bulunmalıdır. İki değişken uzunluklu parametre göz önüne alındığında, derleyicinin bir parametrenin nerede bitip diğerinin nerede başladığını belirlemesi imkansızdır. Örneğin: class Checking ( public Checking (String s, int . . n, double . . . d) //ERROR! ( ) ) Dosya Kontrolü.java Örneğin, araba plakalarını tanıyabilen ve numaraları hatırlayabilen donanımlar var Bir günde her arabanın ziyaret ettiği arazi kareleri. Alan haritasına göre, gün boyunca belirli iki kareyi (örneğin 22 ve 15) ziyaret eden kayıtlı arabaların toplam kütlesinden seçim yapmak gerekir. Bir otomobilin gün içinde pek çok meydanı, belki de yalnızca bir meydanı ziyaret etmesi oldukça doğaldır. Açıkçası, ziyaret edilen karelerin sayısı arabanın fiziksel hızıyla sınırlıdır. Sınıf kurucusunun, araba numarasını zorunlu bir parametre olarak ve alanın ziyaret edilen karelerinin sayısını (sayıları değişken olabilir) argüman olarak alacağı küçük bir program oluşturalım. Yapıcı, bir arabanın iki karede görünüp görünmediğini kontrol edecek ve eğer varsa numarasını ekranda gösterecektir.

Parametrelerin yapıcıya aktarılması

Programlama dillerinde temel olarak iki tür parametre vardır:
  • temel türler (ilkeller);
  • nesnelere göndermeler.
Değere göre çağrı terimi, yapıcının çağıran modül tarafından kendisine iletilen değeri aldığı anlamına gelir. Buna karşılık referansla çağrı, yapıcının değişkenin adresini arayan kişiden alması anlamına gelir. Java yalnızca değere göre çağrıyı kullanır. Parametre değerine ve parametre bağlantı değerine göre. Java, nesneler için referansa göre çağrıyı kullanmaz (her ne kadar birçok programcı ve bazı kitapların yazarları bunu iddia etse de). Java'da nesneleri geçirirken kullanılan parametreler uygulanır linkten değil, A nesne referans değerine göre! Her iki durumda da yapıcı, tüm parametrelerin değerlerinin kopyalarını alır. Yapıcı giriş parametreleriyle yapamaz:
  • yapıcı, ana (ilkel) türlerin giriş parametrelerinin değerlerini değiştiremez;
  • yapıcı giriş parametresi referanslarını değiştiremez;
  • yapıcı, giriş parametresi referanslarını yeni nesnelere yeniden atayamaz.
Yapıcı giriş parametreleriyle şunları yapabilir:
  • giriş parametresi olarak iletilen nesnenin durumunu değiştirin.
Aşağıdaki örnek, Java'da bir yapıcıya giriş parametrelerinin nesne referans değeri tarafından iletildiğini kanıtlamaktadır. Bu örnek aynı zamanda yapıcının giriş parametrelerinin referanslarını değiştiremeyeceğini, ancak aslında giriş parametrelerinin kopyalarının referanslarını değiştirdiğini de yansıtır. Dosya Empoyee.java class Employee ( Employee (String x, String y) ( String temp = x; x = y; y = temp; ) public static void main ( String args ) ( String name1 = new String ("Alice" ) ; String name2 = new String ("Mary" ) ; Çalışan a = yeni Çalışan (name1, name2) ; System. Programın çıktısı şöyledir: isim1= Alice isim2= Mary Java, nesneleri parametre olarak iletmek için referansa göre çağırmayı kullanmışsa, yapıcı bu örnekte isim1 ve isim2'nin yerini değiştirecektir. Yapıcı aslında name1 ve name2 değişkenlerinde saklanan nesne referanslarını değiştirmeyecektir. Bu, yapıcı parametrelerinin bu referansların kopyalarıyla başlatıldığını gösterir. Daha sonra yapıcı kopyaları değiştirir. Yapıcı tamamlandığında, x ve y değişkenleri yok edilir ve orijinal değişkenler name1 ve name2 önceki nesnelere gönderme yapmaya devam eder.

Yapıcıya iletilen parametrelerin değiştirilmesi.

Yapıcı, temel türlerin iletilen parametrelerini değiştiremez. Ancak yapıcı parametre olarak iletilen nesnenin durumunu değiştirebilir. Örneğin, şu programı göz önünde bulundurun: File Salary1.java class Salary1 ( Salary1 (int x) ( x = x * 3 ; System.out.println ( "x=" + x) ; ) public static void main ( String args ) ( int değer = 1000 ; Maaş1 s1 = yeni Maaş1 (değer) ; System.println ("value=" + değer) ; ) Programın çıktısı şöyledir: x= 3000 değer= 1000 Açıkçası bu yöntem ana tip parametresini değiştirmeyecektir. Bu nedenle yapıcı çağrıldıktan sonra değişkenin değeri 1000'e eşit kalır. Esasen üç şey olur:
  1. X değişkeni, değer parametresinin bir kopyasıyla (yani 1000 sayısı) başlatılır.
  2. X değişkeninin değeri üçe katlanır; artık 3000'e eşittir. Ancak değer değişkeni 1000 olarak ayarlı kalır.
  3. Yapıcı sonlandırılır ve x değişkeni artık kullanılmaz.
Aşağıdaki örnekte, bir nesne referansının değeri yönteme parametre olarak aktarıldığı için çalışanın maaşı başarılı bir şekilde üç katına çıkarılmıştır. Dosya Salary2.java class Salary2 ( int value = 1000 ; Maaş2 () ( ) Maaş2 (Salary2 x) ( x.value = x.value * 3 ; ) public static void main (String args) ( Salary2 s1 = new Salary2 () Maaş2 s2 = yeni Maaş2 (s1);"s1.value="+ s1. değer);"s2.value="Sistem. dışarı. println( Programın çıktısı şöyledir:+ s2. değer);

))

s1. değer= 3000 s2. değer= 1000 Nesne referansının değeri parametre olarak kullanılır. Salary2 s2 = new Salary2(s1) satırını çalıştırırken; Salary2(Salary x) yapıcısına s1 değişkeninin nesne referansının değeri iletilecektir ve yapıcı içinde oluşturulan kopya (Salary x) bile s1 değişkenini işaret ettiğinden yapıcı aslında s1.value için maaşı üç katına çıkaracaktır. s1 değişkeninin nesnesi.<- double), то вызов метода со суженным значением возможен, несмотря на то, что метода, перегруженного с таким параметром нет. Например: Файл Primitive.java class Primitive { Primitive (double d) { d = d + 10 ; System. out. println (!}"d=" + d) ; } public static void main (String args ) { int i = 20 ; Primitive s1 = new Primitive (i) ; } } Programın çıktısı şöyledir:İlkellerle parametrelendirilmiş yapıcılar.

Aşırı yüklenmiş kurucunun parametreleri daraltılabilecek bir ilkel kullanıyorsa (örneğin int

d= 30.0 Primitive sınıfının int türünde parametreye sahip bir yapıcısı olmamasına rağmen, giriş parametresi double olan bir yapıcı çalışacaktır. Yapıcı çağrılmadan önce i değişkeni int türünden double türüne genişletilecektir. Tersi seçenek, i değişkeninin double tipinde olması ve yapıcının yalnızca int parametresine sahip olması durumunda, bu durumda derleme hatasına yol açacaktır. Yapıcıyı ve yeni operatörü çağırmak Yapıcı her zaman new operatörüyle çağrılır. Bir yapıcı new operatörüyle çağrıldığında yapıcı her zaman yeni bir nesneye referans üretir. Yapıcıyı, serisi kaldırılan nesnenin yerine başka bir nesne koymak dışında, yeni bir nesneye referans yerine halihazırda var olan bir nesneye referans oluşturmaya zorlamak imkansızdır. Ve new operatörüyle yeni bir nesneye referans vermek yerine, halihazırda var olan bir nesneye referans oluşturmak imkansızdır. Örneğin: Dosya Salary3.java class Salary3 ( int value = 1000 ; Salary3 () ( ) Salary3 (Salary3 x) ( x.value = x.value * 3 ; ) public static void main (String args) ( Salary3 s1 = new Maaş3 () ; System.out println ( "İlk nesne oluşturma: " + s2.value ) out. Programın çıktısı şöyledir:İlk nesne oluşturma: 1000 İkinci nesne oluşturma: 1000 İlk nesne oluşturma: 3000 Üçüncü nesne oluşturma: 1000 İlk nesne oluşturma: 1000 İlk nesne oluşturma: 1000 : 9000 İlk olarak, Salary3 s1 = new Salary3() satırını kullanarak; yeni bir nesne yaratılır. Daha sonra, Salary3 s2 = new Salary3(s1) satırını kullanıyorsanız; veya Salary3 s3 = new Salary3(s1) satırları; zaten var olan bir nesneye referans oluşturmak mümkün olabilir, o zaman s1.value s2.value ve s3.value aynı 1000 değerini saklar. Aslında, Salary3 s2 = new Salary3(s1) satırında; s2 değişkeni için yeni bir nesne oluşturulacak ve s1 değişkeni için nesnenin durumu, referans değeri yapıcı parametresindeki nesneye iletilerek değişecektir. Bu, çıktı sonuçlarıyla doğrulanabilir. Ve Salary3 s3 = new Salary3(s1) satırını çalıştırırken; s3 değişkeni için YENİ bir nesne oluşturulacak ve s1 değişkeni için nesnenin durumu tekrar değişecektir.

Yapıcılar ve başlatma blokları, bir kurucu çağrılırken yapılacak eylemlerin sırası

Nesne Oluşturma ve Oluşturucular bölümü, bir nesne oluşturulurken gerçekleştirilen genel eylemleri listeler. Bunların arasında sınıf alanlarını başlatma ve sınıf oluşturucusunu geliştirme süreçleri yer alır; bunların da bir iç düzeni vardır:
  1. Tüm veri alanları varsayılan değerlerine (0, false veya null) göre başlatılır.
  2. Tüm alan başlatıcıları ve başlatma blokları, sınıf bildiriminde listelendikleri sırayla yürütülür.
  3. Bir kurucunun ilk satırında başka bir kurucu çağrılırsa çağrılan kurucu yürütülür.
  4. Yapıcının gövdesi yürütülür.
Yapıcı başlatmayla ilgilidir çünkü Java'da bir sınıftaki alanı başlatmanın üç yolu vardır:
  • beyanda bir değer atayın;
  • başlatma bloğuna değerler atayın;
  • değerini yapıcıda ayarlayın.
Doğal olarak başlatma kodunu anlaşılması kolay olacak şekilde düzenlemeniz gerekir. Örnek olarak aşağıdaki sınıf verilmiştir: class Başlatma ( int i; short z = 10 ; static int x; static float y; static ( x = 2000 ; y = 3.141 ; ) Başlatma () ( System.out.println ( " i= " + i) ; System.out.println ("z = " + z) ; z = 20 ; System. out. println ("z = " + z) ; ) ) Yukarıdaki örnekte değişkenler başlatılmıştır. aşağıdaki sırayla: ilk olarak Statik değişkenler x ve y varsayılan değerlere başlatılır. Daha sonra statik başlatma bloğu yürütülür. Daha sonra i değişkeni varsayılan değere başlatılır ve z değişkeni başlatılır. Daha sonra tasarımcı çalışmaya başlar. Sınıf kurucularının çağrılması, alanların bildirilme sırasına bağlı olmamalıdır. Bu hatalara yol açabilir.

İnşaatçılar ve miras

Yapıcılar miras alınmaz. Örneğin: public class Örnek ( Örnek () ( ) public void sayHi () ( system.out. println ( "Merhaba" ) ; )) public class SubClass extends Örnek ( ) SubClass sınıfı, içinde tanımlanan sayHi() yöntemini otomatik olarak devralır. ebeveyn sınıfı. Aynı zamanda, üst sınıfın example() yapıcısı, onun soyundan gelen SubClass tarafından miras alınmaz.

Yapıcılardaki this anahtar sözcüğü

Yapıcılar bunu aynı sınıftaki ancak farklı parametre listesine sahip başka bir kurucuya atıfta bulunmak için kullanır. Eğer yapıcı kullanıyorsa anahtar kelime this ise ilk satırda olmalıdır; bu kuralın göz ardı edilmesi derleyici hatasıyla sonuçlanacaktır. Örneğin: File ThisDemo.java public class ThisDemo ( String name; ThisDemo (String s) ( name = s; System.out.println (name) ; ) ThisDemo () ( this ("John" ) ; ) public static void main ( String args ) ( ThisDemo td1 = new ThisDemo ("Mary" ) ; ThisDemo td2 = new ThisDemo () ; )) Programın çıktısı şöyledir: Mary John Bu örnekte iki kurucu var. İlki bir dize argümanı alır. İkincisi herhangi bir argüman almaz, yalnızca "John" varsayılan adını kullanarak ilk kurucuyu çağırır. Böylece, programlarda sıklıkla gerekli olan, alan değerlerini açıkça ve varsayılan olarak başlatmak için yapıcıları kullanabilirsiniz.

Yapıcılardaki süper anahtar kelime

Yapıcılar süper sınıfın yapıcısını çağırmak için super kullanır. Yapıcı super kullanıyorsa bu çağrının ilk satırda olması gerekir, aksi takdirde derleyici bir hata atar. Aşağıda bir örnek verilmiştir: Dosya SuperClassDemo.java public class SuperClassDemo ( SuperClassDemo () ( ) ) class Child extends SuperClassDemo ( Child () ( super () ; )) Bu basit örnekte, Child() yapıcısı super( öğesine bir çağrı içerir. ) Child sınıfına ek olarak bir SuperClassDemo örnek sınıfı oluşturur. Super, bir alt sınıfın yapıcısında yürütülen ilk ifade olması gerektiğinden, bu sıra her zaman aynıdır ve super() işlevinin kullanılıp kullanılmamasına bağlı değildir. Kullanılmazsa, ilk önce temel sınıftan başlayarak her üst sınıfın varsayılan (parametresiz) yapıcısı yürütülür. Aşağıdaki program yapıcıların ne zaman yürütüldüğünü gösterir. Call.java dosyası //Süper sınıf A'yı yarat class A ( A () ( System.out.println ( "Bir yapıcının içi." ) ; )) // A sınıfını genişleten bir B alt sınıfı oluşturun class B extends A ( B () ( System.out.println ("İç B yapıcısı." ) ; )) //B sınıfını genişleten bir (C) sınıfı oluşturun class C extends B ( C () ( System. out. println ("İç C yapıcısı." ) ; ) ) class Call ( public static void main (String args) ( C c = new C () ; )) Bu programdan çıktı: A yapıcısının içinde. B yapıcısının içinde. C yapıcısının içinde. Yapıcılar sınıf sıralamasına göre çağrılır. Bu biraz mantıklı. Üst sınıfın herhangi bir alt sınıf hakkında bilgisi olmadığından, gerçekleştirmesi gereken başlatma işlemleri ayrıdır. Mümkünse, alt sınıf tarafından gerçekleştirilen herhangi bir başlatma işleminden önce gelmelidir. Bu yüzden öncelikle bunun yapılması gerekiyor.

Özelleştirilebilir yapıcılar

Çalışma zamanı tür tanımlama mekanizması, Java dilinin polimorfizmi uygulayan güçlü temel ilkelerinden biridir. Ancak böyle bir mekanizma bazı durumlarda geliştiriciyi uyumsuz tip dökümünden korumaz. En yaygın durum, çeşitli türleri önceden bilinmeyen ve çalışma zamanında belirlenen bir grup nesnenin manipülasyonudur. Tür uyumsuzluğuyla ilgili hatalar yalnızca çalışma zamanı aşamasında ortaya çıkabileceğinden, bu durum onların bulunmasını ve ortadan kaldırılmasını zorlaştırır. Java 2 5.0'da özel türlerin kullanıma sunulması, bu hataların bazılarını çalışma zamanından derleme zamanına taşır ve eksik tür güvenliğinin bir kısmını sağlar. Bir Object türünden somut bir türe geçerken açık tip dökümüne gerek yoktur. Tür özelleştirme araçlarının yalnızca nesnelerle çalıştığı ve sınıf kalıtım ağacının dışında kalan ilkel veri türleri için geçerli olmadığı unutulmamalıdır. Özel türlerle tüm yayınlar otomatik olarak ve perde arkasında gerçekleştirilir. Bu, tür uyumsuzluklarına karşı koruma sağlamanıza ve kodu daha sık yeniden kullanmanıza olanak tanır. Yapıcılarda özel türler kullanılabilir. Yapıcılar, sınıfları özel bir tür olmasa bile özel olabilir. Örneğin: class GenConstructor ( özel çift val;< T extends Number >GenConstructor (T arg) ( val = arg. doubleValue () ; ) void printValue () ( System.out.println ("val: " + val) ; )) class GenConstructorDemo ( public static void main (String args) ( GenConstructor gc1 = new GenConstructor (100) ; GenConstructor gc2 = new GenConstructor (123.5F) ; gc2.printValue () ) GenConstructor yapıcısı, herhangi bir Number sınıfından türetilmiş bir sınıf olması gereken özel bir tür parametresi belirttiğinden.

Basit başlatma ihtiyaçlarının ötesindeki amaçlara ulaşmak için sınıf özel üyeler sağlar: inşaatçılar(yapıcılar). Yapıcı, oluşturulan bir nesneyi başlatmak için kullanılan bir ifade bloğudur. Başlatma, yeni operatör çağıran bloğa bir nesne referansı döndürene kadar gerçekleşir. Yapıcılar bildirildikleri sınıfla aynı adı taşırlar. Normal sınıf yöntemleri gibi, yapıcılar da herhangi bir sayıda argüman alabilir (sıfır dahil), ancak yöntemlerden farklı olarak herhangi bir türden değer döndüremezler. Parametrelerle bildirilen bir kurucu içeren bir sınıfın nesnesini oluştururken, new operatörünün ardından sınıfın adı ve parantez içine alınmış karşılık gelen argümanların bir listesi gelir. Yapıcılar çağrılır sonrasında yeni oluşturulan nesnenin alanlarına varsayılan değerlerin atanması ve alanların başlatılması için açık talimatların yürütülmesi.

Aşağıda metnini gördüğünüz Body sınıfının genişletilmiş versiyonunda, nesne hem başlatma ifadeleri hem de bir yapıcı kullanılarak başlangıç ​​durumuna geri yüklenir.

genel uzun kimlikNUm;

genel Dize isim= "<Без имени>";

kamu Vücut yörüngeleri = null;

özel statik uzun nextID = 0;

idNUm = sonrakiID++;

Bir yapıcı bildirimi, sınıf adının ardından parantezlerle ayrılmış (muhtemelen boş) bir parametre listesinden ve küme parantezleri içine alınmış bir ifade bloğu olan yapıcının gövdesinden oluşur. Yapıcılar, normal sınıf üyeleri gibi, aynı erişim değiştiricilerle donatılabilir, ancak yapıcılar, kesin olarak konuşursak, özel türden üyelerdir; Ancak, kural olarak bu tür ince anlamsal farklılıklar, mirasın devreye girdiği durumlar dışındadır.

Body sınıfının yapıcısı parametresiz olarak bildirilir. Amacı oldukça önemlidir; yeni oluşturulan sınıf nesnesinin idNum alan değerinin benzersiz olmasını sağlar. Sınıfın orijinal versiyonunda, kullanıcı programcısı tarafından yapılan, örneğin idNum alanına bir değer atamak gibi dikkatsizce yürütülen bir işlemle veya nextID alanının içeriğini artırmaya yönelik talimatların bulunmamasıyla ilişkili küçük bir hata, birden fazla Body nesnesinin aynı sıra numarasını almasına yol açar. Bu sonuç açıkça yanlıştır çünkü toplu sözleşmenin şunu söyleyen kısmını ihlal etmektedir:

"Farklı sınıf nesnelerinin idNum değerleri benzersiz olmalıdır."

Doğru idNum değerlerini seçme sorumluluğunu sınıfın kendisine devrederek bu tür hatalardan kesin olarak kurtulacağız. Artık Body sınıfının yapıcısı nextID alanının içeriğini değiştiren ve ona erişmesi gereken tek varlıktır. Bu nedenle nextID değişkenini sınıf dışından erişilmesini önlemek için özel olarak atayabilir ve atamalıyız. Bunu yaparak sınıfımızın gelecekteki kullanıcılarını tehdit eden potansiyel hata kaynaklarından birini ortadan kaldıracağız.

Bir tasarımcıya sahip olmak Biz idNUm değişkenine atanmaya uygun değerleri seçmekte özgürdürler. Sınıfın gelecek versiyonları, örneğin, bilim tarafından bilinen gök cisimleri hakkında bilgi içeren bir veri tabanına göz atma, karşılık gelen astronomik nesneyi isme göre arama ve yalnızca arama başarısız olduğunda nesnenin yeni bir seri numarasını hesaplama işlemini sağlayabilir. Sınıf metninde böyle bir değişikliğin mevcut uygulama kodu üzerinde herhangi bir etkisi olmayacaktır, çünkü uygulama ayrıntıları sınıfın bağırsaklarında gizlidir.

Sınıf bildiriminin gövdesindeki değişken adı ve yörüngeler için başlatma ifadeleri, sınıf bildirimine bazı geçerli ve uygun değerler atar. Artık bir nesne oluşturulduğunda, otomatik olarak durumunu tanımlayan sözleşmeyi karşılayan ilk özellikler kümesini edinir. Ayrıca, bazılarını kendi takdirimize bağlı olarak değiştirmekte özgürüz:

Gövde güneşi = yeni Gövde(); // idNUm = 0

güneş. isim = "Güneş";

Gövde toprağı = yeni Gövde(); // kimlikNum = 1

dünya.adı = "dünya";

dünya.yörüngeler = güneş;

New operatörünü kullanarak bir nesne oluşturma işlemi sırasında Body sınıfının yapıcısı çağrılır. sonrasında Tarafımızca sağlanan Başlatma İfadelerine alan adı ve ogbitlerin atanması.

Yukarıda ele alınan durum - programı yazarken, astronomik nesnenin adı ve yörüngesinin hangi gök cismi etrafından geçtiği hakkında önceden bilgi sahibi olduğumuzda - nispeten nadirdir. Bu açıdan bakıldığında, nesne adının değerlerini ve merkezi nesneye yapılan referansı argüman olarak alan başka bir kurucu oluşturmak oldukça mantıklı olacaktır:

Body(String bodyName, Body yörüngeleriAround) (

isim = gövdeAdı; yörüngeler = yörüngelerAround;

Kolayca görebileceğiniz gibi, bir sınıf kurucusu diğerine bu ifade aracılığıyla atıfta bulunur; bu, başlatıcı kurucunun gövdesindeki ilk çalıştırılabilir talimattır. Böyle bir teklife denir yapıcıya açık bir çağrı. Eğer çağırmak istediğiniz kurucu açıkça argüman gerektiriyorsa, çağrıldıklarında bunların iletilmesi gerekir. Hangi kurucunun çağrılacağı argümanların sayısına ve türlerine göre belirlenir. Bu durumda bu ifade, nesnenin idNum değerini ayarlamanıza ve nextID statik alanının geçerli içeriğini birer birer artırmanıza olanak tanıyan parametresiz bir kurucunun çağrılması anlamına gelir. Bunu çağırmak, idNum'u başlatmak ve nextID'yi değiştirmek için kodun tekrarlanmasını önlemeyi mümkün kılar. Artık nesne oluşturma kodu çok daha basit hale geliyor:

Gövde güneşi = new Gövde("güneş", null);

Beden dünyası = yeni Beden("toprak", güneş);

Yeni operatörün yürütülmesi sırasında çağrılan yapıcının sürümü, aktarılan argümanlar listesinin yapısına göre belirlenir.

Açık bir kurucu çağırma ifadesi kullanılıyorsa, bu, başlatıcı kurucunun gövdesindeki ilk çalıştırılabilir ifade olmalıdır. Çağrı argümanları olarak kullanılan ifadeler, geçerli nesnenin alanlarına ve yöntemlerine referanslar içermemelidir; her durumda, bu aşamada nesnenin yapısının henüz tamamlanmadığı varsayılır.

Mantıksal bütünlük nedeniyle, daha büyük cisimlerin uyduları olmayan gök cisimlerini temsil eden nesneler oluşturmak için kullanılan Body sınıfına başka bir tek argümanlı kurucu ekleyebiliriz. Bu yapıcı, ikinci argümanın değerinin null olduğunu önceden bildiğiniz durumlarda kullanışlıdır:

Gövde(Dize gövdeAdı) (

this(gövdeAdı, null);

Burada yine yapıcıyı açıkça çağırma tekniğini kullanıyoruz.

Bir sınıf sözleşmesinin, o sınıfın nesnelerini yaratmaktan sorumlu olan kodun, sınıf kurucularına ek bilgi sağlamasını gerektirmesi alışılmadık bir durum değildir. Örneğin, Body sınıfının yazarı olarak siz şu koşulu şart koşabilirsiniz: "Body sınıfının tüm nesnelerinin bir adı olmalıdır." Yürütülmesini garanti altına almak için, her sınıf kurucusunun parametre listesine bir ad parametresi ekleyebilirsiniz; artık ad alanını başlatma konusunda endişelenmenize gerek yoktur.

Aşağıda özel yapıcıların kullanılmasının çeşitli nedenleri listelenmiştir.

· Parametreli yapıcıların yardımı olmadan, bazı sınıflar nesnelerine kabul edilebilir başlangıç ​​değerleri sağlayamaz.

· Ek kurucular kullanıldığında nesnelerin başlangıç ​​özelliklerini belirleme görevi basitleştirilir (iki parametreli Body sınıfının kurucusu buna iyi bir örnektir).

· Nesne oluşturma genellikle yanlış başlatıcı seçimi nedeniyle yüksek maliyetlerle ilişkilendirilir. Örneğin, bir sınıf nesnesi bir tablo içeriyorsa ve onu oluşturmanın hesaplama maliyeti yüksekse, daha sonra öyle ya da böyle çalışmasının sonucunu atmanız ve tekrarlamanız gerekeceğini bilerek, varsayılan bir başlatıcı sağlamak tamamen akıllıca olmaz. Tabloya belirli bir durumda ihtiyaç duyulan özellikleri vermek için başlatma. Gerekli özelliklere sahip bir tablo oluşturabilecek uygun bir kurucunun hemen kullanılması daha tavsiye edilir.

· Yapıcı public niteliğiyle işaretlenmemişse, onu sınıfın örneklerini oluşturmak için kullanabilecek öznelerin çemberi sınırlıdır. Örneğin, tüm sınıf kurucularına paket düzeyinde erişim sağlayarak, bir paket kullanan programcıların sınıfın nesnelerini oluşturmasını engelleme hakkına sahipsiniz.

Parametresiz yapıcılar da yaygın olarak kullanılmaktadır. Bir sınıfı bildirirken herhangi bir türde tek bir kurucu oluşturmadıysanız, derleyici otomatik olarak sınıfa parametreleri olmayan boş bir kurucu ekleyecektir. Benzer bir kurucu (adlandırılır) varsayılan yapıcı) parametresiz bir kurucu kullanmanın pratik olmadığı veya imkansız olduğu sınıf örnekleri (örneğin, bir sonraki bölümde ele alınan Attr gibi) olduğundan, yalnızca başka kurucu mevcut olmadığında yaratılır. Hem parametresiz bir kurucuya hem de bir veya daha fazla ek kurucuya ihtiyaç duyulursa, ilkinin açıkça oluşturulması gerekir. Varsayılan yapıcı, kendisi için oluşturulduğu sınıfla aynı erişim niteliğini alır; eğer sınıf bildirimi genel değiştiriciyle donatılmışsa, o zaman yapıcı da olur.

herkese açık olarak işaretlenecektir.

Başka bir özel kurucu biçimi daha var - kopya yapıcı, geçerli türdeki bir nesneyi argüman olarak alır ve onun bir kopyasını oluşturur. Genellikle böyle bir kurucu, orijinal nesnenin değerlerini yeni nesnenin alanlarına kaydeder, ancak bazen sınıfın anlambilimi, yazarı kopya kurucunun gövdesinde daha karmaşık işlemler sağlamaya zorlar. Aşağıda Body türündeki nesneler için basit bir kopya oluşturucu bulunmaktadır.

Gövde(Gövde diğer) (

idNum = diğer.idNum;

isim= diğer.isim;

yörüngeler = diğer.yörüngeler;

Özel kurucuların kullanımını içeren nesnelerin kopyalanması sorununu çözme yaklaşımı, standart Java paketlerinin sınıflarında yaygın olarak kullanılmaz, çünkü böyle bir hedefe ulaşmak için Clone yönteminin kullanılması daha tercih edilir olarak kabul edilir (bkz. Bölüm 3.9, sayfa 111). Bununla birlikte, örneğin String sınıfının bir parçası olarak ve koleksiyon sınıflarında basit bir kopya oluşturucu sağlanmıştır (bunlar Bölüm 16'da tartışılmıştır).

Bir koleksiyonu başka bir koleksiyonun içeriğiyle (aynı türden olması gerekmez) başlatmanıza olanak tanıyan kopya oluşturucuların genel sürümleri desteklenir. Aslında kopya kurucuları oluşturmak, doğru bir klonlama yöntemi yazmakla aynı çabayı gerektirir.

Yapıcıların metninde beyan edilen istisnalardan bahsetmeye izin verilir.

throws cümleciği, parametre listesinden sonra, yapıcı gövdesinin başlangıcını işaret eden açılış küme parantezinin hemen öncesine yerleştirilir. Bir yapıcı bildirimi bir throws cümleciği içeriyorsa, yeni bir ifadeyi çalıştırırken yapıcıya dolaylı olarak erişen herhangi bir yöntem ya uygun catch cümleciklerini kullanarak bu türlerin istisnalarını yakalamalı ya da bu türleri kendi bildiriminin throws bölümünde listelemelidir.

Java'da Yöntem kombinasyonu belirli bir işlemi gerçekleştirmenize izin veren bir ifadeler kompleksidir. Örneğin, System.out.println() yöntemini çağırırken sistem, konsola bir mesaj yazdırmak için bir dizi komut yürütür.

Bu noktada program geliştirirken dönüş değeri olan veya olmayan kendi yöntemlerinizi oluşturma, parametreli veya parametresiz yöntemleri çağırma ve yöntemleri izole etme tekniklerini öğreneceksiniz.

Yöntem Oluşturma

Aşağıda, Java'da bir yöntemin nasıl oluşturulacağına ilişkin yöntem sözdizimini gösteren bir örnek bulunmaktadır.

Sözdizimi

public static int methodName(int a, int b) ( // body )
  • genel statik - değiştirici;
  • int - dönüş türü;
  • methodName - yöntem adı;
  • a, b - resmi parametreler;
  • int a, int b - parametrelerin listesi.

Bir yöntem tanımı, bir yöntem başlığı ve bir yöntem gövdesi ile temsil edilir. Aynı şeyi aşağıdaki metod oluşturma sözdiziminde de görebiliriz.

Sözdizimi

değiştirici returnType nameOfMethod (Parametre Listesi) ( // yöntem gövdesi)

Yukarıdaki sözdizimi şunları içerir:

  • değiştirici – yöntemin erişim türünü ve kullanım olasılığını belirler.
  • returnType – yöntem bir değer döndürebilir.
  • nameOfMethod – yöntemin adını belirtir. Bir yöntem imzası, yöntemin adını ve bir parametre listesini içerir.
  • Parametre Listesi – parametre listesi, yöntem parametrelerinin türü, sırası ve sayısı ile temsil edilir. Bu seçenek keyfi olarak ayarlanır; yöntem boş bir parametre içerebilir.
  • yöntem gövdesi – yöntem gövdesi, komutlarla çalışma yöntemini tanımlar.

Örnek

/* kod parçacığı iki sayı arasındaki minimum değeri döndürür */ public static int minFunction(int n1, int n2) ( int min; if (n1 > n2) min = n2; else min = n1; return min; )

Bir Yöntemin Çağrılması

Bir yöntemi kullanmadan önce çağrılması gerekir. Java'da bir yöntemi çağırmanın iki yolu vardır; Yöntem bir değer döndürür veya döndürmez (dönüş değeri yoktur).

Yöntemi çağırmak için kullanılan algoritma oldukça basittir. Bir program Java'da bir yöntemi çağırdığında, program kontrolü çağrılan yönteme aktarılır. Bu çağrılan yöntem daha sonra aşağıdaki durumlarda iki durumda kontrolü arayan istemciye döndürür:

  • return ifadesi yürütülür;
  • Küme ayracı kapanış yöntemine ulaşıldı.

void return yöntemi komutu çağırır. Bir örneğe bakalım:

Sistem.çıkış.!");

Return yöntemi aşağıdaki örnekle gösterilebilir:

Int sonuç = toplam(6, 9);

Aşağıdaki örnek, Java'da bir yöntemi tanımlamanın ve çağırmanın yolunu gösterir.

Örnek

public class ÖrnekMinNumber ( public static void main(String args) ( int a = 11; int b = 6; int c = minFunction(a, b); System.out.println("Minimum değer = " + c); ) / * İki sayının minimumunu döndürür */ public static int minFunction(int n1, int n2) ( int min; if (n1 >

Minimum değer = 6

Anahtar kelime geçersiz

Anahtar kelime geçersiz Java'da değer döndürmeyen yöntemler oluşturmamıza olanak tanır. Aşağıdaki örnekte void tipinde bir yöntem olan methodRankPoints'e baktık. Java'daki geçersiz yöntemler herhangi bir değer döndürmez. void tipindeki bir yöntem bir komutla çağrılır; methodRankPoints(255.7); Bu, aşağıdaki örnekte gösterildiği gibi noktalı virgülle biten bir Java ifadesidir:

Örnek

public class SampleVoid ( public static void main(String args) ( methodRankPoints(255.7); ) public static void methodRankPoints(double point) ( if (points >= 202.5) ( System.out.println("Rank A1"); )else if (puan >= 122,4) ( System.out.println("Sıra A2"); )else ( System.out.println("Sıra A3"); ) ) )

Sonuç olarak aşağıdaki sonuç elde edilecektir:

A1 Sırası

Parametreleri Java'da değere göre geçirme

Çağırma işlemi yürütüldüğünde Java argümanları iletir. Prosedür, yöntem spesifikasyonunda ilgili parametrelerin belirttiği sırayla gerçekleştirilmelidir. Parametreler değere veya referansa göre iletilebilir.

Java'da parametrelerin değere göre iletilmesi, bir yöntemin parametreyle çağrılması anlamına gelir. Bu nedenle argümanın değeri parametreye iletilir.

Örnek

Aşağıdaki program, bir parametrenin değere göre geçirilmesine ilişkin bir örneği göstermektedir. Argüman değerleri, yöntem çağrıldıktan sonra bile değişmeden kalır.

Public class swappingExample ( public static void main(String args) ( int a = 30; int b = 45; System.out.println("Geçişten önce, a = " + a + " ve b = argümanlarının değerleri " + b ); // Aktarım yöntemini çağırma swapFunction(a, b); System.out.println("\nŞimdi, argümanların değerlerini aktarmadan önce ve sonra "); System.out.println("kalan değişmedi, a = " + a + " ve b = " + b); ) public static void swapFunction(int a, int b) ( System.out.println("Değiştirmeden önce: a = " + a + " b = " + b); // int parametrelerinin aktarılması c = a; a = b; b = c System.out.println("Değiştirildikten sonra: a = " + a + " b = " + b))

Aşağıdaki sonucu elde ederiz:

Aktarımdan önce argümanların değerleri a = 30 ve b = 45 Değiştirmeden önce: a = 30 b = 45 Değiştirmeden sonra: a = 45 b = 30 Şimdi aktarımdan önce ve sonra değerler ​​argümanların sayısı değişmeden kaldı, a = 30 ve b = 45

Yöntem Aşırı Yüklemesi

Java'da Yöntem Aşırı Yüklemesi- Bir sınıfın aynı adda ancak farklı parametrelere sahip iki veya daha fazla yöntem içermesi durumu. Bu süreç yöntemi geçersiz kılmaktan farklıdır. Yöntemleri geçersiz kılarken yöntem benzer bir ad, tür, parametre sayısı vb. ile karakterize edilir.

Bir tamsayı türünün minimum sayılarını belirlerken yukarıda sunulan örneği düşünün. Diyelim ki bir double tipinin minimum sayısını belirlemek istiyoruz. Bu vakada aynı ada ancak farklı parametrelere sahip iki veya daha fazla yöntem oluşturmak için aşırı yükleme kavramı tanıtılacaktır.

Yukarıdaki örnek yukarıdakileri göstermektedir.

Örnek

public class ÖrnekOverloading ( public static void main(String args) ( int a = 7; int b = 3; double c = 5,1; double d = 7,2; int result1 = minFunction(a, b); // diğer parametrelerle aynı fonksiyon double result2 = minFunction(c, d); System.out.println("Minimum değer = " + sonuç1); System.out.println("Minimum değer = " + sonuç2 ) // tam sayı için public static int minFunction (int n1) , int n2) ( int min; if (n1 > n2) min = n2; else min = n1; return min; ) // double için public static double minFunction(double n1, double n2) ( double min; if (n1 > n2) min = n2; aksi takdirde min = n1;

Sonuç olarak aşağıdaki sonuç elde edilecektir:

Minimum değer = 3 Minimum değer = 5,1

Aşırı yükleme yöntemleri bir programı okunabilir hale getirir. Dolayısıyla aynı isimde fakat farklı parametrelere sahip iki yöntem vardır. Sonuç olarak minimum int sayısını ve double type sayısını aldık.

Komut Satırı Bağımsız Değişkenlerini Kullanma

Programın çalışması sırasında bazı bilgileri aktarmanız gerekebilir. Bu, Java'da komut satırı argümanlarını main()'a ileterek yapılabilir.

İÇİNDE Java argümanı komut satırı, yürütüldüğünde komut satırında doğrudan program adını takip eden bilgileri temsil eder. Bir Java programında komut satırı argümanlarına erişmek zor değildir. Main() işlevine iletilen dize dizisinde bir dize olarak saklanırlar.

Örnek

Aşağıdaki program çağrılan tüm komut satırı bağımsız değişkenlerini görüntüler.

Genel sınıf CommandLine ( public static void main(String args) ( for(int i = 0; i

Denemek bu program, Aşağıda gösterildiği gibi:

$java Komut Satırı Komut satırı 300 -200

Sonuç olarak aşağıdaki sonuç elde edilecektir:

Argümanlar: bu args: komut args: string args: 300 args: -200

Java'da yapıcı

Java'da yapıcı Bir nesneyi oluşturulduğunda başlatır. Adı sınıf adına benzer ve sözdizimi bir yönteminkine benzer. Ancak ikincisinden farklı olarak yapıcının bir dönüş değeri yoktur.

Genellikle Java'daki bir yapıcı, bir sınıf tarafından tanımlanan örnek değişkenlere bir başlangıç ​​değeri atamak veya tam biçimli bir nesne oluşturmak için gereken diğer başlatma prosedürlerini gerçekleştirmek için kullanılabilir.

Yapıcılar, belirtilmiş olup olmadıklarına bakılmaksızın tüm sınıflarda mevcuttur, çünkü Java otomatik olarak tüm sınıf üye değişkenlerini sıfıra başlatan bir varsayılan kurucu sağlar. Ancak kendi kurucunuzu tanımladığınızda varsayılan kurucu artık kullanılmayacaktır.

Örnek

Aşağıdaki örnek, parametresiz bir sınıf yapıcısının kullanımını göstermektedir.

// Basit kurucu. class MyClass ( int x; // Sonra MyClass() yapıcısı gelir ( x = 10; ))

Nesneleri başlatmak için aşağıdaki örneğe göre bir yapıcı çağrısı yapmanız gerekir.

Genel sınıf ConsDemo ( public static void main(String args) ( MyClass t1 = new MyClass(); MyClass t2 = new MyClass(); System.out.println(t1.x + " " + t2.x); ) )

Sonucu alıyoruz:

Parametreli yapıcı

Çoğu zaman bir veya daha fazla parametre alan bir kurucuya ihtiyacınız olabilir. Bir yapıcıya parametre eklemek, onları bir yönteme eklemekle aynıdır; tek fark bunları yapıcı adından sonra parantez içine almanızdır.

Örnek

// Basit kurucu. class MyClass ( int x; // Aşağıda MyClass(int i) yapıcısı bulunmaktadır ( x = i; ))

Nesneleri başlatmak için aşağıdaki örnekte olduğu gibi yapıcıyı çağırmanız gerekecektir.

Genel sınıf ConsDemo ( public static void main(String args) ( MyClass t1 = new MyClass(10); MyClass t2 = new MyClass(20); System.out.println(t1.x + " " + t2.x); ) )

Aşağıdaki sonucu elde ederiz:

Anahtar kelime bu

Anahtar kelime bu- bir yöntem veya örnek oluşturucu verilen geçerli sınıfa atıfta bulunmak için kullanılır. Bunu Java'da kullanarak, bir sınıfın yapıcılar, değişkenler ve yöntemler gibi örneklerine başvurabilirsiniz.

Not: this anahtar sözcüğü yalnızca yöntemlerin veya örnek oluşturucuların bir parçası olarak kullanılır.

Tipik olarak, Java'daki this anahtar sözcüğü şu amaçlar için kullanılır:

  • bir yapıcının veya yöntemin parçası olarak aynı ada sahip olduklarında örnek değişkenler ile yerel değişkenler arasındaki fark.
sınıf Öğrenci ( int yaş; Öğrenci(int yaş) ( this.age = yaş; ))
  • bir sınıf içindeki diğer türden bir kurucuyu (parametreli kurucu veya varsayılan kurucu) çağırmak. Bu işleme açık yapıcı çağrısı da denir.
sınıf Öğrenci ( int age Öğrenci() ( this(20); ) Öğrenci(int yaş) ( this.age = yaş; ))

Örnek

Genel sınıf This_Example ( // num değişkenini başlat int num = 11; This_Example() ( System.out.println("Bu, this anahtar sözcüğünü içeren örnek bir programdır"); ) This_Example(int num) ( // Varsayılanı çağır yapıcı this( ); // Num örnek değişkenine yerel bir değişken atamak this.num = num; ) public void greet() ( System.out.println("Merhaba! ProgLang'a hoş geldiniz!"); ) public void print () ( // Yerel değişken num int num = 20; // Sınıf yöntemini çağırın greet this.greet(); // Yerel değişkeni yazdırın. System.out.println("Yerel değişken num'un değeri: " + num ); // Örnek değişkenini yazdırın .out.println("Örnek değişkeninin değeri: " + this.num); public static void main(String args) ( // This_Example sınıfını başlatın obj1 = new This_Example(); // Yazdırma yöntemini çağırın obj1.print() ; // Sayı değişkeninin yeni değerini parametreli yapıcı aracılığıyla iletmek This_Example obj2 = new This_Example(30); // Yazdırma yöntemini tekrar çağırmak obj2.print(); ))

Sonuç olarak aşağıdaki sonuç elde edilecektir:

Bu, this Hello! anahtar sözcüğünü içeren örnek bir programdır. ProgLang'a hoş geldiniz! Yerel değişken num'un değeri: 22 Örnek değişken num'un değeri: 11 Bu, this Hello! anahtar sözcüğünü içeren örnek bir programdır. ProgLang'a hoş geldiniz! Yerel değişken değer numarası: 22 Örnek değişken değer sayısı: 30

Değişken Bağımsız Değişkenler (var-args)

JDK 1.5 ve üzeri, aynı türden değişken sayıda bağımsız değişkeni bir yönteme aktarmanıza olanak tanır. Yöntemdeki parametre şu şekilde bildirilir:

TürAdı...parametreAdı

Bir yöntem bildirirken, türü ve ardından bir üç nokta (...) belirtirsiniz. Bir yöntemde yalnızca bir değişken uzunluklu parametre belirtilebilir ve bu parametrenin son parametre olması gerekir. Herhangi bir normal parametre bundan önce gelmelidir.

Örnek

public class VarargsDemo ( public static void main(String args) ( // args değişkeniyle bir yöntem çağırın printMax(27, 11, 11, 5, 77.1); printMax(new double(10, 11, 12, 77, 71) ); ) public static void printMax(double... sayılar) ( if (numbers.length == 0) ( System.out.println("Hiçbir bağımsız değişken iletilmedi"); return; ) double result = sayılar; for (int) i = 1; i sonuç) sonuç = sayılar[i] System.out.println("Maksimum değer " + sonuç);

Sonuç olarak aşağıdaki sonuç elde edilecektir:

Maksimum değer 77,1 Maksimum değer 77,0

finalize() yöntemi

finalize() yöntemi- nesnenin sonunda çöp toplayıcı tarafından yok edilmesinden hemen önce çağrılacak bir yöntem. (sonlandırıcı). Java'da finalize(), bir nesnenin temiz bir şekilde sonlandırılmasını sağlamak için kullanılabilir.

Örneğin, aşağıdakileri sağlamak için finalize() işlevini kullanabiliriz: açık dosya Bu nesneye ait olan kapatıldı.

Bir sınıfa sonlandırıcı eklemek için Java'da finalize() yöntemini tanımlamanız yeterlidir. Java çalışma zamanı bu sınıfın bir nesnesini işlemeden hemen önce bu yöntemi çağırır.

finalize() yönteminin bir parçası olarak, nesne yok edilmeden önce gerçekleştirilmesi gereken eylemleri belirtirsiniz.

İÇİNDE Genel görünüm finalize() yöntemi şuna benzer:

Korumalı void finalize() ( // kodun sonlandırılması burada )

Burada, protected anahtar sözcüğü, finalize() işlevine kendi sınıfı dışında tanımlanan kod tarafından erişilmesini engelleyen bir belirticiyi temsil eder.

Bu, finalize() işlevinin nasıl ve hatta ne zaman yürütüleceğini bilemeyeceğinizi gösterir. Örneğin, programınız çöp toplama işleminden önce sona ererse finalize() yürütülmeyecektir.

Yapıcı, yeni bir nesne oluşturulduğunda çağrılan özel bir yöntemdir. Bir sınıfın örneğini oluştururken sınıfın tüm değişkenlerini başlatmak her zaman uygun değildir. Bazen bir nesne oluşturulduğunda bazı varsayılan değerlerin oluşturulması daha kolaydır. Temel olarak değişkenleri otomatik olarak başlatmak için bir kurucuya ihtiyaç vardır.

Yapıcı, nesneyi doğrudan oluşturma sırasında başlatır. Yapıcı adı, büyük/küçük harf de dahil olmak üzere sınıf adıyla aynıdır ve yapıcının sözdizimi, dönüş değeri olmayan bir yönteme benzer.

Özel int Cat(); // Cat Cat() adı verilen yöntem böyle görünüyor; // Cat sınıfı yapıcısının neye benzediği budur

Bir yöntemden farklı olarak yapıcı hiçbir zaman hiçbir şey döndürmez.

Yapıcı, bir sınıfın bir nesnesi oluşturulduğunda ve sınıfın önemli bir parçası olduğunda gerçekleştirilen eylemleri tanımlar. Kural olarak programcılar yapıcıyı açıkça belirtmeye çalışırlar. Açık bir kurucu yoksa, Java varsayılan olarak kullanılmak üzere otomatik olarak bir kurucu oluşturacaktır. Sınıfı uyguladığımızda Kutu, hiçbir kurucu oluşturulmadı.

Sınıfa basitçe kutunun başlangıç ​​değerlerini ayarlayacak bir kurucu ekleyelim.

Sınıf Kutusu ( int genişlik; // kutu genişliği int yükseklik; // kutu yüksekliği int derinlik; // kutu derinliği // Constructor Box() ( genişlik = 10; yükseklik = 10; derinlik = 10; ) // hacmini hesapla int getVolume() kutusu ( dönüş genişlik * yükseklik * derinlik; ))

Yöntemi geçici olarak kaldırdık setDim() ve bir kurucu ekledik. Bakalım neler olacak:

Kutu kediKutu = yeni Kutu(); mInfoTextView.setText("Kutu hacmi: " + catBox.getVolume());

Program, herhangi bir boyut belirtmemiş olmamıza rağmen kutunun hacmini gösterecektir. Tasarımcı sayesinde oluşturulan herhangi bir kutunun sabit bir hacmi olacaktır.

Doğal olarak yöntemi geri döndürebilirsiniz setDim()(sınıflarla ilgili makaleye bakın) ve kutunun boyutlarını ayarlayın:

Kutu kediKutu = yeni Kutu(); // catBox.setDim(10, 20, 30); kutusu için kendi boyutlarımızı ayarladık; mInfoTextView.setText("Kutu hacmi: " + catBox.getVolume());

Anahtar kelimeden sonra ne zaman olacağı artık sizin için açık olmalıdır. yeni sınıf adını parantez içinde yazıyoruz, sonra aslında sınıf yapıcısını çağırıyoruz.

Soru ortaya çıkıyor - ancak ilk başta sınıfı oluştururken bir yapıcı değil kod yarattık yeni Kutu()çalıştı. Buradaki önemli nokta, eğer kurucu açıkça tanımlanmamışsa, Java, varsayılan olarak kullanılacak bir kurucu oluşturacaktır. Bu durumda tüm değişkenlere basitçe sıfır değeri atayacaktır. Yapıcıyı kendiniz oluşturduysanız varsayılan kurucu kullanılmayacaktır.

Herhangi bir yöntem gibi, bir kurucunun da argümanları olabilir. Yapıcı argümanları, nesneyi başlatmak için parametreleri iletir. Örneğin, eğer sınıf Kedi kedinin yaşını belirten bir tamsayıyı argüman olarak alan bir kurucu var, ardından nesneler Kedi aşağıdaki gibi oluşturulacaktır:

Kedi kedi = yeni Kedi(8); // kedi 8 yaşında

Eğer Kedi(int) sınıfın tek kurucusu ise derleyici nesne yaratılmasına izin vermez Kedi başka bir şekilde.

Ancak kedi kutularına dönelim. Oluşturduğumuz yapıcı aynı kutular oluşturduğundan pek kullanışlı değildir. Sınıfta parametreleri olan bir kurucu oluşturalım Kutu ve ilk parametresiz kurucuyu yorumlayın:

// İkinci kurucu Box(int ​​w, int h, int d) ( genişlik = w; yükseklik = h; derinlik = d; )

Bir sınıf, parametreleri olan bir kurucu içeriyorsa, sınıfı bildirirken değerleri belirtmeniz gerekecektir:

// Bu yapıcı artık geçerli değil // Box catBox = new Box(); // Yapıcıda kutu boyutu değerlerini belirtmeniz gerekiyor Box catBox = new Box(100, 200, 100); mInfoTextView.setText("Kutu hacmi: " + catBox.getVolume());

Bu arada, böyle bir kurucuyla yöntem setDim() artık ona ihtiyacımız yok. Kutunun boyutlarını doğrudan yapıcıda ayarlayabiliriz. Büyük olasılıkla kutu sabit olduğundan ve boyutu değişmediğinden, yöntem belki de gereksizdir. Ancak kutunun boyutunu değiştirirsek yöntemden çıkmak zorunda kalacağız.

Bir sınıfın birden fazla yapıcısı olabilir. İlk kurucunun açıklamasını kaldırın ve iki kutu oluşturun; bir varsayılan kutu ve bir büyük kutu.

Kutu varsayılanKutu = yeni Kutu(); mInfoTextView.setText("Standart kutunun hacmi: " + defaultBox.getVolume()); Kutu bigBox = yeni Kutu(100, 200, 200); mInfoTextView.append("\nBüyük kutu hacmi: " + bigBox.getVolume());

Yani yapıcıların da tıpkı yöntemler gibi aşırı yüklemeyi desteklediğini görüyoruz.

Örneğin, tüm kenarların eşit olduğu küp şeklindeki bir kutu için özel olarak başka bir kurucu oluşturabiliriz:

// Küpün üçüncü kurucusu Box(int ​​​​len) ( genişlik = yükseklik = derinlik = len; )

Küpün boyutunu hesaplayın:

Kutu küpü = yeni Kutu(5); int vol = cube.getVolume(); mInfoTextView.setText("Küp hacmi: " + hacim);

Bir nesneyi parametre olarak kullanma

Şu ana kadar yapıcılarda parametre olarak basit türleri kullandık. Ancak sınıfın kendisine ait bir nesneyi de iletebilirsiniz. Başka bir kurucu ekleyelim:

// Box Box(Box ob) türünde bir nesne kullanın ( genişlik = ob.genişlik; yükseklik = ob.yükseklik; derinlik = ob.derinlik; )

Program kodunda yapıcıyı aşağıdaki gibi kullanabilirsiniz:

Kutu kutusu1 = yeni Kutu(100, 200, 100); Kutu klonKutu = yeni Kutu(kutu1); int vol = cloneBox.getVolume(); mInfoTextView.setText("Kutu hacmi: " + cilt);

Kutu sınıfı (kaynak)

ru.alexanderklimov.box paketi; class Box ( int genişlik; // kutu genişliği int yükseklik; // kutu yüksekliği int derinlik; // kutu derinliği // Box() yapıcısı ( genişlik = 10; yükseklik = 10; derinlik = 10; ) // İkinci kurucu Box( int w, int h, int d) ( genişlik = w; yükseklik = h; derinlik = d; ) // Küpün üçüncü kurucusu Box(int ​​​​len) ( genişlik = yükseklik = derinlik = len; ) // Kullan Box türünde bir nesne Box(Box ob) ( genişlik = ob.genişlik; yükseklik = ob.yükseklik; derinlik = ob.derinlik; ) // kutunun hacmini hesaplayın int getVolume() ( dönüş genişlik * yükseklik * derinlik; ) // void setDim kutusunun boyutlarını ayarladık (int w, int h, int d) ( genişlik = w; yükseklik = h; derinlik = d; ))

Aşırı yüklenmiş yapıcıları this() aracılığıyla çağırmak

Aşırı yüklenmiş kurucularla uğraşırken, bir kurucuyu diğerinden bir anahtar kelimeyle çağırmak uygundur Bu. Yapıcıyı çalıştırırken Bu()İlk olarak parametre listesiyle eşleşen aşırı yüklenmiş kurucu çalıştırılır. Daha sonra orijinal kurucunun içindeki ifadeler, eğer varsa yürütülür. Yapıcıyı çağırmak Bu() yapıcıdaki ilk ifade olmalıdır.

Öncelikle yapıcı kullanmayan bir sınıf oluşturalım Bu() farkı anlamak için.

Sınıf Cat ( int age; int doğum günü; // Değişkenleri açıkça başlat Cat(int i, int j) ( age = i; doğum günü = j; ) // Değişkenleri aynı değerle başlat Cat(int i) ( age = i; doğum günü = i; ) // Varsayılan değerleri 0 olarak ayarlayın Cat() ( yaş = 0; doğum günü = 0; ))

Üç kuruculu bir sınıf oluşturduk. Yapıcıyı kullanarak sınıfı yeniden yazalım Bu().

Sınıf Cat( int age; int doğum günü; // Değişkenleri açıkça başlat Cat(int i, int j) ( age = i; doğum günü = j; ) // Değişkenleri aynı değerle başlat Cat(int i) ( this( i, i); // Cat(i, i); // Varsayılan değerleri 0 olarak ayarlayın Cat() ( this(0); // Cat(0); ))

Artık alanlara değer atayan tek bir kurucumuz var - Cat(int, int). İfade yürütüldüğünde ne olur:

Kedi kedi = yeni Kedi(8);

Yapıcıyı çağırmak Kedi(8) yapıcının yürütülmesine neden olur bu(8, 8) yapıcıyı çağırmaya eşdeğerdir Kedi(8, 8).

İfade yürütüldüğünde ne olur:

Kedi kedi2 = yeni Kedi();

Bu durumda yapıcı çağrılır bu(0) yapıcının yürütülmesine neden olur Kedi(0)çünkü yapıcının bu özel sürümü parametreler listesiyle eşleşiyor. Bu durumda yapıcı Kedi(0) esasen yapıcıyı çağırır Kedi(0, 0).

Aşırı yüklenmiş yapıcıları yapıcı aracılığıyla kullanma Bu() sınıf yükleme süresini azaltarak kod tekrarını ortadan kaldırmanıza olanak tanır.

Ancak dikkatli olmalısınız çünkü yapıcıyı çağıran yapıcılar Bu(), biraz daha yavaş koş.

Özel inşaatçı

Bazen bir sınıf yalnızca bazı statik alanları ve statik yöntemleri depolamak için oluşturulur. Bu tür sınıflara ad vermek gelenekseldir Araçlar ancak bu isteğe bağlıdır. Böyle bir sınıfın bir kurucuya ihtiyacı yoktur, ancak sınıfın yazarı bir kurucu yaratmadıysa, sistemin kendisi varsayılan bir kurucu yaratacaktır. Böyle bir kurucu anlamsızdır ve aynı zamanda hataların kaynağı da olabilir. Bu soruna karşı korunmak için, kendiniz açıkça boş bir kurucu oluşturmalı ve onu özel yapmalısınız.

Genel sınıf Utils (özel Utils() ( throw new AssertionError(); ) ... //sizin doğru kod// Yanlış kod, yalnızca tanıtım amaçlıdır! public static void someMethod())( Utils utils = new Utils(); utils.toString(); ))

Astar yeni AssertionError() at isteğe bağlıdır, ancak yapıcıyı sınıfın kendisinde çağırırsanız hatayı yakalamanıza yardımcı olacaktır. Derleyici bu seçeneği atlayacak ancak program bir hatayla sonlanacaktır.

Utils.someMethod(); // program hata vererek kapanacak

Bu sınıf için bir alt sınıf oluşturamazsınız.

Bildiğiniz gibi bir nesne belirli bir sınıfın örneğidir. Bunu oluşturmak için new anahtar kelimesini kullanın, örneğin:
Kişi öğrenci = yeni Kişi(“Mike”)
Bu kod yeni bir nesne yaratır Kişi ve adı belirtiliyor - Mike. Astar " Mike" karşılık gelen yapıcıya argüman olarak iletilir Kişi:

Kişi(Dize adı) ( this.name = name; )

Bu yapıcı, bir nesne oluştururken kişinin adını belirtmenize olanak tanır.

Sınıfın yeni bir örneği oluşturulduğunda yapıcı her zaman çağrılır. Başka bir deyişle yapıcılar, bir nesne oluşturulduğunda nesnenin durumunu başlatmak için kullanılır. Yapıcılar normal yöntemlere benziyorlar ama değiller:

  • Yapıcılar sınıf adıyla aynı ada sahiptir.
  • Yöntemler gibi yapıcıların da kabul ettikleri parametrelerin bir listesi vardır, ancak bir dönüş türü yoktur (geçersiz bile değildir).

Aşağıda bir dizi Yapıcılarla çalışmanın 7 temel kuralı , onların çalışmalarını tam olarak anlamanıza olanak tanır.

  1. Yapıcılar aşırı yüklenebilir:

Bu, eğer parametre listeleri farklıysa bir sınıfın birçok farklı kurucuya sahip olabileceği anlamına gelir. Örneğin:

Sınıf Rectangle ( int genişlik; int yükseklik; Rectangle() ( genişlik = 1; yükseklik = 1; ) Rectangle(int genişlik) ( this. genişlik = genişlik; this. yükseklik = genişlik; ) Rectangle(int genişlik, int yükseklik) ( bu genişlik = genişlik; yükseklik = yükseklik;

Üç farklı kurucuya sahip olmak Dikdörtgen Yeni bir nesneyi üç farklı şekilde oluşturabilirsiniz:

Dikdörtgen rect1 = new Dikdörtgen(); Dikdörtgen rect2 = new Dikdörtgen(10); Dikdörtgen rect3 = new Dikdörtgen(10,20);

  1. Varsayılan kurucu:

Yapıcıları bildirmek hiç gerekli değildir. Yapıcılardan hiçbiri tanımlanmamışsa derleyici Java otomatik olarak boş ve parametresi olmayan bir varsayılan kurucu oluşturur.

Örneğin Rectangle sınıfını şu şekilde yazarsak:

Sınıf Dikdörtgen ( int genişlik, yükseklik; int alan() ( ) int çevre() ( ) )

Daha sonra derleyici otomatik olarak varsayılan bir kurucu ekler: ectangle() ( )

  1. Sınıfın zaten bir yapıcısı varsa, derleyici varsayılan bir kurucu oluşturmaz:

Aşağıdaki örneği düşünün:

Sınıf Rectangle ( int width; int height; Rectangle(int width) ( this. width = width; this. height = width; ) Rectangle(int width, int height) ( this. width = width; this. height = height; ) )

Yeni bir nesne oluşturmaya çalışırken: Rectangle rect1 = new Rectangle(); Derleyici argüman içermeyen bir kurucu bulamadığı için hata verecektir.

  1. Yapıcılar miras alınmaz:

Yöntemlerin aksine yapıcılar miras alınmaz. Örnek:

Sınıf Dikdörtgen ( Dikdörtgen(int genişlik, int yükseklik) ( ) ) class Kare Dikdörtgeni genişletir ( )

Şöyle bir şey yapamazsınız: Kare kutu = new Kare(10, 10);

  1. İnşaatçılar özel olabilir!

Harici kodun sınıfın yeni bir örneğini oluşturmasını önlemek için yapıcıyı özel yapabilirsiniz. Özel bir inşaatçının avantajı ne olabilir?

Adı verilen bir tasarım deseninde Tekil, sınıfın her zaman yalnızca bir örneğinin olmasını sağlamak için özel yapıcı kullanılır. Sınıf Tekil bu benzersiz örneği elde etmek için statik bir yöntem sağlar.

  1. Varsayılan kurucu, sınıfla aynı erişim değiştiricisine sahiptir:

Aşağıdaki sınıfı yazarken: public sınıfı Person ( )

Varsayılan bir kurucu eklenirken, derleyici aynı zamanda gerekli erişim değiştiricisini de gösterecektir: public Preson();

  1. Herhangi bir kurucunun ilk satırı ya aynı sınıftan aşırı yüklenmiş bir kurucuyu ya da onun üst sınıfının bir kurucusunu çağırmalıdır:

Durum böyle değilse, derleyici süper sınıf yapıcısına super(); argümanları olmadan otomatik olarak bir çağrı ekleyecektir. Bu bir hatayla sonuçlanabilir çünkü böyle bir kurucu üst sınıfta mevcut olmayabilir. Örnek:

Sınıf Parent ( Parent(int number) ( ) ) class Child extends Parent ( Child() ( ) )

Derleyici sınıf yapıcısına super() çağrısı eklediğinden hatayla sonuçlanacaktır. Çocuk:

Child() (super();// derleyici tarafından eklendi)

Ancak derleyici sınıf için varsayılan bir kurucu eklemez Ebeveyn, Çünkü Zaten başka tasarımcılar da var.