Abstract, Türkçe karşılığından da anlaşılacağı üzere, “Soyut” demektir. Peki, abstract classların normal classlardan farkı nedir? Daha önceden Kalıtım (Inheritence) konumuzda Geometrik Şekil ve ondan türeyen Kare ve Dikdörtgen sınıf örneğini vermiştim. Bu Geometrik Şekil sınıfımızda AlanHesapla() metodumuz mevcuttu, bu metodu diğer Kare ve Dikdörtgen sınıflarında override işlemi yani yeniden yazıyorduk. 

Aslında burada bakılırsa, AlanHesapla() metodunun Geometrik Şekil içinde bir önemi yok, çünkü Geometrik Şekil genel olduğu için hesaplanacak olan alanın önemi yok. İşte bunun yerine abstract sınıf ve abstract metot kavramlarını kullanıyoruz. Şimdi tekrar hatırlamak amacıyla Kalıtım konusundaki örneğimizi tekrar ele alalım.

open public class GeometrikSekil
{
    var en : Int = 0
    var boy : Int = 0
    
    
    open fun AlanHesapla()
    {
        println("Geoemetrik Şeklin Alanı : " + en*boy)
    }
}

class Kare : GeometrikSekil()
{
    override fun AlanHesapla()
    {
        println("Karenin Alanı : " + en*boy)
    }
}

class Dikdortgen : GeometrikSekil()
{
    override fun AlanHesapla()
    {
        println("Dikdortgenin Alanı : " + en*boy)
    }
}

fun main(args: Array<String>)
{
    var kare : Kare = Kare()
    kare.en = 5
    kare.boy = 5
    kare.AlanHesapla()
    
    var dikDortgen : Dikdortgen = Dikdortgen()
    dikDortgen.en = 7
    dikDortgen.boy = 9
    dikDortgen.AlanHesapla()
}


AlanHesapla() metodumun türettiğim iki sınıfta ta olmasını istiyorum, ancak dikkat edilirse; GeometrikSekil() sınıfındaki AlanHesapla() metodunun bir önemi yok, dolayısıyla bunu abstract olarak tanımlarım. Abstract sınıf şeklinde yazılışını aşağıda da verelim.

abstract class GeometrikSekil
{
    var en : Int = 0
    var boy : Int = 0
        
    abstract fun AlanHesapla()
 
}

class Kare : GeometrikSekil()
{
    override fun AlanHesapla()
    {
        println("Karenin Alanı : " + en*boy)
    }
}

class Dikdortgen : GeometrikSekil()
{
    override fun AlanHesapla()
    {
        println("Dikdortgenin Alanı : " + en*boy)
    }
}

fun main(args: Array<String>)
{
    var kare : Kare = Kare()
    kare.en = 5
    kare.boy = 5
    kare.AlanHesapla()
    
    var dikDortgen : Dikdortgen = Dikdortgen()
    dikDortgen.en = 7
    dikDortgen.boy = 9
    dikDortgen.AlanHesapla()
}


Burada dikkat edilirse abstract class olarak tanımlarken, metodumuz hiçbir şekilde “{}” parantezleri içeremez. Adı üstünde soyut sınıf ve soyut metot olduğu için tanımlanan soyut metotlar bu şekilde gerçekleştirilmelidir.

Abstract classlar daima “open” olarak tanımlanmıştır. Bir soyut, abstract final class olarak tanımlanırsa derleyici hata verecektir. Ayrıca, tanımlanan tüm abstract metotlar da daima “open” olarak tanımlanmıştır. “open” anahtar sözcüğü hatırlanacağı üzere, üzerine tekrardan yazılabilir (override edilebilir) anlamındaydı.

Ek olarak, bir abstract class sadece abstract metot barındırmak zorunda değildir. Abstract olmayan metotlarda barındırabilirler.

abstract class Space()
{

    abstract fun CO2()
    
    fun isPlanet(Name:String)
    {
        println("$Name is a planet..")
    }    
}

class World : Space()
{
    override fun CO2()
    {
        println("World contains CO2")
    }
    
    fun isPlanet()
    {
        super.isPlanet("World")
    }
}

class Mars : Space()
{
    override fun CO2()
    {
        println("Mars does not contain CO2")
    }
    
    fun isPlanet()
    {
        super.isPlanet("Mars")
    }
}

fun main (args: Array<String>)
{
    var world : World = World()
    world.CO2()
    world.isPlanet()
    
    var mars : Mars = Mars()
    mars.CO2()
    mars.isPlanet()
}


Burada Space() sınıfımız hem abstract hem abstract olmayan metot içermektedir. Ayrıca abstract classlar kurucu metotlar da içerebilirler. Yukarıdaki örneğin aynısını kurucu metot kullanarak yapalım.

abstract class Space(var name : String)
{

    var pname = ""
    
    init
    {
        this.pname = name
        println("$pname is a planet..")
    }
    
    abstract fun CO2()
   
    
       
}

class World(name : String) : Space(name)
{
    override fun CO2()
    {
        println("World contains CO2")
    }
    
    
}

class Mars(name : String) : Space(name)
{
    override fun CO2()
    {
        println("Mars does not contain CO2")
    }
    
 
}

fun main (args: Array<String>)
{
  var world : World = World("World") // kurucu metot vasıtasıyla
  var mars : Mars = Mars("Mars")  // kurucu metot vasıtasıyla
  world.CO2()
  mars.CO2()
  var space : Space = Space("Space") // NESNE OLUŞTURULAMAZ!! 
  /* Cannot create an instance of an abstract class*/

}


Son olarak, abstract classlardan nesne oluşturulamaz!