VB.NET NESNE YÖNELİMLİ

VB.NET mor kalkanı üzerinde VB harfleri ile üç katmanlı sınıf kalıtım piramidi dominant kompozisyon

2002 yılında Microsoft, Visual Basic 6 ile bambaşka bir yola sapan VB.NET'i duyurduğunda topluluk ikiye bölündü. Bir tarafta on yıllık VB6 kod tabanı, COM bileşenleri ve "Form üzerine sürükle-bırak" alışkanlığı vardı; diğer tarafta ise Common Language Runtime üzerinde çalışan, C# ile aynı tür sistemini paylaşan ve gerçek anlamda nesne yönelimli olan yeni bir dil. VB6'da modüller ve "Class Module" adıyla yarı-OOP destek vardı; ancak kalıtım yoktu, polimorfizm zayıftı, arayüzler sınırlıydı. VB.NET ise CLR'nin sunduğu tip sistemini benimseyerek tam OOP kapasitesine kavuştu. Bu yazıda VB6 dünyasından gelenlerin yeni modele nasıl adapte olabileceğini ve VB.NET'te nesne yönelimli programlamanın temel yapılarını adım adım göreceksiniz.

VB6'dan VB.NET'e Geçişin Anlamı

VB6, kendi runtime'ı (msvbvm60.dll) üzerinde çalışan, COM tabanlı bir ortamdı. VB.NET ise tamamen .NET Framework (ve sonrasında .NET Core / .NET 5+) üzerinde, ortak bir Common Language Runtime ile çalışır. Bu değişikliğin pratik sonuçları şunlardır: Konuya ilişkin konuya dair temel başvuru ek bir başvuru kaynağı olarak değerlendirilebilir.

  • Tüm türler System.Object'ten türer — yani her şey gerçekten nesnedir.
  • Garbage Collector bellek yönetimini üstlenir; Set obj = Nothing alışkanlığı artık zorunlu değildir.
  • C#, F# gibi diğer .NET dilleriyle aynı sınıfları paylaşabilir, aynı kütüphaneleri kullanabilirsiniz.
  • Hata yönetimi On Error Goto yerine yapılandırılmış Try...Catch...Finally bloklarına geçer.
  • Varsayılan parametre geçişi ByRef'ten ByVal'a değişmiştir; bu, VB6 kodunu taşırken en sık hata kaynağıdır.

Geçişin kavramsal olarak en büyük etkisi, dilin artık "form üzerinde script yazılan bir araç" olmaktan çıkıp tam yetkili bir OOP dili haline gelmesidir. Detaylı dil yapısı ve syntax karşılaştırması için VB.NET eğitimi içeriğinden yararlanabilirsiniz.

Sınıf ve Nesne: Temel Yapı Taşları

VB.NET'te sınıf tanımı Class anahtar kelimesiyle başlar. VB6'daki "Class Module" mantığına benzese de yetenekleri çok daha geniştir: alanlar, özellikler, metotlar, olaylar ve yapıcılar (constructor) tek bir blokta toplanır.

Public Class Musteri
    Private _ad As String
    Private _bakiye As Decimal

    Public Sub New(ByVal ad As String)
        _ad = ad
        _bakiye = 0D
    End Sub

    Public Property Ad As String
        Get
            Return _ad
        End Get
        Set(value As String)
            If String.IsNullOrWhiteSpace(value) Then
                Throw New ArgumentException("Ad boş olamaz")
            End If
            _ad = value
        End Set
    End Property

    Public Sub ParaYatir(ByVal miktar As Decimal)
        If miktar <= 0D Then Return
        _bakiye += miktar
    End Sub
End Class

Burada Sub New yapıcı metottur ve nesne oluşturulurken çağrılır. Property blokları VB6'daki Property Let/Get yapısının modern karşılığıdır; tek blok içinde okuma ve yazma davranışını birlikte tanımlar.

Kapsülasyon mor kapsül içinde kilitli private alanlar dış public metot ok ve metot arayüz diyagramı

Kapsülleme (Encapsulation)

Kapsülleme, bir nesnenin iç durumunu dışarıya doğrudan açmadan, kontrollü bir arayüzle sunmaktır. VB.NET dört erişim seviyesi sunar:

  • Public: Her yerden erişilebilir.
  • Private: Sadece tanımlandığı sınıf içinden erişilebilir.
  • Protected: Sınıf ve ondan türeyen alt sınıflardan erişilebilir.
  • Friend: Aynı assembly (proje) içinden erişilebilir; diğer dillerdeki internal karşılığıdır.

VB6'da Private ve Public dışında pratik bir seçenek yoktu; Friend sadece DLL ölçeğinde anlamlıydı. VB.NET'te erişim seviyeleri ile alanları gizleyip yalnızca Property üzerinden okuma/yazma davranışı dayatabilirsiniz. Bu, geçersiz duruma düşmeyi engelleyen ilk savunma hattıdır.

Kalıtım (Inheritance)

VB6'da kalıtım yoktu — sadece Implements ile arayüz benzeri davranış taklit edilebiliyordu. VB.NET'te ise Inherits anahtar kelimesiyle gerçek sınıf kalıtımı vardır:

Public Class KurumsalMusteri
    Inherits Musteri

    Public Property VergiNo As String

    Public Sub New(ByVal ad As String, ByVal vergiNo As String)
        MyBase.New(ad)
        Me.VergiNo = vergiNo
    End Sub
End Class

MyBase üst sınıfa referanstır; MyBase.New çağrısı üst sınıfın yapıcı metodunu tetikler. Bir sınıfın kalıtımı kapatılmak isteniyorsa NotInheritable (C#'taki sealed), tek başına örneklenememesi isteniyorsa MustInherit (C#'taki abstract) kullanılır.

Polimorfizm: Overridable, Overrides, MustOverride

Polimorfizm, aynı metot çağrısının nesnenin gerçek türüne göre farklı davranmasıdır. VB.NET'te bir metodun alt sınıfta ezilebilmesi için üst sınıfta Overridable ile işaretlenmesi, alt sınıfta ise Overrides ile yeniden tanımlanması gerekir:

Public MustInherit Class Sekil
    Public MustOverride Function Alan() As Double
End Class

Public Class Daire
    Inherits Sekil
    Public Property Yaricap As Double

    Public Overrides Function Alan() As Double
        Return Math.PI * Yaricap * Yaricap
    End Function
End Class

Public Class Kare
    Inherits Sekil
    Public Property Kenar As Double

    Public Overrides Function Alan() As Double
        Return Kenar * Kenar
    End Function
End Class

Artık Sekil tipinde bir değişken hem Daire hem Kare tutabilir; Alan() çağrısı çalışma zamanında doğru sınıfa yönlendirilir. Bu, koleksiyonları tek bir tip üzerinden işlemek için güçlü bir araçtır.

Arayüzler (Interfaces)

VB6'daki Implements kullanımı VB.NET'te de korunmuştur, ancak arayüzler artık tam OOP vatandaşıdır. Bir sınıf birden fazla arayüz uygulayabilir; bu, tek kalıtım kısıtının yarattığı sınırı aşmanın yoludur:

Public Interface ILoglanabilir
    Sub Logla(mesaj As String)
End Interface

Public Interface IYedeklenebilir
    Function Yedek() As Byte()
End Interface

Public Class Rapor
    Implements ILoglanabilir, IYedeklenebilir

    Public Sub Logla(mesaj As String) Implements ILoglanabilir.Logla
        Console.WriteLine($"[LOG] {mesaj}")
    End Sub

    Public Function Yedek() As Byte() Implements IYedeklenebilir.Yedek
        Return New Byte() {}
    End Function
End Class

Arayüzler, "ne yapar" sözleşmesini tanımlar; "nasıl yapar" ise uygulayan sınıfın işidir. Bağımlılıkları somut sınıflar yerine arayüzler üzerinden kurmak, test edilebilir ve genişletilebilir kod için en önemli alışkanlıklardan biridir.

Hata Yönetimi ve Kaynak Yönetimi

VB6'daki On Error Resume Next alışkanlığı VB.NET dünyasında bir antipattern olarak görülür. Modern yaklaşımda hatalar Exception nesneleridir ve Try...Catch blokları ile yakalanır:

  1. Try: Riskli kod buraya yazılır.
  2. Catch: Belirli istisna türleri yakalanır; genelden özele değil, özelden genele sıralanır.
  3. Finally: İstisna olsun ya da olmasın çalışacak temizlik kodu buraya gelir.
  4. Using: IDisposable uygulayan kaynakların otomatik kapanması için tercih edilir.

VB.NET, garbage collector sayesinde bellek yönetiminin büyük kısmını üstlenir; ancak dosya, veritabanı bağlantısı, soket gibi yönetilmeyen kaynaklar için Using bloğu veya IDisposable deseni hâlâ kritik öneme dedir. OOP prensiplerini gerçek projelerde uygulamaya dökmek isteyenler, kapsamlı VB.NET eğitimi içeriğini inceleyebilirsiniz.

Polimorfizm üst sınıftan üç farklı şekle dallanma ve kesik çizgili arayüz sözleşmesi diyagramı

VB6 Geliştiricisinin Sık Karşılaştığı Tuzaklar

Eski VB6 kodunu VB.NET'e taşırken çoğu hata aslında dilin değil, alışkanlıkların ürünüdür:

  • Variant tipi yoktur; Object kullanılır, ancak tip güvenliği için mümkün olduğunca somut tip tercih edilmelidir.
  • Dizilerde alt sınır artık her zaman 0'dır; Option Base 1 kalktı.
  • Varsayılan parametre geçişi ByVal'dır; yan etki üreten kodda bu fark gözden kaçabilir.
  • Set anahtar kelimesi atama için artık gerekli değildir.
  • String karşılaştırmasında Option Compare Binary ile Text arasındaki farkı projeye eklemeden test edin.

Nesne yönelimli düşünme alışkanlığı geliştikçe kodun büyüklüğüyle bakımı arasındaki orantı değişir: 500 satırlık bir formdan 50 küçük sınıfa geçmek başta zorlayıcı görünse de uzun vadede çok daha az hatayla ve çok daha hızlı geliştirme döngüsüyle sonuçlanır. VB.NET, OOP'yi öğrenmek isteyen bir geliştirici için hem söz dizimi okunaklı hem de tüm .NET ekosisteminin kapısını aralayan bir başlangıç noktasıdır.