İleri düzeyde C programlama öğrendiğimden beri memory yönetimine(dynamic memory allocation) ve yazdığım kodlar içinde memory kullanımına dikkat etmeye başladım. Son günlerde uzun bir ara verdiğin Java ya hızlı bir geri dönüş yaptım ve eskiden kalma alışkanlıklarımın sürdüğünün farkına vardım ve bunu değiştirme kararı aldım kendimce. Nese önce yazdığım kod bloklarını incelemeye koyuldum ve bir çok yerde ihtiyacımdan fazla nesne türetiğimin farkına vardım ve system üzerinden memory kullanımını incelemeye başladım. Daha sonra tanımlayıp kullanmadığım nesneleri kapatıp yazdığım kodu tekrar derledim ve memory i incelemeye koyuldum. Çok ciddi fark olmasada run time de memory kullanımının daha da azaldığını gördüm. Bu olayı C dilinde kendim rahatça handle edebiliyordum fakat Javada nesneler çoğaldıkça bu iş karmaşıklaşıyordu bunun kontrolü gittikçe zorlaşıyordu bunun farkındaydım ve bu durum için birşeyler olabilirmi diye düşünmeye koyuldum aynı zamanda netten de bakııyordum. Neyseki aramalarım çok uzun sürmeden Garbage Collections ın varlığından haberdar oldum. Bu konu hakkında araştırmamı sürdürürken garbage collectionsların run time da programcıdan habersiz çalıştıklarını öğrendim yani benim memory kullanımına dair endişem birazda boşunaymış java memory optimizasyonunu otomatik olarak garbage collector ler sayesinde yapıyormuş. Bu olayı okyunca Java nın bir kez daha çok güçlü ve bir okadarda düşünceli :) bir dil olduğu kanısına vardım. Garbage Collections run time de random bir zamanda kendi kendiliğinden çalışıyor fakat bunu programcı istediği zaman tetikleyebiliyor.
Garbage Collections Java.lang.system kütüphanesinin içinde mevcut ve istediğimiz bir yerde System.gc(); olarak çağırdığımızda manuel olarakta tetiklemiş oluyoruz ve collectorumuz çalışıp memory deki çöpleri topluyor ve yer açıyor.
public class CheckGC {
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
System.out.println("Total JVM memory: " + rt.totalMemory());
System.out.println("Before Memory = " + rt.freeMemory());
Date d = null;
for (int i = 0; i < 10000; i++) {
d = new Date();
d = null;
}
System.out.println("After Memory = " + rt.freeMemory());
System.gc();
System.out.println("After GC Memory = "+ rt.freeMemory());
}
}
//Console Output
Total JVM memory: 5177344
Before Memory = 4660704
After Memory = 4403968
After GC Memory = 5011864
Bu yaziyi direk bu linkten kopyaladim kisa oz yazilmis Emrah Mete hocamizin elerine saglikhttp://emrahmete.blogcu.com/java-garbage-collection/4899593
Monday, September 20, 2010
Wrapper Classes
Wrapper classes ne oldugunu anlatmadan evel birkac seyi hatirlayalim.
Java programlama dilinde iki tür değişken tipi vardır,
Reference Types : Referans tipleri sınıflar ve arraylar dir. Referans tipleri değer tiplerinin aksine metodlara geçtiğimizde kopyaları üzerinden işlem yapılmazlar, mevcut nesneler üzerinden işlem yapılırlar.
Wrapper Classes : Java da program yazarken bazen Primitive tiplerin yukarıdaki gibi başka bir sınıf tarafından sarmalanmasına ihtiyaç duyarız. Özellikle collections sınıfları ile çalışıyorsak bu kaçınılmazdır.
Bunun sebebi collections nesneleri içerlerinde sadece object tutabilirler. Eğer biz bir collections nesnesinin içerisinde bir Primitive tip tutmak istiyorsak mecburen o Primitive tipi başka bir sınıf ile sarmalamamız gerekecek. Bu yüzden Java da java.lang package altında her ilkel tip için bir sarmalayıcı (wrapper classes) sınıf vardır.
Bir Primitive tipi bir wrapper class sınıf içerisine koyma işlemine Boxing (kutulama), wrapper class'in içerisinden Primitive tipi geri alma işleminede Unboxing (kutudan çıkarma) işlemi denilmektedir.
int x = 100;
Integer box = new Integer (x); //BOXING
int y = box.intValue(); //UNBOXING
Java 5.0 dan önce her wrapper sınıf kullandığımızda mecburen boxing ve unboxing işlemi yapmak zorundaydık.Fakat Java 5.0 ile artık bunu yapmak zorunda değiliz.Çünkü bu işlem Java 5.0 tarafından otomatik olarak yapılıyor.
Aşağıdaki kod örnekleri Java 5.0 dan önce hangi durumlarda hatalarla karşılaşacağımızı göstermektedir.
Integer i = new Integer(100);
i++; //ERROR
Integer x = new Integer(12);
Integer y = new Integer(13);
Integer z = x + y; //ERROR
int a = new Integer(99); //ERROR
Integer b = 555; //ERROR
int w = 100;
Vector v = new Vector();
v.add(w); //ERROR
int k = 777;
Integer l = new Integer(333);
int m = k + l; //ERROR
Fakat aynı kodu Java 5.0 ile derlerseniz hiçbir hata ile karşılaşmazsınız, sebebi Boxing veya Unboxing işlemlerinin gereken yerlerde Java 5.0 ile gelen Autoboxing/Unboxing özelliği sayesinde otomatik olarak yapılıyor olmasıdır.
Önemli Nokta;
Wrapper sınıflar immutable (değişmez) özelliğe sahiptirler, sıradan nesneler gibi davranmazlar.
Bu yaziyi yazarken http://www.csharpnedir.com kaynaktan yararlandim yazar arkadasimizi eline saglik
Java programlama dilinde iki tür değişken tipi vardır,
- Primitive Types
- Reference Types
Reference Types : Referans tipleri sınıflar ve arraylar dir. Referans tipleri değer tiplerinin aksine metodlara geçtiğimizde kopyaları üzerinden işlem yapılmazlar, mevcut nesneler üzerinden işlem yapılırlar.
Wrapper Classes : Java da program yazarken bazen Primitive tiplerin yukarıdaki gibi başka bir sınıf tarafından sarmalanmasına ihtiyaç duyarız. Özellikle collections sınıfları ile çalışıyorsak bu kaçınılmazdır.
Bunun sebebi collections nesneleri içerlerinde sadece object tutabilirler. Eğer biz bir collections nesnesinin içerisinde bir Primitive tip tutmak istiyorsak mecburen o Primitive tipi başka bir sınıf ile sarmalamamız gerekecek. Bu yüzden Java da java.lang package altında her ilkel tip için bir sarmalayıcı (wrapper classes) sınıf vardır.
Bir Primitive tipi bir wrapper class sınıf içerisine koyma işlemine Boxing (kutulama), wrapper class'in içerisinden Primitive tipi geri alma işleminede Unboxing (kutudan çıkarma) işlemi denilmektedir.
int x = 100;
Integer box = new Integer (x); //BOXING
int y = box.intValue(); //UNBOXING
Java 5.0 dan önce her wrapper sınıf kullandığımızda mecburen boxing ve unboxing işlemi yapmak zorundaydık.Fakat Java 5.0 ile artık bunu yapmak zorunda değiliz.Çünkü bu işlem Java 5.0 tarafından otomatik olarak yapılıyor.
Aşağıdaki kod örnekleri Java 5.0 dan önce hangi durumlarda hatalarla karşılaşacağımızı göstermektedir.
Integer i = new Integer(100);
i++; //ERROR
Integer x = new Integer(12);
Integer y = new Integer(13);
Integer z = x + y; //ERROR
int a = new Integer(99); //ERROR
Integer b = 555; //ERROR
int w = 100;
Vector v = new Vector();
v.add(w); //ERROR
int k = 777;
Integer l = new Integer(333);
int m = k + l; //ERROR
Fakat aynı kodu Java 5.0 ile derlerseniz hiçbir hata ile karşılaşmazsınız, sebebi Boxing veya Unboxing işlemlerinin gereken yerlerde Java 5.0 ile gelen Autoboxing/Unboxing özelliği sayesinde otomatik olarak yapılıyor olmasıdır.
Önemli Nokta;
Wrapper sınıflar immutable (değişmez) özelliğe sahiptirler, sıradan nesneler gibi davranmazlar.
Bu yaziyi yazarken http://www.csharpnedir.com kaynaktan yararlandim yazar arkadasimizi eline saglik
Initialization Blocks(Class'ta Bloglarin Calisma Prensibi )
Bu yazimda bir class icinde bloglar hangi siraya gore calistigi hakinda bir ugulama ile anlatmaya calisacam. Ama uygulamaya gecmeden sunlar demek istiyorum blog kavrami biraz genitir yani blog deyince akliniza hemen method gelmesi mesele bir kac blog cesidi yazayim
class Init {
static {
System.out.println("1 static init");
}
static {
System.out.println("2 static init");
}
{
System.out.println("1 instance init");
}
{
System.out.println("2 instance init");
}
Init() {
System.out.println("1 constructor init");
}
Init(int x) {
System.out.println("2 constructor init");
}
Init(int x , int y) {
System.out.println("3 constructor init");
}
}
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
Aslinda su olay gerceklesir bir sinif ilk cagirildigida once sinifa remde bir yer ayriliyor ve bu yere ayni zamanda static olan tum nesneler , methodlar , bloglar yukleniyor ve yuklenmesi demek bir kere calismasi demekoluyor ama her Init class'mizi cagirdik ve remde yer olusturdu ondan sonra her Init icin olusturulan referansta tabiki program sonlanmadigi surece remde yer olusturmaz cunku artik vardir. Sadece Init ile ilgili olusturulan her referansta normal bloglar her seferinde yenide calistirilir
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
Init i1 = new Init(22);
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
1 instance init
2 instance init
2 constructor init
Yukardaki yazdigim aciklama biraz karisik gibi gelsede ikinci olusturdugum InitMain ile hersey daha iyi anlasilir. Goruldiyi gibi TestMain calistirdigimizda ilk once Init class remde yer ayrilip olusuyor ve onunla beraber static bloglarimizda olusyor yani calisiyor ve referans olusturdugun icin normal bloglarimda bir kere calistir ve tabiki cagirilan constructor calisir. ama ikinsi satirda tekrar Init'in referansi olustururken sadece bloglar calisir ve constructor calisir yani static bloglar tekrar calismaz.
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
Init i1 = new Init(22);
Init i2 = new Init(22,11);
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
1 instance init
2 instance init
2 constructor init
1 instance init
2 instance init
3 constructor init
Bir uygulama daha yapip konuyu daha iyi analayalim
public class Bird {
static {
System.out.print("A");
}
{
System.out.print("K");
}
public Bird() {
System.out.print("A");
}
}
public class Raptor extends Bird {
static {
System.out.print("B");
}
public Raptor() {
System.out.print("I");
}
{
System.out.print("D");
}
static {
System.out.print("D");
}
}
public class Hawk extends Raptor {
static {
System.out.print("U");
}
public Hawk() {
System.out.print("4");
}
{
System.out.print("R");
}
public static void main(String args[]){
System.out.print("L");
new Hawk();
System.out.println("7");
}
}
//Console Output
ABDULKADIR47
- public class TestBlockClass{}
- public void testBlockMethod (){}
- public TestBlockClass(){}
- static {}
- {}
class Init {
static {
System.out.println("1 static init");
}
static {
System.out.println("2 static init");
}
{
System.out.println("1 instance init");
}
{
System.out.println("2 instance init");
}
Init() {
System.out.println("1 constructor init");
}
Init(int x) {
System.out.println("2 constructor init");
}
Init(int x , int y) {
System.out.println("3 constructor init");
}
}
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
Aslinda su olay gerceklesir bir sinif ilk cagirildigida once sinifa remde bir yer ayriliyor ve bu yere ayni zamanda static olan tum nesneler , methodlar , bloglar yukleniyor ve yuklenmesi demek bir kere calismasi demekoluyor ama her Init class'mizi cagirdik ve remde yer olusturdu ondan sonra her Init icin olusturulan referansta tabiki program sonlanmadigi surece remde yer olusturmaz cunku artik vardir. Sadece Init ile ilgili olusturulan her referansta normal bloglar her seferinde yenide calistirilir
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
Init i1 = new Init(22);
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
1 instance init
2 instance init
2 constructor init
Yukardaki yazdigim aciklama biraz karisik gibi gelsede ikinci olusturdugum InitMain ile hersey daha iyi anlasilir. Goruldiyi gibi TestMain calistirdigimizda ilk once Init class remde yer ayrilip olusuyor ve onunla beraber static bloglarimizda olusyor yani calisiyor ve referans olusturdugun icin normal bloglarimda bir kere calistir ve tabiki cagirilan constructor calisir. ama ikinsi satirda tekrar Init'in referansi olustururken sadece bloglar calisir ve constructor calisir yani static bloglar tekrar calismaz.
public class InitMain {
public static void main(String[] args) {
Init i = new Init();
Init i1 = new Init(22);
Init i2 = new Init(22,11);
}
}
//Console Output
1 static init
2 static init
1 instance init
2 instance init
1 constructor init
1 instance init
2 instance init
2 constructor init
1 instance init
2 instance init
3 constructor init
Bir uygulama daha yapip konuyu daha iyi analayalim
public class Bird {
static {
System.out.print("A");
}
{
System.out.print("K");
}
public Bird() {
System.out.print("A");
}
}
public class Raptor extends Bird {
static {
System.out.print("B");
}
public Raptor() {
System.out.print("I");
}
{
System.out.print("D");
}
static {
System.out.print("D");
}
}
public class Hawk extends Raptor {
static {
System.out.print("U");
}
public Hawk() {
System.out.print("4");
}
{
System.out.print("R");
}
public static void main(String args[]){
System.out.print("L");
new Hawk();
System.out.println("7");
}
}
//Console Output
ABDULKADIR47
Friday, September 17, 2010
Varargs
Java 5.0'ın bize sundugu guzel bir kullanim Array farkli bir tanim sekli ama yapilan islem ayni Arrayda yaptigimiz bir cok islemden bizi kurtariyor. Asagidaki uygulamayi gorunce dedigimi daha iyi anliyacaksiniz. Vararg'ler su sekilde tanimlanir.
String str...
int i...
Long l...
Burda dikkat etmemiz gereken method parametresi olarak kullanildigi.
public class VarargsTest {
public static void main(String args[] ){
names("Abdulkadir" ,"Ertugrul","Rasim","Nazim");
}
public static void names(String... name){
for (String n : name) {
System.out.println("Name : "+n);
}
}
}
//Console Output
Name : Abdulkadir
Name : Ertugrul
Name : Rasim
Name : Nazim
public class VarargsTest {
public static void main(String args[] ){
String name[]={"Abdulkadir","Ertugrul","Rasim","Nazim"};
names(name);
}
public static void names(String... name){
for (String n : name) {
System.out.println("Name : "+n);
}
}
}
//Console Output
Name : Abdulkadir
Name : Ertugrul
Name : Rasim
Name : Nazim
public class VarargsTest {
public static void main(String args[] ){
System.out.println("2 + 6 = "+toplama(2,6));
}
public static int toplama(int... sayi){
int sonuc = 0;
for (int n : sayi) {
sonuc = sonuc + n;
}
return sonuc;
}
}
//Console Output
2 + 6 = 8
String str...
int i...
Long l...
Burda dikkat etmemiz gereken method parametresi olarak kullanildigi.
public class VarargsTest {
public static void main(String args[] ){
names("Abdulkadir" ,"Ertugrul","Rasim","Nazim");
}
public static void names(String... name){
for (String n : name) {
System.out.println("Name : "+n);
}
}
}
//Console Output
Name : Abdulkadir
Name : Ertugrul
Name : Rasim
Name : Nazim
public class VarargsTest {
public static void main(String args[] ){
String name[]={"Abdulkadir","Ertugrul","Rasim","Nazim"};
names(name);
}
public static void names(String... name){
for (String n : name) {
System.out.println("Name : "+n);
}
}
}
//Console Output
Name : Abdulkadir
Name : Ertugrul
Name : Rasim
Name : Nazim
public class VarargsTest {
public static void main(String args[] ){
System.out.println("2 + 6 = "+toplama(2,6));
}
public static int toplama(int... sayi){
int sonuc = 0;
for (int n : sayi) {
sonuc = sonuc + n;
}
return sonuc;
}
}
//Console Output
2 + 6 = 8
Passing Variables into Methods
Bu yazida method icindeki degiskenlerin bir kac deger verildikten sonra en son hangi degeri sakladiklarini ele alacam basit bir konu ama dikkat gerektiriyor. Ben bu yaziyi ornekler uzerinde anlatmanin daha iyi olacagini dusunerekten ilk uygulamama basliyom.
public static void main(String args[]) {
int value = 1;
System.out.println("Before : " + value);
modify(value);
System.out.println("After : " + value);
}
public static void modify(int valueOne) {
valueOne = valueOne + 2;
System.out.println("Modify : " + valueOne);
}
}
//Console Output
Before : 1
Modify : 3
After : 1
Gorulduyu gibi oncelikle value ilk basta 1 degerini aliyor ve sonra modify methodu cagiriliyor ve methodun parametresi valueOne'ye 1 degeri veriliyor modify methodu 1 deger ile 2 degerini topluyor ve valueOne 3 oluyor ve sonraki satirda value'nin degerine bakilinca hicbir degisiklik olmaz yani value yine 1 olur. Sebebi ise her primitive tip degerini farkli adreste saklar. Birde uygulamada value degerini modify(int valueOne) verince sadece degeri vermis oluyorum degeri kaydettikleri adreste herhangi bir degisme olmuyor
public String name;
public String surname;
}
public class ReferenceTest {
public static void main(String[] args) {
Student studentOne = new Student();
studentOne.name = "Abdulkadir";
studentOne.surname = "Selcukoglu";
System.out.println("Before : " + studentOne.name + " " + studentOne.surname);
modify(studentOne);
System.out.println("After : " + studentOne.name + " " + studentOne.surname);
}
static void modify(Student studentTwo) {
studentTwo.name = "Ertugrul";
studentTwo.surname = "Aslan";
System.out.println("Modify : " + studentTwo.name + " " + studentTwo.surname);
}
}
public class ReferenceTest {
public static void main(String[] args) {
Student studentOne = new Student();
studentOne.name = "Abdulkadir";
studentOne.surname = "Selcukoglu";
System.out.println("Before : " + studentOne.name + " " + studentOne.surname);
modify(studentOne);
System.out.println("After : " + studentOne.name + " " + studentOne.surname);
}
static void modify(Student studentTwo) {
studentTwo.name = "Ertugrul";
studentTwo.surname = "Aslan";
System.out.println("Modify : " + studentTwo.name + " " + studentTwo.surname);
}
}
//Console Output
Before : Abdulkadir Selcukoglu
Modify : Ertugrul Aslan
After : Ertugrul Aslan
Uygulamayi inceliyelim oncelikler bir tane Student diye bir reference bir degisken olusturdum ve adina studentOne dedim ve orencinin name ve surname field'lerine Abdulkadir Selcukoglu degerlerini verdim System.out.println ekranda yazdim sonra modify() methodundaki studentTwo'ya studentOne atadim bu atama sirasinda hem degerleri veridim hemde adres'indeki degeri verdim yani ve degisklik yapinca yani Ertugrul Aslan degerini name ve surname ye verince adresi verdigi icin onceki degeri siler ve yeni degeri verir ve boylece hem studentOne hemde studentTwo uzerinde degisiklik yapilmis olur. yani modify methodu ile studentTwoda yapilacak tum degisiklikler studentOne'yide etkiler sebebinide dedigim gibi biz studentOne degeri studentTwo verince studentTwo artik studentOne adresini gorduyunden degisikliklerden birebir etkilenir.
public static void main(String args[]){
int a[] = {1,2,3};
System.out.print("Before : ");
for (int i : a) {
System.out.print(" - "+i);
}
System.out.println();
modify(a);
System.out.print("After : ");
for (int i : a) {
System.out.print(" - "+i);
}
System.out.println();
}
public static void modify(int b[]){
b[0]=4;
b[1]=5;
b[2]=6;
System.out.print("Modify : ");
for (int i : b) {
System.out.print(" - "+i);
}
System.out.println();
}
}
//Console Output
Before : - 1 - 2 - 3
Modify : - 4 - 5 - 6
After : - 4 - 5 - 6
Gorulduyu gibi reference degiskenlerindeki gibi Array tipleride bir array baska bir arry degiskene atadigimizda adres yollu atanan oluyor.
public class Test {
public static void main(String[] args) {
String d = new String("Abdulkadir");
System.out.println("Before d = " + d);
modify(d);
System.out.println("After d = " + d);
}
static void modify(String s) {
s = s + " Selcukoglu";
System.out.println("Modify = " + s);
}
}
//Console Output
Before d = Abdulkadir
Modify = Abdulkadir Selcukoglu
After d = Abdulkadir
Uygulamadanda gorulduyu gibi ilk deger Abdulkadir ve daha sonra modify methodunda deger bir digerine atanmasina ragmen yapilan degislikten atkilanmiyor
Bu konu ile ilgili guzel bir uygulama daha
public class Laser {
public static void main(String[] args) {
Box b1 = new Box(5);
Box[] ba = go(b1, new Box(6));
ba[0] = b1;
for (Box b : ba) {
System.out.print(b.size + " ");
}
}
static Box[] go(Box b1, Box b2) {
b1.size = 4;
Box[] ma = {b2, b1};
return ma;
}
}
//Console Output
4 4
- Ilk once primitive tiplerteki degiskienleri incelemekle basliyorum acama primitif tiplere b ir deger verdikten sonra ve beli basli islemlerden ve deger atamalaridan gectiten sonra en son degeri ne olur.
public static void main(String args[]) {
int value = 1;
System.out.println("Before : " + value);
modify(value);
System.out.println("After : " + value);
}
public static void modify(int valueOne) {
valueOne = valueOne + 2;
System.out.println("Modify : " + valueOne);
}
}
//Console Output
Before : 1
Modify : 3
After : 1
Gorulduyu gibi oncelikle value ilk basta 1 degerini aliyor ve sonra modify methodu cagiriliyor ve methodun parametresi valueOne'ye 1 degeri veriliyor modify methodu 1 deger ile 2 degerini topluyor ve valueOne 3 oluyor ve sonraki satirda value'nin degerine bakilinca hicbir degisiklik olmaz yani value yine 1 olur. Sebebi ise her primitive tip degerini farkli adreste saklar. Birde uygulamada value degerini modify(int valueOne) verince sadece degeri vermis oluyorum degeri kaydettikleri adreste herhangi bir degisme olmuyor
- Simdide Reference tipteki degiskenleri inceliyelim burada olay tamamen farkli bir reference degiskenini baska bir reference degiskenine verdiyimizde hem degeri veriyor hemde kendi adresine yonlendiriyor.
public String name;
public String surname;
}
public class ReferenceTest {
public static void main(String[] args) {
Student studentOne = new Student();
studentOne.name = "Abdulkadir";
studentOne.surname = "Selcukoglu";
System.out.println("Before : " + studentOne.name + " " + studentOne.surname);
modify(studentOne);
System.out.println("After : " + studentOne.name + " " + studentOne.surname);
}
static void modify(Student studentTwo) {
studentTwo.name = "Ertugrul";
studentTwo.surname = "Aslan";
System.out.println("Modify : " + studentTwo.name + " " + studentTwo.surname);
}
}
public class ReferenceTest {
public static void main(String[] args) {
Student studentOne = new Student();
studentOne.name = "Abdulkadir";
studentOne.surname = "Selcukoglu";
System.out.println("Before : " + studentOne.name + " " + studentOne.surname);
modify(studentOne);
System.out.println("After : " + studentOne.name + " " + studentOne.surname);
}
static void modify(Student studentTwo) {
studentTwo.name = "Ertugrul";
studentTwo.surname = "Aslan";
System.out.println("Modify : " + studentTwo.name + " " + studentTwo.surname);
}
}
//Console Output
Before : Abdulkadir Selcukoglu
Modify : Ertugrul Aslan
After : Ertugrul Aslan
Uygulamayi inceliyelim oncelikler bir tane Student diye bir reference bir degisken olusturdum ve adina studentOne dedim ve orencinin name ve surname field'lerine Abdulkadir Selcukoglu degerlerini verdim System.out.println ekranda yazdim sonra modify() methodundaki studentTwo'ya studentOne atadim bu atama sirasinda hem degerleri veridim hemde adres'indeki degeri verdim yani ve degisklik yapinca yani Ertugrul Aslan degerini name ve surname ye verince adresi verdigi icin onceki degeri siler ve yeni degeri verir ve boylece hem studentOne hemde studentTwo uzerinde degisiklik yapilmis olur. yani modify methodu ile studentTwoda yapilacak tum degisiklikler studentOne'yide etkiler sebebinide dedigim gibi biz studentOne degeri studentTwo verince studentTwo artik studentOne adresini gorduyunden degisikliklerden birebir etkilenir.
- Simdide Array tipdeki degiskenler nasil hareket eder ona bakalim
public static void main(String args[]){
int a[] = {1,2,3};
System.out.print("Before : ");
for (int i : a) {
System.out.print(" - "+i);
}
System.out.println();
modify(a);
System.out.print("After : ");
for (int i : a) {
System.out.print(" - "+i);
}
System.out.println();
}
public static void modify(int b[]){
b[0]=4;
b[1]=5;
b[2]=6;
System.out.print("Modify : ");
for (int i : b) {
System.out.print(" - "+i);
}
System.out.println();
}
}
//Console Output
Before : - 1 - 2 - 3
Modify : - 4 - 5 - 6
After : - 4 - 5 - 6
Gorulduyu gibi reference degiskenlerindeki gibi Array tipleride bir array baska bir arry degiskene atadigimizda adres yollu atanan oluyor.
- Simdide bir bir uyari ile konuyu bittirecem Object,String,Long,Short,Byte,Integer ,Double ,Float gibi siniflarde reference olusmalarina ragmen primitive tip gibi haraket eder sebeb aynende ozel bir durumda diyebiliriz bu siniflar her olusturulan degisken iciin bir adres olusturur ve birini digerine atadiginizda ancak deger atanir adreslerde bir degisiklik olmaz.
public class Test {
public static void main(String[] args) {
String d = new String("Abdulkadir");
System.out.println("Before d = " + d);
modify(d);
System.out.println("After d = " + d);
}
static void modify(String s) {
s = s + " Selcukoglu";
System.out.println("Modify = " + s);
}
}
//Console Output
Before d = Abdulkadir
Modify = Abdulkadir Selcukoglu
After d = Abdulkadir
Uygulamadanda gorulduyu gibi ilk deger Abdulkadir ve daha sonra modify methodunda deger bir digerine atanmasina ragmen yapilan degislikten atkilanmiyor
Bu konu ile ilgili guzel bir uygulama daha
public class Laser {
public static void main(String[] args) {
Box b1 = new Box(5);
Box[] ba = go(b1, new Box(6));
ba[0] = b1;
for (Box b : ba) {
System.out.print(b.size + " ");
}
}
static Box[] go(Box b1, Box b2) {
b1.size = 4;
Box[] ma = {b2, b1};
return ma;
}
}
//Console Output
4 4
Monday, September 13, 2010
Interface Class
- Interface(Arayuz) abstract siniflarin gelismi bir hali diyebiliriz.
- Bir interface interface keyword ile tanimlaniyor ve sisteme bir class dosyasi olarak kaydedilen bir yapidir
- Interface tamamen birlestirici bir rol oynamak icin gelistirilmistir.
- Interface'ler iclerinde govdesiz methodlar ve degiskenler icerir.
- Bir interface bir class'a implements keyword declare olur
- Interface class'a implementsolunca icindeki tum govdesiz methodlari Override etmek zorunda
- Interface siniflar icin bir yol gostericidir. Yani interface icinde govdesiz methodlarin oldugunu soylemistik iste bu govdesiz methodlar olusturuken diyorki bak method senin ismin bu olacak sen bunu dondereceksin ve bu parametreleri alacaksin gibisinde olusturulan govdesiz methodlar bulundugu interfaceyi biz bir class'a implements ettigimizde bu methodlar implements ettigimiz class'a Override olunca artik kullanicinin yapmasi gereken bu methodlari govde kismini doldurmak yani kullanici artik biliyor bu method hangi parametreleri iceriyor neyi dondurecegi gibi bilgiler ile ugrasma zahmetinden kurtuluyor.
- Interface methodlarinin erisim belirtecleri public olmak zorundadir.
- Interfacenin en onemli ozeliklerinden biriside class'lar uzerinde coklu kalitima izin vermesidir.
- Interfaceler birbirlerinden turetilebilir. Bu turutme extends keyword ile oluyor. Birdenfazla intreface extends edilmesine izin veriyor. extends olunan interface'ler Override edilmez . Ama bir sinifa implements edilince kendisi ile beraber extends olundudu tum methodlar Override olunur.
- Bir interface'yi abstract class implements edince methodlari Override edilmez. Ama abstract class bir sinifa extends olunca hem abstract'teki hemde interface'deki methodlar Override olunur.
- Interface icerisinde ayno zamanda degiskenlerde bulunur. Bu degiskenler otomatik olarak hem public hem final hemde static ozeligine sahiptir.
- Interface icerisinde tanimlanan degiskenler ilk degerini calisma aninda verilebilir
- Interface ile ilgili bir tek sorun ile karsilasilabilir o da birden cok interfacede extends olunmis bir interface dusunelim diyelimki bu interface ikitane interfacede turemis ve bu iki interfacede geridous degerlerinin disinda ayni olan methodlari barindirmasi bazi sorunlara neden olabilir.
String getName();
String getSurname();
int getBoy();
String getGozRengi();
int getKilo();
int getYas();
}
public class Abdulkadir implements Insanlar{
public String getName() {
return "Abdulkadir";
}
public String getSurname() {
return "Selcukoglu";
}
public int getBoy() {
return 180;
}
public String getGozRengi() {
return "Ela";
}
public int getKilo() {
return 71;
}
public int getYas() {
return 27;
}
}
public class Ertugrul implements Insanlar{
public String getName() {
return "Ertugrul";
}
public String getSurname() {
return "Aslan";
}
public int getBoy() {
return 182;
}
public String getGozRengi() {
return "Kahverengi";
}
public int getKilo() {
return 70;
}
public int getYas() {
return 26;
}
}
public class TestMain {
public static void main(String argsp[]) {
Abdulkadir a = new Abdulkadir();
System.out.println("Name : " + a.getName());
System.out.println("Surname : " + a.getSurname());
System.out.println("Yas : " + a.getYas());
System.out.println("Kilo : " + a.getKilo());
System.out.println("Boy : " + a.getBoy());
System.out.println("Goz Rengi : " + a.getGozRengi());
System.out.println("----------------------------------------");
Ertugrul e = new Ertugrul();
System.out.println("Name : " + e.getName());
System.out.println("Surname : " + e.getSurname());
System.out.println("Yas : " + e.getYas());
System.out.println("Kilo : " + e.getKilo());
System.out.println("Boy : " + e.getBoy());
System.out.println("Goz Rengi : " + e.getGozRengi());
}
}
//Console Output
Name : Abdulkadir
Surname : Selcukoglu
Yas : 27
Kilo : 71
Boy : 180
Goz Rengi : Ela
----------------------------------------
Name : Ertugrul
Surname : Aslan
Yas : 26
Kilo : 70
Boy : 182
Goz Rengi : Kahverengi
Simdi ayni ornegi interface kullanimi sayesinde polimorfizim ile gorelim
public class TestMain {
public static void main(String argsp[]) {
Abdulkadir a = new Abdulkadir();
insanP(a);
Ertugrul e = new Ertugrul();
insanP(e);
}
public static void insanP(Insanlar i){
System.out.println("Name : " + i.getName());
System.out.println("Surname : " + i.getSurname());
System.out.println("Yas : " + i.getYas());
System.out.println("Kilo : " + i.getKilo());
System.out.println("Boy : " + i.getBoy());
System.out.println("Goz Rengi : " + i.getGozRengi());
System.out.println("----------------------------------------");
}
}
//Console Output
Name : Abdulkadir
Surname : Selcukoglu
Yas : 27
Kilo : 71
Boy : 180
Goz Rengi : Ela
----------------------------------------
Name : Ertugrul
Surname : Aslan
Yas : 26
Kilo : 70
Boy : 182
Goz Rengi : Kahverengi
----------------------------------------
Simdide bir interface'nin bir cok interface'de turetilmesine bakalim yukarda yazdigim gibi bir interface'yi diger interfacede turetmek icin extends ifadesinden kullaniyoruz. Asagidaki ornektede anlasilacagi gibi Insanlar interface'si Canlikar'dan turemis ve turme sirasinda herhangi bir override islemi olmamisitir. Biz Insanlar interfacesini bir class implements edince hem Canlilar'daki hemde Insalar'daki methodlar override olunur.
public interface Canlilar {
void yemek();
void sinirlenmek();
void acikmak();
String gulmek();
}
.
public interface Insanlar extends Canlilar{
String getName();
String getSurname();
int getBoy();
String getGozRengi();
int getKilo();
int getYas();
}
public class Rasim implements Insanlar{
public String getName() {
return "Rasim";
}
public String getSurname() {
return "Imanov";
}
public int getBoy() {
return 165;
}
public String getGozRengi() {
return "Kahverengi";
}
public int getKilo() {
return 82;
}
public int getYas() {
return 36;
}
public void yemek() {
System.out.println("Yemek yemyi sever");
}
public void sinirlenmek() {
System.out.println("Cok sinirli degil");
}
public void acikmak() {
System.out.println("Normal acikir");
}
public String gulmek() {
return "Ha ha ha ..... :)";
}
}
Simdide bir interface'ye bircok inteface'nin extends olunmasi uygulamasi
public interface B {
// -------------------------------------
}
public interface C {
// -------------------------------------
}
public interface D {
// -------------------------------------
}
public interface A extends B,C,D{
//-------------------------------------
}
Enum
Javaya enum yapisi 1.5 versiyonundan sonra geldi.enum'lar normal siniflara benze ama bircok kisitlama getirilmistir. enum yapisi olusturulmada evel static final int seklinde tanimlanan degiskenler tanimlaniyordu ama bu bir cok sorunun cikmasina neden oluyordu. Aslinda enum tanimini yapmak yrine enum'larin nasil kullanildigi ile ilgili uygulamalar ile anlatma istiyorum.
Javada enum tanimlamak icin enum keyword yararlanilir. Daha sonra enum elemanlari {} arasina yazilir.
public enum Sebzeler {
DOMATEZ,BIBER,PATLICAN,SALATALIK
}
DOMATEZ,BIBER,PATLICAN,SALATALIK
}
Yukarda bir enum tanimladik simdi biraz daha ilerleyere bu enumdaki degerleri nasil alabiliriz.
public class TestMain {
public static void main(String args[]) {
System.out.println(Sebzeler.DOMATEZ);
System.out.println(Sebzeler.BIBER);
System.out.println(Sebzeler.PATLICAN);
System.out.println(Sebzeler.SALATALIK);
}
}
public static void main(String args[]) {
System.out.println(Sebzeler.DOMATEZ);
System.out.println(Sebzeler.BIBER);
System.out.println(Sebzeler.PATLICAN);
System.out.println(Sebzeler.SALATALIK);
}
}
//Console Output
DOMATEZ
BIBER
PATLICAN
SALATALIK
BIBER
PATLICAN
SALATALIK
Simdide enum icindeki methodlari inceliyelim
values() : Enum'daki elemanlari bir dizi seklinde elde etmemizi sagliyor
public class TestMain {
public static void main(String args[]) {
for (Sebzeler s : Sebzeler.values()) {
System.out.println(s.ordinal());
}
}
}
public static void main(String args[]) {
for (Sebzeler s : Sebzeler.values()) {
System.out.println(s.ordinal());
}
}
}
//Console Output
DOMATEZ
BIBER
PATLICAN
SALATALIK
BIBER
PATLICAN
SALATALIK
ordinal() : Isetile bir enum elemanin kacinci sirada oldugunu bildirir. burada ilk deger sifirdan basliyor.
public class TestMain {
public static void main(String args[]) {
System.out.println(Sebzeler.BIBER.ordinal());
System.out.println(Sebzeler.DOMATEZ.ordinal());
System.out.println(Sebzeler.SALATALIK.ordinal());
System.out.println(Sebzeler.PATLICAN.ordinal());
}
}
public static void main(String args[]) {
System.out.println(Sebzeler.BIBER.ordinal());
System.out.println(Sebzeler.DOMATEZ.ordinal());
System.out.println(Sebzeler.SALATALIK.ordinal());
System.out.println(Sebzeler.PATLICAN.ordinal());
}
}
//Console Output
1
0
3
2
0
3
2
valueOf(String name) :Enum isindeki elemanlarin ismini biliyorsak valueOf methodunun parametresine istenilen enum elemanin adini yazarak elde edebiliriz.
public class TestMain {
public static void main(String args[]) {
for (Sebzeler s : Sebzeler.values()) {
System.out.println(Sebzeler.valueOf(s.name()));
}
}
}
public static void main(String args[]) {
for (Sebzeler s : Sebzeler.values()) {
System.out.println(Sebzeler.valueOf(s.name()));
}
}
}
//Console Output
DOMATEZ
BIBER
PATLICAN
SALATALIK
BIBER
PATLICAN
SALATALIK
Yada bu methodun daha iyi anlasilmasi icin sunu yapabiliriz
public class TestMain {
public static void main(String args[]) {
System.out.println(Sebzeler.valueOf("BIBER"));
}
}
public static void main(String args[]) {
System.out.println(Sebzeler.valueOf("BIBER"));
}
}
//Console Output
BIBER
Simdide enumlar ile ilgili farkli noktalara deyinelim
- Enum elemanlarinin deger almasi ve bu degerlerini kullanilmasi
public enum Sebzeler {
DOMATEZ(100), BIBER(200), PATLICAN(300), SALATALIK(400);
int fiyat;
Sebzeler(int fiyat) {
this.fiyat = fiyat;
}
}
DOMATEZ(100), BIBER(200), PATLICAN(300), SALATALIK(400);
int fiyat;
Sebzeler(int fiyat) {
this.fiyat = fiyat;
}
}
Yukarida enum elemanlarina deger verdim ama bu degerleri Constructor parametre degeri ne ise elemanlarda o tipte degerler aliyor.
public class TestMain {
public static void main(String args[]) {
for (Sebzeler f : Sebzeler.values()) {
System.out.println(f.name() +" : "+f.fiyat);
}
}
}
public static void main(String args[]) {
for (Sebzeler f : Sebzeler.values()) {
System.out.println(f.name() +" : "+f.fiyat);
}
}
}
//Console Output
DOMATEZ : 100
BIBER : 200
PATLICAN : 300
SALATALIK : 400
BIBER : 200
PATLICAN : 300
SALATALIK : 400
public enum Sebzeler {
DOMATEZ("Kirmizi"), BIBER("Yesil"), PATLICAN("Siyah"), SALATALIK("Yesil");
DOMATEZ("Kirmizi"), BIBER("Yesil"), PATLICAN("Siyah"), SALATALIK("Yesil");
String renkler;
Sebzeler(String renkler) {
this.renkler = renkler;
}
}
public class TestMain {
public static void main(String args[]) {
for (Sebzeler f : Sebzeler.values()) {
System.out.println(f.name() +" : "+f.renkler);
}
}
}
public static void main(String args[]) {
for (Sebzeler f : Sebzeler.values()) {
System.out.println(f.name() +" : "+f.renkler);
}
}
}
//Console Output
DOMATEZ : Kirmizi
BIBER : Yesil
PATLICAN : Siyah
SALATALIK : Yesil
BIBER : Yesil
PATLICAN : Siyah
SALATALIK : Yesil
- Simdide enum elemanlarina method ekleme islemine geciyoruz
public enum Hesapla {
TOPLA{ double islem(double x, double y) { return x + y; } },
CIKAR{ double islem(double x, double y) { return x - y; } },
CARP { double islem(double x, double y) { return x * y; } },
BOL { double islem(double x, double y) { return x / y; } };
abstract double islem(double x, double y);
}
TOPLA{ double islem(double x, double y) { return x + y; } },
CIKAR{ double islem(double x, double y) { return x - y; } },
CARP { double islem(double x, double y) { return x * y; } },
BOL { double islem(double x, double y) { return x / y; } };
abstract double islem(double x, double y);
}
public class TestMain {
public static void main(String args[]) {
System.out.println("2 + 3 : "+Hesapla.TOPLA.islem(2, 3));
}
}
public static void main(String args[]) {
System.out.println("2 + 3 : "+Hesapla.TOPLA.islem(2, 3));
}
}
//Console Output
2 + 3 : 5.0
- Enum'lar kalitim yetenegine sahip degiller
- Enum'larin Constructor public olamaz.
- Enum yapisi interface'yi implement edebilir.
Az once yaptigimiz Hesapla enum'unu interface yetenegi ile beraber yapalim
public interface Hesap {
double islem(double x, double y);
}
double islem(double x, double y);
}
public enum Hesapla implements Hesap {
TOPLA{
@Override
public double islem(double x, double y) {
return x + y;
}
},
CIKAR{
@Override
public double islem(double x, double y) {
return x - y;
}
},
CARP{
@Override
public double islem(double x, double y) {
return x * y;
}
},
BOL{
@Override
public double islem(double x, double y) {
return x / y;
}
};
}
TOPLA{
@Override
public double islem(double x, double y) {
return x + y;
}
},
CIKAR{
@Override
public double islem(double x, double y) {
return x - y;
}
},
CARP{
@Override
public double islem(double x, double y) {
return x * y;
}
},
BOL{
@Override
public double islem(double x, double y) {
return x / y;
}
};
}
public class TestMain {
public static void main(String args[]) {
System.out.println("2 + 3 : "+Hesapla.TOPLA.islem(2, 3));
System.out.println("2 * 3 : "+Hesapla.CARP.islem(2, 3));
System.out.println("2 - 3 : "+Hesapla.CIKAR.islem(2, 3));
}
}
public static void main(String args[]) {
System.out.println("2 + 3 : "+Hesapla.TOPLA.islem(2, 3));
System.out.println("2 * 3 : "+Hesapla.CARP.islem(2, 3));
System.out.println("2 - 3 : "+Hesapla.CIKAR.islem(2, 3));
}
}
//Console Output
2 + 3 : 5.0
2 * 3 : 6.0
2 - 3 : -1.0
2 * 3 : 6.0
2 - 3 : -1.0
Yukeridaki interface kullanarak yazdigim ornegi bir baska sekilde kullanimi
public class TestMain {
public static void main(String args[]) {
for(Hesapla h : Hesapla.values()){
System.out.println(h.name() +" : "+ h.islem(4, 2));
}
}
}
public static void main(String args[]) {
for(Hesapla h : Hesapla.values()){
System.out.println(h.name() +" : "+ h.islem(4, 2));
}
}
}
//Console Output
TOPLA : 6.0
CIKAR : 2.0
CARP : 8.0
BOL : 2.0
CIKAR : 2.0
CARP : 8.0
BOL : 2.0
- Enum konusunu inceliyorken EnumSet sinifinida incelemeden gecemiyecem
public enum Gunler {
PAZARTESI("Monday") , SALI("Tuesday") , CARSAMBA("Wednesday") , PERSEMBE("Thursday") , CUMA("Friday") , CUMARTESI("Saturday") , PAZAR("Sunday");
String eng;
Gunler(String eng){
this.eng = eng;
}
}
PAZARTESI("Monday") , SALI("Tuesday") , CARSAMBA("Wednesday") , PERSEMBE("Thursday") , CUMA("Friday") , CUMARTESI("Saturday") , PAZAR("Sunday");
String eng;
Gunler(String eng){
this.eng = eng;
}
}
public class TestMain {
public static void main(String args[]) {
EnumSet d = EnumSet.range(Gunler.PAZARTESI, Gunler.PERSEMBE);
System.out.println(d);
}
}
public static void main(String args[]) {
EnumSet
System.out.println(d);
}
}
//Console Output
[PAZARTESI, SALI, CARSAMBA, PERSEMBE]
public class TestMain {
public static void main(String args[]) {
EnumSet d = EnumSet.allOf(Gunler.class);
for(Gunler g: d.clone()){
System.out.println(g);
}
}
}
public static void main(String args[]) {
EnumSet
for(Gunler g: d.clone()){
System.out.println(g);
}
}
}
//Console Output
PAZARTESI
SALI
CARSAMBA
PERSEMBE
CUMA
CUMARTESI
PAZAR
SALI
CARSAMBA
PERSEMBE
CUMA
CUMARTESI
PAZAR
public class TestMain {
public static void main(String args[]) {
for(Gunler g: EnumSet.allOf(Gunler.class)){
System.out.println(g);
}
}
}
//Console Output
PAZARTESI
SALI
CARSAMBA
PERSEMBE
CUMA
CUMARTESI
PAZAR
SALI
CARSAMBA
PERSEMBE
CUMA
CUMARTESI
PAZAR
public class TestMain {
public static void main(String args[]) {
for(Gunler g : EnumSet.of(Gunler.PAZARTESI, Gunler.CUMA)){
System.out.println(g);
}
}
}
public static void main(String args[]) {
for(Gunler g : EnumSet.of(Gunler.PAZARTESI, Gunler.CUMA)){
System.out.println(g);
}
}
}
//Console Output
PAZARTESI
CUMA
CUMA
public class TestMain {
public static void main(String args[]) {
EnumSet es = EnumSet.allOf(Gunler.class);
EnumSet e= EnumSet.complementOf(es);
e.add(Gunler.SALI);
System.out.println(e);
}
}
public static void main(String args[]) {
EnumSet
EnumSet
e.add(Gunler.SALI);
System.out.println(e);
}
}
//Console Output
[SALI]
public class TestMain {
public static void main(String args[]) {
System.out.println(EnumSet.noneOf(Gunler.class));
}
}
public static void main(String args[]) {
System.out.println(EnumSet.noneOf(Gunler.class));
}
}
//Console Output
[]
Access Modifiers(Erisim Belirtecleri)
- Public
- Private
- Protected
- Friendly
package az.risk
public class A{
public void test(){
System.out.println("A sinifindaki test methoduna erisebildiniz...... :)");
}
}
package tr.net
import az.risk.A;
public class B{
public static void main(String args[]){
A a = new A();
a.test();
}
}
//Console Output
A sinifindaki test methoduna erisebildiniz...... :)
Private : Bu erisim belirteci sadece method ve degiskenelere uygulanir. Bu erisim belirteci tanimlanmis oldugu sinif icinde erisiliyor. Kendi yada baska paketlerde erisilemiyor.
Bir sinifa ait Construvtor private olabilir Eyer sinifa ait Construvtor private ise Referans olusturamayiz.Construvtor private yaptigimiz bir sinifa ulasmak icin static methodlar olusturark o siniftaki elemanlardan yaralana biliriz Bir ornek ole bunu aciklayalim
public class A{
private String name;
private int age;
private A(){
name ="Abdulkadir";
age=27;
}
public static void writeA(){
A a = new A();
System.out.println("NAME :"+a.name);
System.out.println("Age :"+a.age);
}}
package tr.net
import az.risk.A;
public class B{
public static void main(String args[]){
A.writeA();
}
}
//Console Output
NAME :AbdulkadirAge :27
Asagidaki sekilde bir kullanim yanlis olur
package tr.net
import az.risk.A;
public class B{
public static void main(String args[]){
A a = new A();
a.writeA();
}
}
Bir sinif hicbirzaman private erisim belirteci ile belirtilemez
Protected : Bu erisim belirteci kendi paketinde erisilebilr ama diyer paketlerde erisilemez.
Friendly : Varsayilan erisim belirteci demektir. Yani bir deyiskene , methoda, sinifa herhangi bir erisim belirteci yazilmamis ise o zaman defaul olarak friendly olur.
Degiskenelere , methodlara ve siniflara uygulanabilir
friendly erisim belirteci uyelere ayni paket icinden erisilebilirken farkli paketlerde erisilemez.
Herhangi bir uyeyi friendly yapmak icin bu erisim belirtecini yamaya gerek yoktur zaten yazilmasi durumda hata meydana geliyor.
int a; // DOGRU
friendly int a; //YANLIS
Sunday, September 12, 2010
Abstract Class
Normal bir sinif ile interface sinifinin birlesimi diye dusunurseniz o zaman abstract siniflari anlamak daha kolay olacak tabi boyle bir tanim abstract gibi guclu bir sinif yapisina haksizlik olacak ama yazinin ilerleyen kisimlarinda abstract siniflarin gucunden ve kullanimi sirasinda dikkat edilmesi gereken kurallardan bahsetmek icin bu yaziyi yazdim oncelikle bir abstrac ornegi ile basliyacam ve bu ornek uzerinde tum konuyu anlatmaya calisacam
Benim uygulamam su sekilde Insan diye bir abstract sinifim var ve bu sinifta insanlarin ortak olan ve farkli olan tum niteliklerini olusturdugum bir sinif
public abstract class Insan {
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
public class Abdulkadir extends Insan{
@Override
public int getBoy() {
return 180;
}
@Override
public String getGozRengi() {
return "Ela";
}
@Override
public int getKilo() {
return 73;
}
@Override
public int getYas() {
return 27;
}
}
public class Ertugrul extends Insan{
@Override
public int getBoy() {
return 182;
}
@Override
public String getGozRengi() {
return "Kahverengi";
}
@Override
public int getKilo() {
return 70;
}
@Override
public int getYas() {
return 26;
}
}
public class TestMain {
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
a.gulmek();
a.sinirlenmek();
a.yemek();
System.out.println("BOY : "+a.getBoy());
System.out.println("KILO : "+a.getKilo());
System.out.println("YAZ RENGI : "+a.getGozRengi());
}
}
//CONSOLE OUTPUT (Ekranda gosterilen veriler)
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 180
KILO : 73
YAZ RENGI : Ela
Yukaridaki uygulamayi inceledigimizde Insan Abstract sinifinin hem bir inteface gibi soyut siniflarinin var oldugunu hemde normal sinif gibi ici dolu methodlarinin oldugunu goruyoruz. ve biz bu insan Abstract sinifini yaparken su mantiktanda yararlandigimizada dikkat etmissinizdir kalitim konusundaki gibi insana ait olan ortak ozelikleri bir araya toplayarak her seferinde tekrar tekrar yazmak ve kalitimin gucunden yararlanmak gibi bir durumda dikkatinizi cekmistir ve ayrica icinde soyut methodlarda var yani ben diyorumki bu insan sinifini extends edecek sinifa sen su methodlarida kullanmalisin yani tipki interfacede oldugu gibi Simdi gelelim Abstract siniflarda dikkat edilmesi gereken hususlara
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
testPoli(a);
System.out.println("---------------------------------------------------");
Ertugrul e = new Ertugrul();
testPoli(e);
}
public static void testPoli(Insan i){
i.gulmek();
i.sinirlenmek();
i.yemek();
System.out.println("BOY : "+i.getBoy());
System.out.println("KILO : "+i.getKilo());
System.out.println("YAZ RENGI : "+i.getGozRengi());
}
}
//CONSOLE OUTPUT
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 180
KILO : 73
YAZ RENGI : Ela
---------------------------------------------------
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 182
KILO : 70
YAZ RENGI : Kahverengi
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public Abdulkadir() {
System.out.println("Ben Abdulkadir sinifinin Yapilandiricisiyim.....");
}
Simdi bu dedigimiz olayin nasil calistigina bakalim
public class TestMain {
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
System.out.println("KILO : "+a.getKilo());
}
}
//CONSOLE OUTPUT
Ben Insan sinifin Yapicisiyim
Ben Abdulkadir sinifinin Yapilandiricisiyim.....
KILO : 73
public Canlilar() {
System.out.println("Canlilar sinifinin Yapilandiricisi......");
}
public abstract void yasamak();
public abstract void olmek();
public void test(){
System.out.println("Canlilar sinifinin test methodu");
}
}
public abstract class Insan extends Canlilar{
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
Gorulduyu gibi bir abstract sinifi baska bir abstract siniftan turetmek icin oncelikle extends kelimesinden yaralalndik yani ayni normal siniflarda oldugu gibi. Normal bir sinifa abstract sinifi extends ettigimizde abstract methodlari override etmek gerekliydi ama yukardaki uygulamada gorulduyu gibi bu sekilde bir sey soz konusu degil.
Eyer biz Insan abstract sinifini Abdulkadir sinifina extends edersek o zaman hem Canlilar'daki hemde Insan'daki abstract methodlari override etmemiz gerekir
void yasamak();
void olmek();
}
public abstract class Insan implements CanlilarIn{
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
public class Abdulkadir extends Insan{
public Abdulkadir() {
System.out.println("Ben Abdulkadir sinifinin Yapilandiricisiyim.....");
}
@Override
public int getBoy() {
return 180;
}
@Override
public String getGozRengi() {
return "Ela";
}
@Override
public int getKilo() {
return 73;
}
@Override
public int getYas() {
return 27;
}
public void yasamak() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void olmek() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Gorulduyu gibi Insan abstract sinifa CanlilarIn inteface sinifi implements olunca methodlarini Override edilmiyor ama Abdulkadir sinifina Insan abstract sinifi extends olununca CanlilarIn ile Insan sinifindaki soyut methodlar Override olunuyor
Benim uygulamam su sekilde Insan diye bir abstract sinifim var ve bu sinifta insanlarin ortak olan ve farkli olan tum niteliklerini olusturdugum bir sinif
public abstract class Insan {
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
public class Abdulkadir extends Insan{
@Override
public int getBoy() {
return 180;
}
@Override
public String getGozRengi() {
return "Ela";
}
@Override
public int getKilo() {
return 73;
}
@Override
public int getYas() {
return 27;
}
}
public class Ertugrul extends Insan{
@Override
public int getBoy() {
return 182;
}
@Override
public String getGozRengi() {
return "Kahverengi";
}
@Override
public int getKilo() {
return 70;
}
@Override
public int getYas() {
return 26;
}
}
public class TestMain {
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
a.gulmek();
a.sinirlenmek();
a.yemek();
System.out.println("BOY : "+a.getBoy());
System.out.println("KILO : "+a.getKilo());
System.out.println("YAZ RENGI : "+a.getGozRengi());
}
}
//CONSOLE OUTPUT (Ekranda gosterilen veriler)
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 180
KILO : 73
YAZ RENGI : Ela
Yukaridaki uygulamayi inceledigimizde Insan Abstract sinifinin hem bir inteface gibi soyut siniflarinin var oldugunu hemde normal sinif gibi ici dolu methodlarinin oldugunu goruyoruz. ve biz bu insan Abstract sinifini yaparken su mantiktanda yararlandigimizada dikkat etmissinizdir kalitim konusundaki gibi insana ait olan ortak ozelikleri bir araya toplayarak her seferinde tekrar tekrar yazmak ve kalitimin gucunden yararlanmak gibi bir durumda dikkatinizi cekmistir ve ayrica icinde soyut methodlarda var yani ben diyorumki bu insan sinifini extends edecek sinifa sen su methodlarida kullanmalisin yani tipki interfacede oldugu gibi Simdi gelelim Abstract siniflarda dikkat edilmesi gereken hususlara
- . Bir sınıf soyut olucaksa, abstract anahtar sözüğü ile tanımlanır.public abstract class Insan
- Abstract bir sınıftan herhangibir nesne örneği türetilemez. Insan i = new Insan() seklinde bir nesne ornegi olusturamayiz.
- Abstract bir sinif abstract metod tanımlamarını içermesidir. public abstract int getBoy() ;
- Bu Abstract sınıftan türeyen sınıflarda abstract methodlar mutlaka ama mutlaka override edilmelidir.
- Abstract siniflar olustururken tek baslarina bir manalari yok anacak kalitim yolu ile kullanildigini soylemistik iste eyer bir yerde kalitim varsa o zaman polimorfizimden bahsetmek mumkun buda yine abstrac sinifini bir gucudur
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
testPoli(a);
System.out.println("---------------------------------------------------");
Ertugrul e = new Ertugrul();
testPoli(e);
}
public static void testPoli(Insan i){
i.gulmek();
i.sinirlenmek();
i.yemek();
System.out.println("BOY : "+i.getBoy());
System.out.println("KILO : "+i.getKilo());
System.out.println("YAZ RENGI : "+i.getGozRengi());
}
}
//CONSOLE OUTPUT
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 180
KILO : 73
YAZ RENGI : Ela
---------------------------------------------------
Tum Insanlar Guler yer
Tum Insanlar Sinirlenir yer
Tum Insanlar yemek yer
BOY : 182
KILO : 70
YAZ RENGI : Kahverengi
- Abstract sınıf tanımlamalarında dikkat çeken bir diğer unsurda, bu sınıfın abstract metodlar dışındada normal sınıfların sahip olduğu üyelere sahip olabilmesidir. Normal metodlar veya alanlar. Normal bir metodu türeyen sınıflara ait nesneler üzerinden kalıtımın bir gereği olarak çağırabiliriz.
- Kalıtımın doğası gereği ilk olarak abstract sınıf içerisindeki yapıcı metodu işleyeceğinide biliyoruz burada sunu demek istiyorum
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public Abdulkadir() {
System.out.println("Ben Abdulkadir sinifinin Yapilandiricisiyim.....");
}
Simdi bu dedigimiz olayin nasil calistigina bakalim
public class TestMain {
public static void main(String args[]){
Abdulkadir a = new Abdulkadir();
System.out.println("KILO : "+a.getKilo());
}
}
//CONSOLE OUTPUT
Ben Insan sinifin Yapicisiyim
Ben Abdulkadir sinifinin Yapilandiricisiyim.....
KILO : 73
- Abstract sınıftan başka abstract sınıflar türetilmesi sirasinda dikkat edilecek hususlar
public Canlilar() {
System.out.println("Canlilar sinifinin Yapilandiricisi......");
}
public abstract void yasamak();
public abstract void olmek();
public void test(){
System.out.println("Canlilar sinifinin test methodu");
}
}
public abstract class Insan extends Canlilar{
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
Gorulduyu gibi bir abstract sinifi baska bir abstract siniftan turetmek icin oncelikle extends kelimesinden yaralalndik yani ayni normal siniflarda oldugu gibi. Normal bir sinifa abstract sinifi extends ettigimizde abstract methodlari override etmek gerekliydi ama yukardaki uygulamada gorulduyu gibi bu sekilde bir sey soz konusu degil.
Eyer biz Insan abstract sinifini Abdulkadir sinifina extends edersek o zaman hem Canlilar'daki hemde Insan'daki abstract methodlari override etmemiz gerekir
- Simdide bir Interface sinifini Abstract sinifina implements sirasinda nelerin olduguna bakalim:
void yasamak();
void olmek();
}
public abstract class Insan implements CanlilarIn{
public Insan() {
System.out.println("Ben Insan sinifin Yapicisiyim");
}
public abstract int getBoy() ;
public abstract String getGozRengi();
public abstract int getKilo();
public abstract int getYas();
public void yemek(){
System.out.println("Tum Insanlar yemek yer");
}
public void sinirlenmek(){
System.out.println("Tum Insanlar Sinirlenir yer");
}
public void gulmek(){
System.out.println("Tum Insanlar Guler yer");
}
}
public class Abdulkadir extends Insan{
public Abdulkadir() {
System.out.println("Ben Abdulkadir sinifinin Yapilandiricisiyim.....");
}
@Override
public int getBoy() {
return 180;
}
@Override
public String getGozRengi() {
return "Ela";
}
@Override
public int getKilo() {
return 73;
}
@Override
public int getYas() {
return 27;
}
public void yasamak() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void olmek() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
Gorulduyu gibi Insan abstract sinifa CanlilarIn inteface sinifi implements olunca methodlarini Override edilmiyor ama Abdulkadir sinifina Insan abstract sinifi extends olununca CanlilarIn ile Insan sinifindaki soyut methodlar Override olunuyor
Final
- Bir final method, Temel sinifa uygulandiginda, turetilen siniflarda iptal edilmeyen methodlardir. Yani override isleminden bahsetmek mumken degildir.
- Degiskenleri final olarak tanimladigimizda onlara ilk degerinin atanmasindan sonra degerlerini degistiremiyorduk.
- Final olarak tanimlanmis degiskenlere degiskenlere tanimlandiklari anda deger atanmasi gerektigi
- Final anahtar kelimesi ile olusturulan nesne orneginde bu nesne orneginin programin calisma boyunca ancak birkez olusturulabilecegi
- Final yapicilara uygulanmaz
- Bir methodun parametrelerini final olarak tanimlayabilir ve bu sayede methodlara gelen parametre degerlerinin degistirilmesini engelleyebiliriz.
- Final olarak tanimlanmis bir siniftan baska sinif turetemeyiz(Kalitim soz konusu olamaz).
- Sinifin final olarak tanimlanmasi icerdigi method ve degiskenlerin final olarak algilanmasi manasina gelmiyor
Bu konu ile iulgili daha ayrintili bilgiyi asagidaki linkten elde edebilirsiniz ben bu kunuya bu kaynaktan hazirlandim guzel anlatigina inandigim icin sizler ile paylasmak istedim
Subscribe to:
Posts (Atom)
