Kapsülleme (Encapsulation), nesne yönetlimli olarak hazırlanan bir yazılımda en önemli konulardan birisidir. Kapsüllemenin iki önemli amacı vardır:

     1. Arka Plan Kodlarını Gizleme: Oluşturulan bir class içerisinde kullanıcının işlemlerini daha kolay gerçekleştirebilmesi için bazı işlemler birleştirilerek (kapsüllenerek) tek bir işlem gibi gösterilir. Örneğin veritabanına bağlantı işleminde, biz sadece bağlantı değişkeninin Open() metodunu kullanmaktayız. Fakat sınıf içerisinde kullanıcıdan aldığı parametreleri kullanarak bağlantıyı gerçekleştirebilmek için birçok metod bulunmaktadır. Bu metodları kullanıcıya gösterip bağlantıyı sağlayabilmek için bunları şu şekilde birleştirin demek yerine bu işlem sınıf içerisinde yapılmış ve kullanıcının kolaylıkla kullanabilmesi için Open() metodu oluşturulmuştur.

     2. Değişkenlere Tam Erişimi Engelleme: Sınıf içerisinde oluşturduğumuz global değişkenlere dışarıdan erişmek için public olarak tanımlama yapmaktayız. Fakat bazen bu değişkenlerin değerlerini değiştirmek istemeyebiliriz. Fakat kullanmamız da gerekebilir. Bu durumda değişkenimizi kapsüllememiz gerekmektedir. Yani, bu değişkeni private olarak tanımlamak ve bir read-only property ile bu değişkenin yazma iznini ortadan kaldırmamız gerekmektedir.

Bu konuyu bir örnek ile pekiştirelim:

Oluşturacağım program içerisinde SMS gönderme işlemi gerçekleştirmek istiyoruz. Bu işlem için SMS isimli bir sınıf oluşturacağız. Bu sınıf içerisinde SMS gönderebilmek için gerekli işlemler yapılacaktır. Ayrıca kullanıcının Türkçe karakter kullanması ihtimalini göz önünde bulundurarak bu karakterleri düzenleme işlemini de gerçekleştirmemiz gerekecektir:

    class SMS
    {
        private string kullaniciAdi, sifre;
        public SMS(string kullaniciAdi, string sifre)
        {
            this.kullaniciAdi = kullaniciAdi;
            this.sifre = sifre;
        }
        private void TurkceKarakterleriDuzenle(ref string mesaj)
        {
            char[] trKarakterler = { ‘ç’, ‘ğ’, ‘ı’, ‘ö’, ‘ş’, ‘ü’, ‘Ç’, ‘Ğ’,’İ’, ‘Ö’, ‘Ş’, ‘Ü’ };
            char[] ingKarakterler = { ‘C’, ‘g’, ‘i’, ‘o’, ‘s’, ‘u’, ‘C’, ‘G’,’I’, ‘O’, ‘S’, ‘U’ };
            for (int i = 0; i < ingKarakterler.Length; i++)
            {
                mesaj.Replace(trKarakterler[i], ingKarakterler[i]);
            }
        }
        private string XMLOlustur(string mesaj)
        {
            //Mesaj metnini, kullanıcı adı ve şifreyiXML içerisine yerleştir.
            throw new NotImplementedException();
        }
        private void SMSGonder(string xmlMetni)
        {
            //SMS’i gönderme işlemi
        }
        public void Gonder(string mesaj)
        {
            //Türkçe karakterleri düzenle
            TurkceKarakterleriDuzenle(ref mesaj);//1
            string xmlMetni = XMLOlustur(mesaj);//2
            SMSGonder(xmlMetni);//3
        }
    }

Bu sınıfı kullanan bir kullanıcı, SMS gönderebilmek için XML düzenleme, XML’i sunucuya gönderme ve karakterleri düzenleme işlemlerini yapmasına gerek olmadan sadece Gonder isimli metodu kullanarak mesajını gönderebilecektir.

SMS smsMesaji = new SMS(“Kullanıcı Adı”, “Şifre”);
smsMesaji.Gonder(“Mesaj Metni”);

Şimdi kapsüllemenin kullanıldığı 2. maddeyi inceleyelim:

Geometrik şekiller ile ilgili bir program yazmaktayız ve bu program içerisinde her nesne türü için bir sınıf oluşturuyoruz. Örneğin kare işlemleri için Kare sınıfını oluşturuyoruz. Kare sınıfından türettiğim bir kare değişkenimin enini değişkenim oluştururken belirleyip bir daha değiştirmek istemiyorum:

    class Kare
    {
        private double kenar;
        public Kare(double kenar)
        {
            this.kenar = kenar;
        }
        public double Kenar
        {
            get { return this.kenar; }
        }
    }
Örnek kodumuzda, constructor ile kenar uzunluğumuzu aldık. Bu uzunluğu private bir global değişkende saklıyoruz. İstendiği zaman Kenar isimli property ile bu değere ulaşabiliyoruz fakat değiştiremiyoruz.