1. Tip Tahmini
Referans tiplerini (sınıfları) saklayan değişkenler de farklı tiplere dönüştürülebilir. Ancak bu yalnızca tek bir tür hiyerarşisi içinde çalışır. Basit bir örneğe bakalım. Aşağıdaki sınıfların yukarıdaki sınıfları miras aldığı aşağıdaki sınıf hiyerarşisine sahip olduğumuzu varsayalım.
İlkel türlerin yanı sıra referans türlerinin tip tahmini de genişletme ve daraltma olarak kategorize edilir.
Cat sınıfının Pet sınıfını ve Pet sınıfının da Animal sınıfını miras aldığını görüyoruz.
Şöyle bir kod yazarsak:
Animal kitten = new Cat();
Bu, genişleyen bir tür dönüştürmedir . Aynı zamanda örtük döküm olarak da adlandırılır. cat referansını, artık bir Cat nesnesine atıfta bulunacak şekilde genişlettik . Bunun gibi bir tür dönüştürme ile, Cat sınıfında bulunan ancak Animal sınıfında olmayan yöntemleri çağırmak için yavru kedi referansını kullanamayacağız .
Ters yönde bir daraltma dönüştürmesi (veya açık atama) gerçekleşir:
Cat cat = (Cat) kitten;
Kitty değişkeninde (tipi Animal olan ) saklanan referansı Cat tipine dönüştürmek istediğimizi açıkça belirttik .
2. Bir nesnenin türünü kontrol etme
Ancak burada çok dikkatli olmalısınız. Eğer bunu yaparsan:
Animal beast = new Cat(); Wolf grayWolf = (Wolf) beast;
Derleyici bu koda izin verecektir, ancak program çalışırken bir hata olacaktır ! JVM bir istisna atar:
Exception in thread "main" java.lang.ClassCastException: Cat cannot be cast to a Wolf
Bir Cat nesnesine yapılan başvurular, yalnızca türü Cat sınıfının atası olan değişkenlerde saklanabilir: Pet, Animal veya Object.
Nedenmiş?
Buradaki ilgili nokta, bir nesne referansının, o nesnenin yöntemlerine ve değişkenlerine atıfta bulunmak için kullanılmasıdır . Ve bir Cat nesnesine referans depolamak için bir Animal değişkeni kullanırsak herhangi bir sorun olmaz: Cat türü her zaman Animal türünden değişkenlere ve yöntemlere sahiptir — onları miras almıştır!
Ancak JVM, bir Cat nesnesine bir başvuruyu bir Wolf değişkeninde saklamamıza izin verdiyse, o zaman o değişkende depolanan Cat nesnesinde bulunmayan bir yöntemi çağırmak için grayWolf değişkenini kullanmayı deneyebileceğimiz bir durumla karşılaşabiliriz. . Bu yüzden bu düzenlemeye izin verilmiyor.
instanceofJava , bir nesnenin belirli bir türde olup olmadığını ve bu nedenle belirli bir türdeki bir değişkende depolanabileceğini kontrol etmenizi sağlayan özel bir operatöre sahiptir . Oldukça basit görünüyor:
variable instanceof Type
Örnek:
Animal beast = new Cat(); if (beast instanceof Wolf) { Wolf grayWolf = (Wolf) beast; }
Bu kod, çalışma zamanında bile hatalara neden olmaz.
İşte durumu gösteren birkaç örnek daha:
|Genişletme tipi dönüştürme||Tanım|


Bu, klasik bir genişletme dönüştürmesidir - tür dönüştürme operatörü gerekmez. Artık nesne üzerinde yalnızca sınıfta tanımlanan yöntemler
değişkeninde
|Daraltma tipi dönüştürme|


||Klasik daraltma dönüştürmesi: Bir tür denetimi ve bir atama işleci eklemeniz gerekir.


Değişken
Durumun böyle olduğunu doğrularız ve ardından bir (daraltma) tür dönüştürmesi gerçekleştiririz. Veya şu şekilde de adlandırılır:
bir tip döküm.


||Nesnenin tipini kontrol etmeden bir referans tipini daraltabilirsiniz.


Değişken
3. Orijinal yöntemi çağırmak:
superanahtar kelime
Bir üst sınıfın yöntemini geçersiz kılarken, bazen onu kendi yöntemimizle değiştirmek yerine, onu yalnızca biraz tamamlamak isteriz.
Ana sınıfın yöntemini kendi yöntemimizde kullanabilsek ve sonra kendi kodumuzun bir kısmını çalıştırabilsek harika olurdu. Ya da belki önce kendi kodumuzu çalıştırın ve sonra üst sınıfın yöntemini çağırın.
Ve Java tam da bunu yapmamıza izin veriyor. Üst sınıfın bir yöntemini çağırmak için şunu yapın:
super.method(arguments);
Örnekler:
class PeaceTime { public double getPi() { return 3.14; } } class WarTime extends PeaceTime { public double getPi() { return super.getPi()*2; // 3.14*2 } }
Savaş zamanında değeri
Pi6'dan büyük olabilir! Elbette şaka yapıyoruz, ancak bu örnek tüm bunların nasıl çalışabileceğini gösteriyor.
İşleri biraz netleştirmek için birkaç örnek daha:
|kod||Tanım|


||Ekran çıktısı şöyle olacaktır:


Bu zor bir şey. Dürüst olmak gerekirse, OOP'deki en zor şeylerden biri . Bununla birlikte, onu bilmeniz ve anlamanız gerekiyor.