You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
/*---------------------------------------------------------------------------------------------------------------------- 04.10.2020 Bir sınıfın içerisinde tüm metotların dışında herhangi bir yerde static anahtar sözcüğü ile tanımlanan bloklara sınıfın static blokları (static initializers) denir. Sınıfın herhangi bir elamanı ilk kez kullanıldığında tüm static bloklar yukarıdan aşağıya doğru sırayla bir kez olmak üzere çalıştırılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Sample.foo();
System.out.println("////////////////////");
Sample.foo();
}
}
classSample {
static {
System.out.println("static initializer1");
}
//...static {
System.out.println("static initializer2");
}
static {
System.out.println("static initializer3");
}
publicstaticvoidfoo()
{
System.out.println("foo");
}
}
static bloklar (static initializers) (2)
/*---------------------------------------------------------------------------------------------------------------------- Bir sınıfın içerisinde tüm metotların dışında herhangi bir yerde static anahtar sözcüğü ile tanımlanan bloklara sınıfın static blokları (static initializers) denir. Sınıfın herhangi bir elamanı ilk kez kullanıldığında tüm static bloklar yukarıdan aşağıya doğru sırayla bir kez olmak üzere çalıştırılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Samples;
System.out.println("////////////////////////////////");
s = newSample();
}
}
classSample {
static {
System.out.println("static initializer1");
}
//...static {
System.out.println("static initializer2");
}
static {
System.out.println("static initializer3");
}
publicSample()
{
System.out.println("Sample.Sample()");
}
}
static bloklar static metotlar gibidir yani bu bloklarda sınıfın yalnızca static elemanlarına doğrudan erişilebilir
Sınıfın final static veri elemanlarına static bloklarda değer atanabilir.
/*---------------------------------------------------------------------------------------------------------------------- Sınıfın final static veri elemanlarına static bloklarda değer atanabilir. Şüphesiz burada değer atanabilmesi için bildirim noktasında atanmamış olması gerekir. Zaten static initilizer'ın en çok kullanıldığı durum da finale ve static veri elemanlara değer verilmesidir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
System.out.println(Sample.PI);
}
}
classSample {
publicstaticfinaldoublePI;
static {
PI = 3.14;
}
//...
}
Aşağıdaki örnekte static blok kullanılarak kod daha basit bir biçimde yazılmıştır.
/*---------------------------------------------------------------------------------------------------------------------- Aşağıdaki örnekte static blok kullanılarak kod daha basit bir biçimde yazılmıştır. static blok kullanmadan nasıl yaparsınız? Düşünün----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Random;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
System.out.println(Sample.VAL);
System.out.println(Sample.VAL2);
System.out.println("****************");
System.out.println(Sample.VAL);
System.out.println(Sample.VAL2);
}
}
classSample {
static {
Randomr = newRandom();
Scannerkb = newScanner(System.in);
System.out.print("min?");
intmin = Integer.parseInt(kb.nextLine());
System.out.print("max?");
intmax = Integer.parseInt(kb.nextLine());
VAL = r.nextInt(max - min) + min;
VAL2 = r.nextInt(max - min) + min;
}
publicstaticfinalintVAL;
publicstaticfinalintVAL2;
//...
}
Bir sınıf içerisindeki tüm static blokların kendi faaliyet alanları vardır.
/*---------------------------------------------------------------------------------------------------------------------- Bir sınıf içerisindeki tüm static blokların kendi faaliyet alanları vardır. Yani aslında bunlar ayrı metotlar gibi düşünülebilir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
System.out.println(Sample.VAL1);
System.out.println(Sample.VAL2);
}
}
classSample {
publicstaticfinalintVAL1;
publicstaticfinalintVAL2;
static {
System.out.println("static initializer1");
inta = 10;
VAL1 = a * 2;
}
static {
System.out.println("static initializer2");
inta = 20;
VAL2 = a * 3;
}
}
/*---------------------------------------------------------------------------------------------------------------------- Bir sınıfın non-static blokları (non-static initializer) olabilir. Bu bloklar ctor'ların başında çalıştırılır. Yani adeta bu bloklar her ctor'un başına gizlice eklenir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Samples = newSample();
System.out.println("*****************");
Samplek = newSample();
//...
}
}
classSample {
{
System.out.println("non-static initializer1");
}
{
System.out.println("non-static initializer2");
}
}
non-static bloklar (non-static initializer) (2)
/*---------------------------------------------------------------------------------------------------------------------- Bir sınıfın non-static blokları (non-static initializer) olabilir. Bu bloklar ctor'ların başında çalıştırılır. Yani adeta bu bloklar her ctor'un başına gizlice eklenir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Samples = newSample();
System.out.println("*****************");
Samplek = newSample(10);
//...
}
}
classSample {
{
System.out.println("non-static initializer1");
}
{
System.out.println("non-static initializer2");
}
publicSample()
{
System.out.println("Sample.Sample()");
}
publicSample(inta)
{
System.out.println("Sample.Sample(int)");
}
}
Bir sınıfın ctor'u içerisinde o sınıfın başka bir ctor'unun çağrılması kodu yazılmışsa (this ctor) bu durumda çağıran için non-static initializer kodu yerleştirilmez.
/*---------------------------------------------------------------------------------------------------------------------- Bir sınıfın ctor'u içerisinde o sınıfın başka bir ctor'unun çağrılması kodu yazılmışsa (this ctor) bu durumda çağıran için non-static initializer kodu yerleştirilmez. Çünkü zaten çağrılan ctor' da ya olacaktır ya da o da başka bir ctor'u çağırsa da sonuçta çalıştırılacak bir non-static blok mutlaka olacaktır. Yani bir non-static initializer nesne başına bir kez çağrılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Samples1 = newSample();
System.out.println("**********************");
Samples2 = newSample(10);
System.out.println("**********************");
Samples3 = newSample(3.4);
//...
}
}
classSample {
{
System.out.println("non-static initializer");
}
publicSample(doublea)
{
System.out.println("Sample.Sample(double)");
}
publicSample()
{
this(Math.PI);
System.out.println("Sample.Sample()");
}
publicSample(inta)
{
this();
System.out.println("Sample.Sample(int)");
}
}
super ctor sentaksı kullanıldığında non-static blokların çalıştırılma sırası
Aşağkdaki sınıfta public bölümde hiç static eleman olmadığından müşteri kodlar nesne yaratmadan bu sınıfı kullanamazlar.
/*---------------------------------------------------------------------------------------------------------------------- Aşağkdaki sınıfta public bölümde hiç static eleman olmadığından müşteri kodlar nesne yaratmadan bu sınıfı kullanamazlar. İlk nesne yaratılırken sınıfın static bloğu çalıştırılacağından diğer nesneler aynı MIN ve MAX değerlerini kullanacaktır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Random;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Samples = newSample();
System.out.printf("s.val=%d%n", s.val);
Samplek = newSample();
System.out.printf("k.val=%d%n", k.val);
}
}
classSample {
privatestaticfinalRandomRAND;
privatestaticfinalScannerKB;
privatestaticfinalintMIN;
privatestaticfinalintMAX;
publicfinalintval;
static {
RAND = newRandom();
KB = newScanner(System.in);
System.out.print("min?");
MIN = Integer.parseInt(KB.nextLine());
System.out.print("max?");
MAX = Integer.parseInt(KB.nextLine());
}
{
val = RAND.nextInt(MAX - MIN) + MIN;
}
}
Türemiş sınıfı içerisinde taban sınıfta bulunan non-static bir veri elemanı ile aynı isimde veri elemanı bildirilebilir.
/*---------------------------------------------------------------------------------------------------------------------- Türemiş sınıfı içerisinde taban sınıfta bulunan non-static bir veri elemanı ile aynı isimde veri elemanı bildirilebilir. Bu durumda türemiş sınıf içerisindeki veri elemanı taban sınıf veri elemanı ismini maskeler (shadowing, masking). Aşağıdaki örnekte b referansı ile B içerisinde bildirilen x veri elemanına, a referansı ile a'nın gösterdiği B nesnesinin (dinamik türünün) A bölümündeki x veri elemanına erişilir. Artık B türü üzerinden A sınıfının x veri elemanına erişilemez. Bu anlatılanlar sınıf dışından erişimler için geçerlidir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Bb = newB();
b.x = 10;
System.out.printf("b.x=%d%n", b.x);
Aa = b;
System.out.printf("a.x=%d%n", a.x);
}
}
classBextendsA {
publicintx;
//...
}
classA {
publicintx;
//...
}
super referansı ile taban sınıfın bir elemanına erişilebilir.
/*---------------------------------------------------------------------------------------------------------------------- super referansı ile taban sınıfın bir elemanına erişilebilir. Aşağıdaki örnekte setValues metodu ile hem taban hem de türemiş sınıfta aynı isimde bulunan veri elemanlarına atama yapılmıştır. super referansı ile taban sınıfın bir metodu da çağrılabilir. Bu konunun detayları ileri ele alınacaktır. Örnekte super.x erişiminde super referansının kaldırırarak sonucu inceleyiniz----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Bb = newB();
b.setValues(10, 20);
System.out.printf("b.x=%d%n", b.x);
Aa = b;
System.out.printf("a.x=%d%n", a.x);
}
}
classBextendsA {
publicintx;
publicvoidsetValues(inta, intb)
{
x = a; //this.x = a;super.x = b;
super.foo();
}
//...
}
classA {
publicintx;
publicvoidfoo()
{
}
//...
}
Türemiş sınıf içerisinde taban sınıfta bulunan static bir veri elemanı ile aynı isimde bir veri elemanı bildirilebilir
/*---------------------------------------------------------------------------------------------------------------------- Türemiş sınıf içerisinde taban sınıfta bulunan static bir veri elemanı ile aynı isimde bir veri elemanı bildirilebilir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
B.setValues(10, 20);
System.out.printf("B.x=%d%n", B.x);
System.out.printf("A.x=%d%n", A.x);
}
}
classBextendsA {
publicstaticintx;
publicstaticvoidsetValues(inta, intb)
{
x = a;
A.x = b;
}
//...
}
classA {
publicstaticintx;
//...
}
Çok biçimlilik (polymorphism)
/*---------------------------------------------------------------------------------------------------------------------- Çok biçimlilik (polymorphism): Biyolojiden programlamaya aktarılmıştır. Biyolojide çok biçimlilik: "Farklı doku ya da organların evrim süreci içerisinde temel işlevleri aynı kalması koşuluyla, bu işlevi yerine getirme biçiminin değişmesidir" şeklinde tanımlanabilir. Örneğin duyma eylemi (davranışı) birbirlerinde türetilmiş canlılar arasında farklılık gösterebilir. Fakat görev "duymaktır" Nesne yönelimli programlama tekniğinde aşağıda anlatılan çpk biçimliliğe "çalışma zamanı çk biçimliliği (runtime polymorphism")" denir. Aslında çok biçimlilik çalışma zamanı ve derleme zamanı çok biçimliliği olarak iki gruba ayrılabilir. Biyoloji'den programlamaya aktarılan çok biçimlilik çalışma zamanı çok biçimliliğidir. Çoğu zaman çalışma zamanın çok biçimliliği yerine doğprudan "çok biçimlilik" denir. Çalışma zamanı çok biçimliliği için çok fazla tanım ya da açıklama yapılabilse de aşağıdaki 3(üç) tanım ile bu kavram anlatılabilir: 1. Biyolojik tanım: Taban sınıfın bir fonksiyonunun türemiş sınıfta yeniden gerçekleştirilmesidir 2. Yazılım mühendisliği tanım: Türden bapımsız kod yazmaktır. Yani bir kavramın çok sayıda türevi olsa da türevlerden bağımsız olarak sadece o kavram üzerinde kod yazmaktır. 3. Aşağı seviyeli tanım: Önceden yazılmış kodların sonradan yazılmış kodları çağırabilmesidir. Java'da çok biçimlilik sanal metotlar (virtual method) kullanılarak gerçekleştirilir. Java' da non-static olan ve final olmayan her metot sanaldır. İleride bunun dışında da sanal olan metotlar antalıcaktır. Sanal bir metodun türemiş sınıfta geri dönüş değeri ve imzası aynı olacak şekilde yazılmasına "override" denir. override işleminde erişim belirleyicinin durumu ileride ele alınacaktır. Yani örneğin "public bir metodu override edebilir miyim?" sorusunın detayları ayrıca cevaplanacaktır. Ancak public bir metot public olarak override edilmelidir----------------------------------------------------------------------------------------------------------------------*/
non-static bir metot çağrısında metot sanal ise derleyici "çalışma zamanında referansın dinamik türüne bak, dinamik türe ilişkin sınıfta metot override edilmişse onu çağır" kodunu üretir
/*---------------------------------------------------------------------------------------------------------------------- non-static bir metot çağrısında metot sanal ise derleyici "çalışma zamanında referansın dinamik türüne bak, dinamik türe ilişkin sınıfta metot override edilmişse onu çağır" kodunu üretir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
classApp {
publicstaticvoidmain(String [] args)
{
Bx = newB();
Ay;
y = x;
y.foo();
}
}
classBextendsA {
publicvoidfoo() //override
{
System.out.println("B.foo");
}
}
classA {
publicvoidfoo()
{
System.out.println("A.foo");
}
}
non-static method ve override edilerek çalışması
/*---------------------------------------------------------------------------------------------------------------------- non-static bir metot çağrısında metot sanal ise derleyici "çalışma zamanında referansın dinamik türüne bak, dinamik türe ilişkin sınıfta metot override edilmişse onu çağır" kodunu üretir. Aşağıdaki örnekte main metodunun içindeki müşteri kodu A sınıfından türetilenlerden bağımsız olarak yazılmıştır. Yani türden bağımsız yazılmıştır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
returnval % 2 == 0 ? newB() : newA();
}
}
classBextendsA {
publicvoidfoo(intval) //override
{
System.out.println("B.foo");
}
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
Yukarıdaki örneğe C sınıfı eklenmesine rağmen main içerisinde kodlar bundan etkilenmemiştir (türden bağımsızlık)
/*---------------------------------------------------------------------------------------------------------------------- Yukarıdaki örneğe C sınıfı eklenmesine rağmen main içerisinde kodlar bundan etkilenmemiştir (türden bağımsızlık)----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newA();
returnx;
}
}
classCextendsA {
publicvoidfoo(intval) //override
{
System.out.println("C.foo");
}
}
classBextendsA {
publicvoidfoo(intval) //override
{
System.out.println("B.foo");
}
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır
/*---------------------------------------------------------------------------------------------------------------------- Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newA();
returnx;
}
}
classCextendsB {
}
classBextendsA {
publicvoidfoo(intval) //override
{
System.out.println("B.foo");
}
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır (2)
/*---------------------------------------------------------------------------------------------------------------------- Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newA();
returnx;
}
}
classCextendsB {
}
classBextendsA {
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır (3)
/*---------------------------------------------------------------------------------------------------------------------- Sanal metot dinamik türe ilişkin sınıfta override edilmemişse sırasıyla taban sınıflar bakılır. İlk bulunan metot çağrılır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newA();
returnx;
}
}
classCextendsB {
publicvoidfoo(intval)
{
System.out.println("C.foo");
}
}
classBextendsA {
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
override edilen metot içerisinde "augmatation" işlemi
/*---------------------------------------------------------------------------------------------------------------------- Bazen override edilen metot içerisinde taban sınıfının ilgili metodu da çağrılmak istenebilir. Bu durumda super referansı kullanılmalıdır. Bu işleme "augmatation" da denir----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newA();
returnx;
}
}
classCextendsB {
publicvoidfoo(intval)
{
System.out.println("C.foo");
super.foo(val); //augmetation
}
}
classBextendsA {
publicvoidfoo(intval)
{
System.out.println("B.foo");
super.foo(val); //augmetation
}
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}
Yukarıdaki örneğe D sınıfı eklenmesine rağmen yine müşteri kodları etkilenmemiştir.
/*---------------------------------------------------------------------------------------------------------------------- Yukarıdaki örneğe D sınıfı eklenmesine rağmen yine müşteri kodları etkilenmemiştir. Ayrıca taban sınıfın ilgili metodunu çağırma kuralına D için de bu senaryoda uyulduğundan D için de program doğru çalışmıştır----------------------------------------------------------------------------------------------------------------------*/packageorg.csystem.app;
importjava.util.Scanner;
classApp {
publicstaticvoidmain(String [] args)
{
Factoryfactory = newFactory();
Scannerkb = newScanner(System.in);
System.out.print("Bir sayı giriniz:");
intval = Integer.parseInt(kb.nextLine());
Ax;
x = factory.getInstance(val);
x.foo(23);
}
}
classFactory {
//...publicAgetInstance(intval)
{
Ax;
if (val > 0)
x = newB();
elseif (val == 0)
x = newC();
elsex = newD();
returnx;
}
}
classDextendsC {
publicvoidfoo(inta)
{
System.out.println("D.foo");
super.foo(a);
}
}
classCextendsB {
publicvoidfoo(intval)
{
System.out.println("C.foo");
super.foo(val); //augmetation
}
}
classBextendsA {
publicvoidfoo(intval)
{
System.out.println("B.foo");
super.foo(val); //augmetation
}
}
classA {
publicvoidfoo(intval)
{
System.out.println("A.foo");
}
}