BMH-303 Nesneye Yönelik Programlama
this anahtar kelimesi ve kalıtım
Dr. Musa ATAŞ
Siirt Üniversitesi Bilgisayar Mühendisliği
this kelimesinin kullanım yerleri
• Aktif sınıfın örneğine referans vermek için
• Aktif sınıfın kurucusunu çağırmak için
• Aktif sınıftaki metodu çağırmada
• Metod çağrısında parametre olarak
• Kurucu metod çağrısında parametre olarak
• Aktif sınıfın örneğini geri döndürmede
Aktif sınıfın örneğine referans vermek için
• Bir metodun formal parametresi ile sınıf değişkenleri aynı isme sahipse atamalarda karışıklığı gidermek için kullanılır.
• Farklı isimler kullanılacaksa this kelimesini sınıf değişkenlerinin başına eklemek gereksizdir çünkü derleyici bunu sizin yerinize otomatik olarak zaten yapmaktadır.
class Student10{int id;String name;
Student10(int id,String name){id = id;name = name;
}void display(){System.out.println(id+" "+name);}
public static void main(String args[]){Student10 s1 = new Student10(111,"Karan");Student10 s2 = new Student10(321,"Aryan");s1.display();s2.display();}
}
Test it NowOutput:0 null
0 null
//example of this keywordclass Student11{
int id;String name;
Student11(int id,String name){this.id = id;this.name = name;}void display(){System.out.println(id+" "+name);}public static void main(String args[]){Student11 s1 = new Student11(111,"Karan");Student11 s2 = new Student11(222,"Aryan");s1.display();s2.display();}
}
Test it Now
Output111 Karan
222 Aryan
Aktif constructor’u çağırmada this() kullanımı
• Bir sınıfta constructor overloading yapılmışsa yani birden fazla farklı formal parametrelere sahip kurucu metod tanımlanmışsa ve eğer bu kurucu metodlar kendi içlerinde zincirleme bir birlerini çağırıyorlarsa kullanımı geliştiriciye bir pratik sağlayabilir. (method reuse)
//Program of this() constructor call (constructor chaining)
class Student13{int id;String name;
Student13(){System.out.println("default constructor is invoked");}
Student13(int id,String name){this ();//it is used to invoked current class constructor.this.id = id;this.name = name;
}void display(){System.out.println(id+" "+name);}
public static void main(String args[]){Student13 e1 = new Student13(111,"karan");Student13 e2 = new Student13(222,"Aryan");e1.display();e2.display();
}}
Test it Now
Output:
default constructor is invoked
default constructor is invoked
111 Karan
222 Aryan
class Student14{int id;String name;String city;
Student14(int id,String name){this.id = id;this.name = name;}Student14(int id,String name,String city){
this(id,name);//now no need to initialize id and namethis.city=city;
}void display(){System.out.println(id+" "+name+" "+city);}
public static void main(String args[]){Student14 e1 = new Student14(111,"karan");Student14 e2 = new Student14(222,"Aryan","delhi");e1.display();e2.display();
}}
Test it Now
Output:111 Karan null
222 Aryan delhi
Kural:this() çağrımı constructor’da ilk satırda yer almalıdır
this kelimesi derleyici tarafından kaynak koda otomatik eklenir.
this kelimesinin metoda formal parametre olarak gönderilmesi
• Genellikle olay yönetiminde (event handling) kullanılan bir yaklaşımdır.
class S2{
void m(S2 obj){System.out.println("method is invoked");}
void p(){m(this);}
public static void main(String args[]){S2 s1 = new S2();s1.p();}}
Kurucu metoda parametre olarak gönderilmesi• Herhangi bir metoda gönderilebildiği gibi kurucu metoda da
parametre olarak gönderilebilir. Bu özellik daha çok tek bir nesnenin birçok sınıf tarafından kullanılacağı durumlarda işimize yarar.
class B{A4 obj;B(A4 obj){
this.obj=obj;}void display(){System.out.println(obj.data);//using data member of A4 class}}
class A4{int data=10;A4(){B b=new B(this);b.display();}public static void main(String args[]){A4 a=new A4();}}
Metodun aktif sınıf örneğini geri döndürmesinde
• Burada dikkat edilmesi gereken nokta metod primitive tür yerine kendi sınıfının türünde bir nesneyi geri döndüreceğidir. O yüzden metod tasarlanırken geri dönüş türü kendi sınıfı olarak belirtilmelidir.
• this kelimesinin bu tarz kullanımı daha çok fluent interface ve methodchaining tasarım kalıplarında sıklıkla kullanılır.
• Open Cezeri Library (OCL) DSL kütüphanesindeki CMatrix sınıfı bu yaklaşımla geliştirilmiştir. https://github.com/hakmesyo/open-cezeri-library
Method Chaining
When to use it
Method Chaining can add a great deal to the readability of an internal DSL and as a result has
become almost a synonum for internal DSLs in some minds. Method Chaining is best, however,
when it's used in conjunction with other function combinations.
Method Chaining is particularly effective with grammars like parent::= (this | that)*. The use of
different methods provides readable way of seeing which argument is coming next. Similarly optional
arguments can be easily skipped over with Method Chaining. A list of mandatory clauses, such as
parent::= first second doesn't work so well with the basic form, although it can be supported well by
using progressive interfaces. Most of the time I'd prefer Nested Function for that case.
The biggest problem for Method Chaining is the finishing problem. While there are workarounds,
usually if you run into this you're better off using a Nested Function. Nested Function is also a better
choice if you are getting into a mess with Context Variables.
class A{A getA(){return this;}
void msg(){System.out.println("Hello java");}
}
class Test1{public static void main(String args[]){
new A().getA().msg();}
}
Kalıtım
• Bir sınıfın ata sınıfta tanımlı bütün özellik (states) ve davranışları (methods) devralmasıdır.
• Kalıtım OOP’de is-a yani bu-dur ilişkisidir.
• Türetilen yeni sınıf ata sınıftan miras yolu ile aldığı özellik ve metodlara ek olarak yeni özellikler (sınıf değişkenleri) ve metodlarekleyebilir veya varolan metodları yeniden tanımlayarak içeriğini değiştirerek kendisine has yaklaşımlar geliştirebilir.
• Kalıtım kod tekrar kullanılabilirliğini (code reuse) ve çalışma zamanı çok biçimliliğini sağladığı için kullanılmaktadır.
Syntax of Java Inheritance
class Subclass-name extends Superclass-name{//methods and fields
}
The extends keyword indicates that you are making a new class that derives from an
existing class.
In the terminology of Java, a class that is inherited is called a super class. The new
class is called a subclass.
class Employee{float salary=40000;}
class Programmer extends Employee{int bonus=10000;public static void main(String args[]){Programmer p=new Programmer();System.out.println("Programmer salary is:"+p.salary);System.out.println("Bonus of Programmer is:"+p.bonus);}}
Test it Now
Programmer salary is:40000.0
Bonus of programmer is:10000
In the above example, Programmer object can access the field of own
class as well as of Employee class i.e. code reusability.
Java’da Kalıtım Çeşitleri
• Tekli (single)
• Çoklu (Multilevel)
• Hiyerarşik (Hierarchical)
• Not: Java’da çoklu ve hibrid kalıtım sadece interface üzerinden yapılabilmektedir. İlerleyen derslerde ele alınacaktır.
Çoklu kalıtım Java’da desteklenmemektedir
Çoklu kalıtım Java’da neden desteklenmiyor?
• Dili basitleştirmek ve karmaşıklığı düşürmek için
• Belirsizliği gidermek için
• Mesela: A, B ve C isimli üç sınıfımız olduğunu farzedelim. C sınıfı A ve B sınıfından çoklu kalıtım ile türesin. A ve B sınıfında aynı metod imzasına sahip metodlar olduğunu düşünelim. OOP kalıtım prnesibinde göre C sınıfı ebeveyn sınıftan metodları devralır. Bu durumda C sınıfının bir örneği (nesnesi) isimleri aynı olan metodları çağırmada sorun yaşayacaktır. Yani hangi ata sınıfın metodunun çağrılacağı belirsizdir.
• Her zaman compile-time error (derlem zamanı hatası), run-time error’agöre daha iyi olduğundan Java’da çoklu kalıtım yazıldığında hata derleme hatası üretecektir.
Java’da diamond problemi
• https://www.linkedin.com/pulse/dealing-diamond-problem-java-saral-saxena
Araştırma Soruları
• Java’da diamond problemi nasıl çözülür?
• C++’da diamond problemi nasıl çözülür?