Java platform bağımsız bir dildir. Yani java işletim sistemlerine göre derlenmez. Yazılan codelar oncelikle javac derleyicisiyle derlendikten sonra C,C++ tarzındaki diller gibi bizler Executable tarzında işlemcimizin hemen derleyebileceği bir tarzda dosya oluşturmaz. Oluşan dosya .class biçiminde bir dosyadır .class uzantılı dosyamızı açtığımızda bunun içinde yazılan Byte code denilen insanlarla işletim sistemlerinin anlayamayacağı bir codedur. Bunların işlemcimiz tarafında anlaşılması için jvm (java virtual machine )' ihtiyacımız vardır.
Compiler(derleyici) ⏩ codeları yüksek seviyeli bir dilden daha düşük seviyeli bir dile düşürür **ör:**Compiler'lar bildiğimiz Google translate gibidir direk olarak verilen şeyi anlaşılır bir hale gettirir.
İnterpreter(yorumlayıcı) ⏩ yüksek seviyeli dillerde sıklıkla görülür compiler edilen code'lar bilgisayar dillerine dönüştürülemediği için yorumlayıcılar Bunları işlemciler için anlaşılır bir hale gettirir ör İnterpreter'ler birer çevirmen gibi düşüne biliriz konuşulan diyalogları duygu ve düşünce bakımından da karşı tarafa aktarım gösterirler
jvm bir yorumlayıcıdır fakat buna virtual machine dememizin bir sebebi var mı acaba ? tabikide burdaki makineden kastımız ayrı bir işlemci gibi davranır ve girilen verileri direk olarak bilgisayarımızın anlayabilecegi kodlara çevirir. fakat C gibi bizlere bir executable dosyası vermez satır satır yorumlar ve yorumlanan satırları çalıştırır.
İşlemciler
1.Fetc(al)
2.Decode(çözümle)
3.Execut(çalıştır)
tarzında çalışırken jvm ilk 2 satırı yapar ve 3. satırımızı yanı Execut işlemini işlemcilere bırakır.
C dilinde
define Adam 3 Const int Adam = 3 Diye iki farklı veri tipimiz bulunmaktadır. #define ön bellekte adam görülen her yere 3 yazılmasına sebeb olur bizim işlemcimiz Adam diye bir veriyi görmez.
Const int te ise verilen Adam değişkenine başka bir değer atayamayız her zaman Adam 3 olarak kalackatır
Java dilinde
final; diye bir değişkenimiz var bu değişkenimiz ise C deki define ve Const int değerlerimizie benziyorlar final değişkenimiz önceden bir değer almaz ne zaman biz bir değer veririz o zaman o değeri alır ve kilitler
adam | static |
---|---|
Runtime Steck | |
nesne | Heap |
Nesnenin yeri bellidir sabittir, program başlar ve değişmez
Program içerisinde hafızaya alınan nesneler kulanımı bittikten sonra yerlerini farklı class verirler
Refactoring: codun çalışması değiştirilmeden tekrardan inşa edilmesi
Public static void main(string[] args)
>Public JVM programı yorumlamaya başlarken main metodunu arar bu yüzden JVM in bulabilmesi için public veriyoruz.
>static class tanımlamadan da çagırabilmemiz için
>void metodun değerini belirler
metodun değerlerine bir dizi parametresi göndermiyiz. Metodlarda direk olarak dizi parametresi giremediğimizden dolayı bunu bir indes olarak veririz
>string[] args dizinin indislerini parametre olarak metoda gönderilmesine yarar
Ayrıntılardan uzaklaşma soyutlama ör bir klavyeyi düşünelim üzerinde tuşlar bulunuyor basınca bişeyleri ekrana yazmamıza yardımcı olan bir aygıt fakat bunu devresel olarak düşündüğümüz zaman ne kadar karmaşık bir hal alacağını düşünebilirz her bir harfin her bir tuşun aslında bir code'a takabul ettiğini düşünerek çalışmak gayet derecede zor olması lazım gelir. Bundan dolayı nesneye dayalı programlamada ne kadar sade, insanların daha basit anlayıp kompleks yapılardan uzaklaştıra işlemidir.
- bir varlığın ne olduğu ile ilgilenir nasıl olduğuyla değil
şimdi kediyle ilgili bir class oluşrutalım ve buradan türetecegimiz nesneler farklı bakış açılarından oluşsun (bi veteriner bi petshop vb.)
public class kedi{
string: kuyruk
string: cinsi
yasi: int
asıdurumu: boolean
fiyati: duble
-------------------------
miyav()
asiyap(asix)
getFiyat
}
-
bir bakış açısı ile bir varlıgın ne oldugu üzerinde durur (böylelikle yazdığımız kılastaki bakış açıları birden çok olduğundan yanlıştır)
-
single responsibility prhciple
bir sınıfın yanlız bir sorumluluğu olmalı
fiyat:duble texture:jpg koordinat:3D koordinat ------------------------------- ciz(); getFiyat();
public class stack{
public int[] array;
public int top;
public stack(){
array =new int [10];
top=0;
}
public boolean isEmpyty(){
if (top <=0)
return true;
return false;
}
public boolean isFull(){
if (top >= array.lenght)
return true;
return fasle;
}
public void push(int value){
if (!isFull())
array[top++]=value;
else
System.out.print("stack full");
}
public int pop(){
if (!isEmpty())
return array[--top];
}
}
yukarıda verilmiş olan bir kod dizisinde stack data type örnek kodu verilmiştir aşagılarda açıklayarak ilerliyeceğiz
yukarıda görüldüğü gibi stack yapısında veriler üst üste biner ve sadece üstten ekleme olur ve en üstten çekme olur
örnek verecek olursak bir tabak yığını düşünelim bu tabakları alırken ve yerlerine koyarken sadece en üsten alıp en üstten ekleme yapıyoruz
şimdi bizim stacke kodumuzu kulanacak bir program geliştiricisi kalkıp şöyle bir code yazdı
public class Deneme{
public static void main(String[] args){
static s = new static();
s.push(5);
s.push(3);
int a = s.pop();
s.array[5]=7; //1.hata
s.top = 20; //2. hata
}
}
şu anda gördüğümüz üzere array[5]'i 7 ye eşitledik peki bizim top noktamız orasımıydı ya daha üstte iken biz > kalkıp onun üzerine yazmış bulunduk veya daha altta iken biz stack yapısını bozup arada boşluk bıraktık
aynı şekilde s.top=20 yazan bölmede bizim önceden tanımladığımız top değeriniz bozup 20 yaptı
Şu anda bizim yazmış oldugumuz stacke kodunun bir anlamı bulunmamaktadır çünki yapı tamamıyla bozulmuştur peki biz bu olanların önüne nasıl geçicez ? Tabikide bunun bir yöntemi var
- Gerçekleştirme ayrıntılarını gizlenmesi
- Bilgi sakalam
- Kapsülleme
- Erişim kısıtlama
- Bilgi sakalama olmazsa
- Abstraction ortadan kalkar
- Kullanıcının hata yapmasına neden olur
- Bakımı zorlaşır
syntax:
ErişimOperetörü DönenTip methodAdı (parametre){
-
-
-
-
}
Metod adı : parametrelerden önceki isim Metod imzsaı : metodların tamamen aynı yazılması
Bir sınıfın içinde aynı adlı farklı imzaya sahip methodların bulunmasıdır
Method tanımında static eklenen sınıf methodları
Method tanımında static eklenmeyen nesne metodları
- Görevi
- 1-> Nesneyi ilklemek (oluşturmak deği) - olusturulan classlara ilk degerleri verir
- 2-> "new" operetörlerine sınıfın bir örneğini (nesnesini) üretmesi gerektiğini söyler
- Yapılandırıcı method adı sınıf adı ile aynıdır
- Bir sınıfın içinde birden fazla yapılandırıcı bulunabilir
- Bir sınıf içerisinde yapılandırıcı method yoksa varsayılan (default) yapılandırıcı devreye girer
stack s = new stack();
- Sınıf içinde bir construction varsa varsayılan constructor devreden çıkar
* Parametre almaz.
* Eğer sınıfta bir constructor yazılmadıysa Java otomatik üretir
public SınıfAdi (){
}
bu yapılandırma alt alanlara var sayılan değeri atanır Java varsayılan değerler String, Dizi, referans için Null int, double, float için 0
* Dışardan parametre alır
* Dışardan alınan parametre alt alanların ilklemesinde kullanılır
public class Ogrenci{
private int no ;
private String adi;
public Ogrenci(int snot String sadi){
no=sno;
adi=sadi;
}
// Eğer default constructor yapmak istersek
Ogrenci ogr = new Ogrenci ();
//parametrized constructor için ise
Ogrenci ogr = new Ogrenci (2563 ,"ali");
}
* Parametre olarak kopyası alınacak nesnenin referansı geçirilir
* Bu referans ile nesnenin alt alanları ilklenir
public Ogrenci(Ogrenci kopya){
no = kopya.getNo();
adı = kopya.getAdi();
Ogrenci ogr3 = new Ogrenci(ogr2)
}
clone() Metodu bir nesnenin kopyasını almak için kullanılır
Ogrenci ogr5 = ogr2.clone();
This article discusses getters and setters; the standard way to provide access to data in Java classes.
Setters and Getters allow for an object to contain private variables which can be accessed and changed with restrictions. For example,
public class Person {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
if(name!=null && name.length()>2)
this.name = name;
}
}
In this Person class, there is a single variable: name. This variable can be accessed using the getName() method and changed using the setName(String) method.
public String getName(){
if(name.length()>16)
return "Name is too large!";
else
return name;
}
Metoda sadece değer geçirilir
Metod değişkeni sadece adresi geçirilir
Metoda geri döndürülecek değeri tutacak adresi bilgisi gönderilir
Metoda değişkenin adı geçirilir
**JAVADA HERŞEY PASS-BY VALUE OLARAK GEÇİRİLİR**
1-> Sınıfta öğrenciler vardır
2-> Her öğrencinin bir kartı vardır
3-> Fakülte böümlerden oluşur
4-> Üniverste bir eğitim kurumudur
5-> Ali bir öğrencidir
6-> Bir dersin bir hocası bulunur
7-> Öğrenciler kart ile giriş yapar
8-> Bir öğrencinin kayıt tarihi vardır
1-) Sınıf ⏩ Öğrenci (has (vardır))
2-) Öğrenci ⏩ kartı (has (vardır))
3-) Fakülte ⏩ Bölüm (has (vardır))
4-) Üniverste ⏩ Eğitim kurumu ("is a" ("-dir"))
5-) Ali ⏩ Öğrenci ("is a" ("-dir"))
6-) Ders ⏩ Hoca (has (vardır))
7-) Öğrenci ⏩ Kartı (use (kullanır))
8-) Öğrenci ⏩ Tarih (has (vardır))
yapısal olarak bakıldığında 1. ile 6. A benzerken 2. 3. ve 8. de B (A ile B aşağıda açıklanacaktır).
1-) Kapsayan kapasanan ilişkisi
2-) Kapsayan kapsanan'a sahip mi ?
A ⏩ 🔹 Has a ilişkisi 🔹 "is a part of " veya "owns" ilişkisi var. (Composition)
B ⏩ Sadece "has a" ilişkisi (Aggregation)
Has a ilişkisi Aggegation ile kullanılır Composition Aggegation'ın özel bir türüdür
- Has a ilişkisi
- Nesnelerin yaşamları birbirlerine bağlı değildir
yukarda anlatılmak istenen gibi Her bir *Öğrencinin * bir *danışmanı *vardır gibi ne burdaki danışman giderse öğrencinin öğrenciliğinde bir değişim olur ne de öğrenci giderse danışmanın danışmanlığına birşey olur
public class Ders {
private string dersAdı;
private hoca;
private ogrenci [] ogrenciler;
public ders (string Adı, hoca,int k )
{
dersAdı = adı;
this.h = hoca;
ogrenciler = new Ogrenci[k];
}
public void set hoca(hoca h)
{
this.h=h;
}
public static main (String args[])
{
dersAdı ndp = new Ders("nesne,100");
hoca d = new Hoca("dogan");
ndp.setHoca(d);
ders td = new Ders("tasarım",d,30);
ndp = null; // ndp yı yoketme
}
}
Yukarda gördüğümüz üzere (ndp = null) tarzında bir kod yazarak (ndp) yi sıfırlıyoruz burada Aggregation mantığı ile bakacak olursak nesnemiz silinse bile ona bağlı özellikler veya başka nesneler metodlar her hangi bir verimiz başka bir nesneye de bağlı olabileceğinden nesnenin sıfırlanmasından etkilenmeyebilir.
-
"Has a" + "is part of " ilişkisi.
-
Kapsayanın hayatı biterse kapsananın da hayatı sona erer.
Buda da gördüğümüz üzere her bir Öğrencinin bir Öğrenci kartı vardır burda öğrenciye ortadan kaldırırsak otamatik olarak kartı da geçersiz olur böylelikle öğrencinin hayatıyla kartın hayatı birbirine bağlıdır
public class Ogrenci{
private string adı;
private kart k;
public Ogrenci(int k-id,string adı)
{
this.adı=adı;
k= new kart (k-id);
}
public class kart {
private int k-id;
public kart (int d){
k-id=d;
}
public Ogrenci(string adı)
{
this.adı=adı;
k= null; //1. ihtimal
k= new kart (); //2. ihtimal
}
public void set kart (int id)
{
k= new kart (id);
}
public int getkartId()
{
return k.getId();
}
}
public static void main (string args[])
{
Ogrenci ogr = new Ogrenci(1234586,"Ali");
int id = ogr.getkartId();
}
}
Composition bilgileri saklar ve dişardan ne bilgi alır ne de dışarıya bilgi verir böylelikle bir nesnenin referansı başka bir ver tarafından tutulamaz ve buradaki nesnemizi öldürdüğümüz zaman tüm metodlar veriler beraberinde ölürler. Composition Aggregation'ın özel bir halidir. Composition da getter setter metodları kullanılmaz.Bunun sebebi getter setter metodları dışardan bağlantıya sebeb olur.Böylelikle bizler Composition yerine Aggregation yazmış oluruz Aliasing = bir nesneyi birden fazla pointer tutuyorsa buna Aliasing deniliyor
int [] a; // Bu şekilde diziler tanımlarız
int a[]={1,2,3,4,5,6}; // Diziyi aşagıdaki şekilde çagırırız.
a= new int [10]; // Diziyi oluşturma
2 boyutu diziler
String[][] name {
*
*
*
}
for (int DiziElemani : DiziIsmi){
System.out.println(DiziElemani)}
Burada görüldüğü gibi foreach şeklinde bir anahtar kelimemiz yok burada asıl yapılan iş dizinin içine girip dizinin içindeki elemanları tek tek okumak ve verilen komutları ona göre yapmak
Öncelikle burada bir for döngüsü açıyoruz sonrasında ":" dan sonra istediğimiz diziyi yazıyoruz sonrasında istediğimiz komutları yazıyoruz
int a [] = {2,3,5,6,96};
int b[] = a;
kopyalanacak olan dizi ile kopya olan dizi rem de aynı yeri gösterecek (pointer misali) burada biz b[] dizisinde bir veri değiştiridik mi otomatik olarak a[] dizisnde de değişiklik gözlenir
int b[] = new int [a.length]; // burada a dizisinin uzunlugunu b dizisine atadık
for (int i =0;i<a.length;i++) // burada ise teker teker verileri diğer diziye kaydetme
{
b[i]=a[i]
}