Nesneye dayalı programlamanın ( OOP ) asıl amacı gerçek hayattaki olguların programlamaya aktarılma yöntemidir. Klasik programlamada veriler ve bu verileri işleyen methodlar vardı. OOP’de ise gerçek hayattaki olguların detaylı olarak incelenerek programlamada veriler olarak saklanıp kullanılmasına fırsat verilmektedir.
Mesela bir arabamız olsun. Arabamızını markası, modeli, motor gücü, rengi ve hızı gibi bir çok özelliği vardır. Bu özellikler işlememiz gereken verilerdir. Aynı zamanda arabamızı çalıştırabilir, durdurabilir ve sürebiliriz. Bu tarz işlevler de methodlardır. Eğer biz bir ‘Araba’ sınıfı oluşturup nesneye dayalı programlamayı uygulasarsak. Arabanın özelliklerini veriler, işlevlerini fonksiyonlar olarak kullanıp programımıza kolaylıkla entegre edebiliriz. Ayrıca Araba sınıfı oluşturduğumuz için bu sınıftan nesneler oluşturup farklı farklı arabalar da üretebiliriz. OOP’nin bize sağladığı kolaylıklar bunlardır.
Nesneye dayalı programlamanın 3 temel prensibinden bahsedelim ;
- Encapsulation ( Kapsülleme )
- Polymorphism ( Çok biçimlilik )
- Inheritance ( Kalıtım )
Encapsulation ( Kapsülleme )
Kapsülleme verilerin ve işlemlerin dış etkilerden korunmasını, bir grup içinde toplanmasına denir. Kapsülleme sayesinde sınıfımız içinde kullandığımız alanların dışarıdan herhangi bir etki ile değiştirilmesini engellemiş oluruz. Bu durum bizim istediğimiz dışında oluşabilecek atamaların önüne geçmemize ve eğer bir atama yapılacaksa da bizim belirlediğimiz şekilde olmasına imkan sağlayacaktır. Bu özelliklerde nesne tabanlı programlamada kontrolün elimizde olmasını sağlıyor.
Inheritance ( Kalıtım )
Kalıtım için bir sınıfın bir başka sınıftan türetilerek oluşturulmasıdır diyebiliriz. Yeni oluşturulan sınıf miras aldığı üst sınıfın değişkenlerine ve methodlarına istediği zaman erişip kullanabilir. Bu durum da nesneye dayalı programlamada bir çok kolaylığı yanında getiriyor. Örneğin araçları düşünürsek araba, otobüs, kamyonet birer araçtır. Birbirlerinden farklı olsalarda hepsi birer araç olduğu için ortak noktaları da vardır. İşte bu ortak noktaları her bir sınıf için ayrı ayrı yazmaktansa Araç isimli bir üst sınıf oluşturup ortak özellikleri bu sınıfta toplayabiliriz.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
class Arac {
var marka = “”
var model = “”
var aracTipi = “”
func koltukSayisi()
{
println(“Koltuk sayısı : 0”)
}
}
class Araba: Arac {
}
class Otobus: Arac {
}
class Kamyonet: Arac {
}
|
Üstteki kodumuzda Arac sınıfını oluşturduk. Aynı kategoride olan Araba,Otobus ve Kamyonet sınıflarını da bu sınıftan miras alarak oluşturduk.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
var araba = Araba()
var otobus = Otobus()
var kamyonet = Kamyonet()
araba.aracTipi = “Araba”
araba.marka = “Ford”
araba.model = “Focus”
otobus.aracTipi = “Otobus”
otobus.marka = “Mercedes”
otobus.model = “Travego”
kamyonet.aracTipi = “Kamyonet”
kamyonet.marka = “BMC”
kamyonet.model = “Megastar”
|
Ana sınıfımızda da nesneleri oluşturup her bir sınıfın üst sınıfta tanımlanmış olan değişkenlerine erişip değer ataması yapabildiğini görüyoruz. Ortak özellikler dışında kendisine özgü özellikleride her bir sınıf için kendi içinde tanımlamasını yapıp işleminizi yapabilirsiniz.
Birde burada şundan bahsedebiliriz. Genelde iOS ve mac OS sınıfları NSObject sınıfından miras alır. Eğer bir kod temeliniz var ise swift sınıflarını da NSObject’den miras alarak oluşturabilirsiniz. Swift sınıflarında NSObject’den miras almanız size objective-c deki derleme esnasında esneklik sağlar fakat performansdan ödün verirsiniz. Eğer objective-c’nin esnekliğine gerek duymuyorsanız NSObject kullanmayıp performansdan öne çıkabilirsiniz.
Polymorphism ( Çok biçimlilik )
Polymorphism ( çok biçilmlilik ) bir A türünün bir başka tür olan B gibi davranabilme ve bu tür gibi kullanılabilme özelliğidir. Nesne yönelimli programlama dillerinde çok biçimlilik özelliği ise aynı temel sınıfdan türetilmiş olan sınıflarda paylaşılan aynı metodun bu sınıflarda farklı şekillerde uyarlanabilmesidir.
Yukarıdaki örnekte bahsettiğimiz gibi Araba,Otobüs,Kamyonet hepsi birer araçtır. Biz bu sınıfları Araç sınıfından miras alarak oluşturmuştuk. Araç sınıfının içinde bir aracın koltuk sayısını belirlediğimiz bir methodumuz vardı buna ek olarak maksimum hızını alabilmek için de bir method oluşturalım. Bu methodların içerikleri Araba,Otobüs ve Kamyonet için farklılık gösterebileceği için bu methodları yine bu sınıfların içinde override edip yeniden dolduruyoruz. Ve oluşturulan nesnelerden çağırdığımız aynı methodlardan farklı sonuçlar alabiliriz
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
class Arac {
func koltukSayisi()
{
println(“Koltuk sayısı : 0”)
}
}
class Araba: Arac {
override func koltukSayisi() {
println(“Koltuk sayısı : 4”)
}
}
class Otobus: Arac {
override func koltukSayisi() {
println(“Koltuk sayısı : 22”)
}
}
class Kamyonet: Arac {
override func koltukSayisi() {
println(“Koltuk sayısı : 3”)
}
}
|
Yukarıda üst sınıfımız olan Arac ve diğer alt sınıflarımızı oluşturduk. Ve ortak olan bir methodu tum sınıflarda override edip içini doldurduk.
1
2
3
4
5
6
7
|
var araba = Araba()
var otobus = Otobus()
var kamyonet = Kamyonet()
araba.koltukSayisi()
otobus.koltukSayisi()
kamyonet.koltukSayisi()
|
Main sınıfta da üstteki kodu çalıştırdığımız da çok biçimliliği sağlamış oluyoruz. Üst sınıftaki bir methodu bütün alt sınıflar kendilerine göre override edip kullandılar. Ve ekran çıktıları;
Koltuk sayısı : 4
Koltuk sayısı : 22
Koltuk sayısı : 3
Şeklinde olacaktır.
Konunun anlaşılması bakımından farklı bir örnek üstünde daha çalışalım;
Yeni örneğimiz de Counter,Terrorist ve Gun sınıflarımız var. Gun sınıfını üst sınıf olarak tanımladık ve içine ortak kullanılan silahları ve atak güçlerini girdik
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
import Cocoa
class Guns: NSObject {
let b13 = “b13”
let b21 = “b21”
let b22 = “b22”
let b31 = “b31”
let b41 = “b41”
let b43 = “b43”
let b46 = “b46”
var damage = 0
func gunList()
{
println(“-b13 Desert Eagle *30 damage \n-b21 BENELLI M3 SUPER *80 damage\n-b22 BENELLI XM – 1014 *60 damage\n-b31 MP5 NAVY *10 damage \n-b41 KALASHNIKOV *25 damage\n-b43 M4A1 *20 damage \n-b46 AWP *300 damage\n”)
}
func hitPower(Silah : String)->Int
{
if(Silah == b13)
{
return 30
}
else if(Silah == b21)
{
return 80
}
else if(Silah == b22)
{
return 60
}
else if(Silah == b31)
{
return 10
}
else if(Silah == b41)
{
return 25
}
else if (Silah == b43)
{
return 20
}
else if(Silah == b46)
{
return 300
}
else
{
return 0
}
}
}
|
Daha sonra Terrorist ve Counter sınıflarında bu silahları ve vuruş gücünü kullandık.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
class Counter: Guns {
var Hp = 100
var gunT = “”
let PlayerName = “”
init(gun : String , name : String){
gunT = gun
PlayerName = name
}
func Atack( Enemy : Terrorist)
{
Enemy.Hp = Enemy.Hp – hitPower(gunT)
println(“\(PlayerName) atacked \(Enemy.PlayerName) – \(Enemy.Hp) hp left”)
if(Enemy.Hp < 0)
{
println(“You are dead \(Enemy.PlayerName), sorry”)
}
}
func changeGun(gun : String)
{
gunT = gun;
println(“\n\(PlayerName) changed his gun to \(gunT) \n”)
}
}
|
hem Counter için hem Terrorist için sabit bir Hp ve bunun yanında silah ve isim değişkenleri tanımladık ve silah ve isim değişkenlerini init methodu içinde aldık. Her ikisi içinde birer nesne oluştururken kullanıcıdan silah ve isim girdilerini alalım ki kimin kime ateş ettiğini hangi silahla ateş ettiğini bilelim ve gelen hasara göre Hp değerini düşürelim.
Tabi birde Atack fonksiyonu oluşturduk ve kullacının seçtiği silahın vuruş gücüne göre Atack fonksiyonu içinde düşman oyuncunun hp değerini azalttık.
Bunun dışında birde silah değiştirme methodu oluşturduk isteğe göre silahını değiştirebilsin diye.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
class Terrorist: Guns {
var Hp = 100
var gunT = “”
let PlayerName = “”
init(gun : String , name : String){
gunT = gun
PlayerName = name
}
func Atack( Enemy : Counter)
{
Enemy.Hp = Enemy.Hp – hitPower(gunT)
println(“\(PlayerName) atacked \(Enemy.PlayerName) – \(Enemy.Hp) hp left”)
if(Enemy.Hp < 0)
{
println(“You are dead \(Enemy.PlayerName), sorry”)
}
}
func changeGun(gun : String)
{
gunT = gun;
println(“\n\(PlayerName) changed his gun to \(gunT) \n”)
}
}
|
Terrorist sınıfında da farklı bir şey yok sadece Atack fonksiyonunda Enemy parametresinin tipini Counter yaptık.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
var ct1 = Counter(gun: “b43”, name: “Sedat”)
var ct2 = Counter(gun: “b31”, name: “Özlem”)
var t1 = Terrorist(gun: “b41”, name: “Yigit”)
var t2 = Terrorist(gun: “b13”, name: “Mert”)
var t3 = Terrorist(gun: “b46”, name: “Esma)
ct1.gunList()
ct1.Atack(t1)
ct1.Atack(t1)
ct1.Atack(t1)
ct1.changeGun(“b21”)
t2.Atack(ct2)
t2.Atack(ct2)
t3.Atack(ct1)
|
Ana sayfamızda da nesnelerimizi oluşturup methodlarımızı çağırdık. İki counter iki terrorist nesnesi oluşturup birbirlerine ateş ettirdik.