2 Eylül 2015 Çarşamba

C# ile abstract class kullanımı ve protected, public ve private keyword'lerine bakış

Merhabalar,

Bu yazımızda OOP nin temel keyword'lerinden bahsediyor olacağız.

public, protected ve private.

Aslında kapsamına göre sıralamış olduk. Bu keyword'ler property, class veya metod olabilir yani burada hiç bir sınırlama yok.


İçlerinde en geniş kapsamlı olanı PUBLIC.
Bu keyword ile tanımlanmış property, class veya metodu herhangi bir sınırlama olmadan her yerden kullanabiliriz.



    public class Deneme1
    {
        public int Number;
    }

    public class Deneme2
    {
        public Deneme1 DenemeDegisken;
    }



Yukarıdaki minik kod bloğunda gördüğünüz üzere Deneme1 class'ını public olarak tanımladık ve Deneme2 class'ı içerisinde gönül rahatlığı ile kullanabildik.

Peki gelelim property'lere. Kodumuzu aşağıdaki gibi düzenlersek hiç bir sorun yaşamayız.
Deneme1 class'ı içerisinde bir tane public bir tane de private property ekledik. Deneme2 class'ı içerisinden Deneme1 class'ındaki public değişkene ulaşıp istediğimiz gibi kullanabiliyoruz. Ancak "Ulasilamaz" property'si için aynı şeyi söyleyemiyeceğiz. Çünkü private olarak tanımlanmış ve sadece kendi Deneme1 class'ı içerisindeki metodlarda kullanılabilir.

    public class Deneme1
    {
        public int Number;
        private String Ulasilamaz;
        public String Ulasilabilir;
    }

    public class Deneme2
    {
        private void Process()
        {
            Deneme1 D = new Deneme1();
            D.Ulasilabilir = "";
        }
    }




Şimdi birazda protected keywordü üzerinde konuşalım. Bu keyword ağırlıklı olarak kalıtım dediğimiz inherit yöntemi kullanıldığında çok işimize yarıyor.

Aşağıdaki kod parçacığında görüldüğü üzere bir tane Human bir tane de Student class'ımız var. Human class'ımız Student class'ına inherit edilmiş durumda. Yani Student Class'ı Human class'ından türetilmiş. Bu durumda Student class'ı içerisindeki tüm metodlarda Human class'ının public, internal ve protected property'leri ve metodları kullanılabilir. Human class'ı içerisindeki Kullanilabilir property'si Student class'ı içerisinden kullanılabilir ve örnekte de sorunsuz bir şekilde kullanılmıştır.



    public abstract class Human
    {
        public String Name;
        public String SurName;
        public int IdentityNumber;
        public DateTime BirthDate;
        protected String Kullanilabilir;

    }
    public class Student : Human
    {
        public String SchoolName;
        public int SchoolNumber;
        protected DoSomething()
        {
            String A = this.Kullanilabilir;
        }
    }




Peki Student class'ını create edip başka bir yerde kullanmaya çalışırsam? Bahsettiğim kodu aşağıya ekledim. Student class'ı create edildi ve Human class'ının bir elemanı olan Kullanilabilir property'sine erişmeye çalıştık ama hata aldık. Ne demiştik, protected tanımlanmış property'ler, class'lar veya metodlar sadece inherit edildiği class içerisinde kullanılabilir. Human class'ı içerisindeki Kullanilabilir property'si public olarak tanımlanmış olsaydı aşağıdaki örnekte hata almadan kodumuzu yazmaya devam edecektik.





     public class Deneme
    {
        void Proces()
        {
            Student Ogrenci = new Student();
            Ogrenci.Kullanilabilir = ""; // Hatalı Satır
        }
    }



Sıra geldi interface ile çok karıştırılan ancak ikisi arasında bariz farklar olan abstract kullanımına. Abstract diyince aklınıza ilk olarak "Create Edilemez" ifadesi gelmeli. Çünkü abstract ön eki ile bir class oluşturulduğunda o class'ı "new" kodu ile create edemezsiniz. Editörünüz buna izin vermez ve size kızar. Abstract class'ların normal class'lardan tek farkı create edilemiyor olmasıdır. Onun dışındaki her türlü kullanıma açıktır.

Peki abstract nerede ve neden işimize yarasın ki dediğinizi duyar gibiyim :)

Yukarıdaki örneğimizide Human diye bir class vardı. Dikkat ettiyseniz bu class abstract ön eki almıştı. Durumu şöyle özetleyebiliriz. Human bizim en temeldeki class'ımız. Yeni doğmuş bir bebek gibi düşünebiliriz. Her bebek büyüyüp belli özelliklere sahip olur ama en başta bebektir. Bir bebeğin doğduğunda sahip olduğu tüm özellikleri hala taşımaktadır. ( 2 el, 2 göz, adı, soyadı vs.)

Bu durumda büyümüş her insan aslında bebek iken sahip olduğu özellikleri hala taşımaktadır. Yani aslında herkes biraz bebektir :) Bir öğrenci düşünün. Adı, soyadı, tckimlik numarası ve doğum tarihi gibi temel bilgilere sahiptir. Bir İnşaat işçisi düşünün aynı özelliklere inşaat işçisi de sahiptir.

Şimdi ben bir öğrenci class'ı oluşturmak istesem ne yapmam gerekir ? Saydığım bütün bu özellikleri bu class içerisine property olarak ekleyebilirim. Peki inşaat işçisi için bir class yaratmak istesem aynı özellikleri bu class içerisine de yazabilirim. Hobaa ben bu özellikleri az önce öğrenci class'ı için yazmıştım zaten bir daha neden yazıyorum ki demeli insan :) Hadi biz de öyle demiş olalım.

Bu temel bilgilerin olduğu Human diye bir class yaratıyorum. Bu saydığım özellikleri bu class'a ekliyorum. Daha sonra oluşturmak istediğim inşaat işçisi ve öğrenci class'larını Human class'ından türetip fazla kod yazmış olmaktan kurtuldum.

Buraya kadar aslında class'ların birbirinden türemesinin faydasını anlatmış olduk. Şimdi abstract ne işe yarıyor diyorsunuzdur herhalde.

Human class'ımız belirttiğimiz gibi abstract yani create edilemez olarak tanımlandı. Buradaki amaç
bir student yada işçi class'ı oluşturur gibi Human class'ını oluşturmak istemememiz.

Human class'ının görevi sadece benim için diğer class'lara temel bilgileri sunmasıdır. Human class'ını tek başına create edersem eğer sadece içindeki temel bilgileri kullanmış olurum ama ben bunu istemiyorum. Ben yeni class'lar yaratıp o class'ların bu temel özelliklere sahip olmasını istiyorum.





Bu yazımızda bir kaç bilgiyi daha paylaşmış olduk. Anlaşılmayan konular veya kavramlar için benimle her zaman iletişime geçebilirsiniz.

Son olarak yukarıda bahsetmiş olduğumuz kodlara ilişkin minik örneğimizin ekran görüntüsünü paylaşıyorum..

















24 Ağustos 2014 Pazar

Delphi ile Overload Metod Tanımlamak

İlk olarak Overload ne demektir ne için kullanılır onu öğrenelim. "Overload" kelime anlamı olarak "Aşırı Yük" veya "Aşırı Yükleme" anlamına geliyor. Programcılıkta ise aynı isimli metodlar yaratabilmek için kullanılıyor. ( Aynı isimli metodlar kullanarak o metodu aşırı yüklemiş oluyoruz. Çünkü aşırı yüklenmediği taktirde aynı isme sahip en fazla 1 tane metod kullanılabilir )

 Delphi üzerinde farklı işi yapsalar bile aynı isime sahip metodlar yazdığınızda Delphi bize kızacak ve "MetodName must be marked with the 'overload' directive" hatasını verecektir. Bunun olmaması için ise aynı isimli yazmış olduğumuz metodlarımızın sonuna "Overload;" ifadesini eklememiz gerekecek. Overloading yapmanın en temel amacı, farklı tipte veya sayıda parametreyi aynı isimli metodlara gönderebilmektir.


Hemen küçük bir örnek ile deneyelim































Gördüğünüz gibi "Hesapla" isminde farklı işler yapan 3 farklı function tanımladık. İsimleri aynı olmasına rağmen yaptığı işler farklı olabiliyor, hatta aldıkları ve geriye döndürdükleri parametre tipleri bile farklı olabiliyor. Kullanımı sırasında Delphi tarafından aşağıdaki gibi bilgilendiriliyoruz.


19 Ağustos 2014 Salı

C# İçerisinde Kullanılan String Metodlar - String Fonksiyonlar

Merhabalar, Bugün C# ta aslında işimize çok yarayan string tipi ile kullanılan metodları inceleme fırsatı bulacağız. Hemen örneklere geçelim


String.Compare: Yaptığı iş aslında kendisine verilen 2 adet string tipindeki değerin bir birine eşit olup olmadığıdır. ( 3. Parametre boolean bir tiptedir ve true verirseniz büyük küçük harf duyarlılığını dikkate almaz). Bu metod bize 0, 1 veya -1 diye 3 farklı sonuç döndürecektir. Eğer değerler eşit ise 0 dönecek. Peki geriye kalan 1 ve -1 hangi durumlarda dönecek ? Hemen cevap verelim, burada metodumuz alfabettik hassasiyet gösteriyor. İlk parametre alfabetik olarak ikinci parametreden önce yer alıyorsa sonuç -1 dönecektir. Tam tersi durumda ise 1 olarak değer döndürür.




String.Concat: Kendisine parametre olarak verilen sınırsız sayıda string değeri yanyana birleştirip geriye tek bir string olarak dönecektir.






String.Copy: Tek parametreli bir fonksiyondur. Kendisine parametre olarak verilen değeri geriye döndürür. Burada asıl amaç değişkenler arası bir atama işlemi değil, bir değişkenin değerinin başka bir değişkene kopyalanmasıdır.







String.Equals: Geriye Boolean bir değer döndürmektedir. Kendisine verilen 2 object tipindeki değerin birbirine eşit olupmadığını kontrol ediyor, eğer eşit ise true döndürüyor.









IndexOf: String Sınıfının altında bulunmadığından kullanımı String.IndexOf olarak değildir ancak String bir değişkenin sonuna nokta koyduğumuz zaman orada görebiliriz. String değişkenin içinde başka bir string ifade arar. Eğer bulamazsa -1, bulduğunda ise kaçıncı karakterden itibaren olduğunu döndürüyor.














Insert: String bir değere istediğimiz karakterden sonra istediğimiz başka bir string değeri eklememize yarayan bir metoddur.










Length: String bir ifadenin uzunluğunu integer olarak geriye dönen fonksiyondur.












Remove: String bir ifadeden dilediğimiz karakter sayısı kadar kesebilmemiz için kullanılır. Aslına bakarsak 2 kes Overload edilmiş bir fonksiyondur. Yani aynı isimde olan ancak farklı iş yapan 2 fonksiyon vardır. ilk metod tek parametre alır ve verilen karakter index numarasından sonraki tüm karakterleri siler. Diğer kullanımı ise 2 parametreli, ilk verdiğimiz karakter index numarasından itibaren ikinci parametre değeri kadar karakter siler. Geriye string bir değer döndürür.













Replace: String bir ifade içerisinde belirlemiş olduğumuz Char yada String bir ifadeyi başka bir ifade ile değiştirebiliriz.








SubString: String ifade içerisinden belli bir bölümü almak için kullanılır. 2 kez Overload edilmiş bir metoddur.
İlk kullanımı tek ve integer tipinde parametreli olandır. Parametre olarak verilen karakterden sonraki ifadeyi String olarak geriye döner. İkinci kullanımında ise 2 tane integer parametre var. İlk parametreden itibaren ikinci parametre kadar olan string ifadeyi geriye döner.











ToUpper: String bir ifadeyi büyük harf olarak geriye döner.
ToLower:  String bir ifadeyi küçük harf olarak geriye döner.














Trim: String ifadenin başından ve sonundan boşluk karakterlerini temizler
TrimStart: String ifadenin sadece başındaki boşlukları temizler
TrimEnd: String ifadenin sadece sonundaki boşlukları temizler














PadLeft: String bir ifadenin başına istediğimiz bir char tipinde ifadeyi istediğimiz sayı kadar eklememize yarayan metoddur.
PadRight: PadLeft'ten farkı ifadenin başına değil sonuna ekleme yapmasıdır.
( Not: Eğer karakter belirtmezsen boşluk karakteri ekliyor )













17 Ağustos 2014 Pazar

C# ta String Birleştirme de LinQ & Aggregate Kullanımı



Diyelim elinizde string tipinde bir List var. Bu list'in içerisinde de mail adreslerinizin kayıtlı olduğunu düşünelim. Tek bir seferde birden fazla mail atmak için mail adresleri ";" ile ayrılarak tek bir mail adresi gibi gönderilir. Bu List içerisinde basit bir döngü ile dönerek istediğimiz gibi bir string oluşturabiliriz. Yada aşağıdaki gibi LinQ nun bizlere sunmuş olduğu Aggregate metodunu kullanabiliriz.




Delphi ile Kolay Thread Kullanımı


Delphi de Thread konusu yıllardır insanları korkutmuştur. Bugün çok basit bir örnek ile "Thread" i biraz inceleme fırsatı bulacağız.

Öncelikle Thread kullanırken hakkında bilmemiz gereken bir şey var. Thread Create edildiğinde eğer özellikle belirtilmedi ise hemen çalışmaya başlar. TThread sınıfı içerisinde Execute metodu vardır ve thread'in başlaması demek aslında Execute metodunun çalışması demektir. Execute metodunu Override ederek thread'in bizim istediğimiz şeyleri yapmasını sağlıyıcaz. Az önce söylediğim gibi özellikle belirtilmedi ise otomatik başlıyor. Peki bunu özellikle nasıl belirteceğiz.? Hemen cevap verelim. Şöyle ki, Create Metodu içerisinde "inherited Create(False);" gibi bir tanımlama yapacağız ki otomatik olarak başlamasın. Peki otomatik başlamayacaksa biz hazır olduğumuzda nasıl başlatacağız? Kilit cevap "Resume" metodunda yatıyor. Hazır olduğumuzda Thread'imizin başlaması için ( Execute Metodunun Başlaması ) Resume Metodunu kullanıyoruz.


16 Ağustos 2014 Cumartesi

C# String Birleştirmede Performans

.Net çatısı altında özellikle de birden fazla client'ın aynı anda bağlandığı bir mimaride, server tarafında string birleştirme işlemleri çok sık kullanılıyorsa dikkat edilmesi gereken bir konu var.


İşletim sisteminin çalışma yapısı gereği .net çatısı altında string değişkenler birbirleri ile birleştirildiklerinde Ram Bellek üzerinde eski ve yeni değer olmak üzere 2 adet yer ayırılır ve bu yerlerde bu değişkenlerin değerleri saklanır. Örnek vermek gerekirse,

diyelim String s1 = "C#"; ve String s2 = "CSharp"; diye iki değişken tanımladık ve daha sonra s1 = s1 + s2; komutunu verdik.
Bu durumda en başta bellek üzerinde s1 ve s2 değişkenleri için yer ayırılmış ve değerleri saklanmıştı. Daha sonra bizim birleştirme işlemimizden sonra durum şöyle oldu. s1, s2 ve yeni s1. s1 değişkeninin birleşmeden önceki hali de bellek üzerinde saklanmakta. Bu işlem küçük sayıdaki birleştirmeler için elbet dert edecek kadar sorunlar çıkartmayacaktır ancak özellikle "Web Service" veya Web Siteleri gibi birden fazla Client'ın aynı anda istek yapması durumunda bu tür birleştirmeler can yakabilir. Durumu daha iyi özetleyebilmek adına aşağıdaki örneği inceleyelim.



Formumuz üzerinde 2 adet buton ve 2 adet textBox bulunmakta.
Üzerinde Normal yazan buton a basıldığında 0 dan başlayarak 50.000 e kadar olan bütün sayıları string birleştirme yolu ile birleştirerek tek bir değişkende toplayacağız.Toplamda bu işlemin bilgisayarımız tarafından ne kadar sürdüğünü hesaplayıp çıkan değeri milisaniye cinsinden textBox'a yazdıracağız.

With SB butonuna tıklantığında ise .Net yapısının bizim için geliştirmiş olduğu bir "Nesne" kullanarak aynı birleştirme işlemini gerçekleştireceğiz. "StringBuilder". Bu nesne aslına bakılacak olursa List<String> Tipinde bir nesne gibi iş yapıyor. StringBuilder nesnesi içerisinde birleştirme yaptığımızda ise Bellek üzerinde bu nesne için tek bir yer ayırılıyor ve her birleştirme işlemi sırasında bu bilgi güncelleniyor.




Aşağıdaki ekranda ise kullandığımız kodlar ve almış olduğumuz sonuç yer alıyor. Aradaki süre farkı epey fazla.

İyi düşünün iyi yazın.

Başka Makalede görüşmek üzere



Delphi ile ExtractStrings Kullanımı



Öncelikle metodun ne iş yaptığından bahsedelim. Adından da anlaşılacağı gibi kendisine parametre olarak verilen string bir değeri yine kendisine parametre olarak verilen seperator lere ayırarak size bir string tipinde bir liste döner. Aslında döner dediğime bakmayın, bu bir function değil bir procedure. Dolayısı ile yine kendisine parametre olarak verilen  TStrings sınıfından türetilmiş bir Liste yi dolduruyor. Aşağıdaki örnek ile daha net anlayabiliriz



Metodun en can alıcı özelliklerinden birisi ayıraç olarak kullanacağımız Char tipindeki değişkenlerin çeşitliliği. Birden fazla ayraç kullanabiliyoruz.


Metod kullanılırken dikkat edilmesi gereken diğer bir husus ise parametre olarak göndermiş olduğumuz list tipindeki değişkenin tarafımızdan Create edildikten sonra metodumuzda kullanılması gerektiğidir. Eğer Create etmezsek ExtractStrings metodu Exception Throw ediyor. (Access Violation)




procedure TForm1.btnParseClick(Sender: TObject);
var
  Str: String;
  parsedList: TStringList;
begin
  Str := '1, 2, 3, 4, 5, 6, 7, 8; 9: 10_11_12;13:14;16-17.18.19';
  parsedList := TStringList.Create; // Create Etmeyi Unutmayın Yoksa Metodunuz Hata Fırlatacaktır
  ExtractStrings([':', ';', '.', ',', '_', '-'], [' '], PAnsiChar(Str), parsedList);
  edParsedStr.Lines.Assign(parsedList);
  parsedList.free; // işimiz bitti artık free ediyoruz.
end;


Çıktısı: