Clear        


                
                    using _21_ConstructorChaining.Demos.DosyaIslemleri;

namespace _21_ConstructorChaining
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // Constructor Chaining kalıtım üzerinden sub (child) class tipinde obje new'lenirken base class'ın da ilgili
            // constructor'ının çalıştırılması için kullanılır. Önce base daha sonra sub class'ın constructor'ı çalışır.
            // Soyut (abstract) base class'lar üzerinden de Constructor Chaining yapılabilir ancak bu durumda
            // base class'ın constructor'ları public değil protected tanımlanmalıdır.

            // parametreli constructor chaining:
            Sub parametreliSub = new Sub(1.2, 'a', 3, true, "B");

            parametreliSub.SubMethod();
            parametreliSub.BaseMethod();

            // parametresiz (default) constructor chaining:
            Sub parametresizSub = new Sub();



            #region Dosya İşlemleri Demo
            DosyaIslemleriDemo dosyaIslemleriDemo = new DosyaIslemleriDemo();
            dosyaIslemleriDemo.Calistir();
            #endregion
        }
    }



    class Base
    {
        // alan
        //private int base1; // *1
        private int _base1; // *2

        // alan
        //protected bool base2; // *1
        protected bool _base2; // *2

        // özellik
        public string Base3 { get; set; }

        // parametreli constructor:
        public Base(int base1, bool base2, string base3) 
        {
            // this içinde bulunulan bu sınıfa (Base) ait alan, özellik veya methodlara ulaşmak için kullanılır.
            // Genelde gelen parametre adları ile alan adlarının aynı olması durumunda kullanılır.
            // *1
            //this.base1 = base1;
            //this.base2 = base2;
            //this.Base3 = base3; // base3 parametre adı ile Base3 özellik adları çakışmadığından burada this kullanmaya gerek yoktur
            //Console.WriteLine($"Base class constructor çalıştırıldı." +
            //    $"\nBase 1: {this.base1}" +
            //    $"\nBase 2: {this.base2}" +
            //    $"\nBase 3: {this.Base3}\n"); // base3 parametre adı ile Base3 özellik adları çakışmadığından burada this kullanmaya gerek yoktur

            // *2
            // Bu sınıfa (Base) ait alanlara ulaşmada sürekli this kullanmamak için private ve protected alanlar başında _ ile tanımlanır.
            _base1 = base1;
            _base2 = base2;
            Base3 = base3; 
            Console.WriteLine($"Base class constructor çalıştırıldı." +
                $"\nBase 1: {_base1}" +
                $"\nBase 2: {_base2}" +
                $"\nBase 3: {Base3}\n");
        }

        // parametresiz constructor:
        public Base()
        {
            Console.WriteLine($"Base class constructor çalıştırıldı.\n");
        }

        // davranış
        public void BaseMethod()
        {
            // *1
            //Console.WriteLine($"Base class BaseMethod çalıştırıldı." +
            //    $"\nBase 1: {this.base1}" +
            //    $"\nBase 2: {this.base2}" +
            //    $"\nBase 3: {this.Base3}\n");

            // *2
            Console.WriteLine($"Base class BaseMethod çalıştırıldı." +
                $"\nBase 1: {_base1}" +
                $"\nBase 2: {_base2}" +
                $"\nBase 3: {Base3}\n");
        }
    }



    class Sub : Base
    {
        // alan
        //private double sub1; // *1
        private double _sub1; // *2

        // özellik
        public char Sub2 { get; set; }

        // parametreli constructor:
        // Sub tipinde bir obje new'lenirken gönderilen sub1 ve sub2 parametreleri Sub sınıfına ait alan ve özelliklere atanabilir,
        // base1, base2 ve base3 parametreleri ise ": base(base1, base2, base3)" üzerinden Base sınıfının parametreli constructor'ına gönderilerek
        // Base sınıfının alan ve özelliklerinin atanması sağlanır.
        public Sub(double sub1, char sub2, int base1, bool base2, string base3) : base(base1, base2, base3)
        {
            // *1
            //this.sub1 = sub1;
            //this.Sub2 = sub2; // sub2 parametre adı ile Sub2 özellik adları çakışmadığından burada this kullanmaya gerek yoktur
            //Console.WriteLine($"Sub class constructor çalıştırıldı." +
            //    $"\nSub 1: {this.sub1}" +
            //    $"\nSub 2: {this.Sub2}\n"); // sub2 parametre adı ile Sub2 özellik adları çakışmadığından burada this kullanmaya gerek yoktur

            // *2
            _sub1 = sub1;
            Sub2 = sub2;
            Console.WriteLine($"Sub class constructor çalıştırıldı." +
                $"\nSub 1: {_sub1}" +
                $"\nSub 2: {Sub2}\n");
        }

        // parametresiz constructor:
        // Sub tipinde bir obje parametresiz (default) constructor üzerinden new'lenirken Base class'ının parametresiz (default) constructor'ı çağrılabilir.
        public Sub() : base()
        {
            Console.WriteLine($"Sub class constructor çalıştırıldı.\n");
        }

        // davranış
        public void SubMethod()
        {
            // base miras alınan sınıfa (Base) ait alan, özellik veya methodlara ulaşmak için kullanılır.
            // *1
            //Console.WriteLine($"Sub class SubMethod çalıştırıldı." +
            //    $"\nSub 1: {this.sub1}" +
            //    $"\nSub 2: {this.Sub2}");
            //Console.WriteLine($"Base 2: {base.base2}\nBase 3: {base.Base3}\n"); // ihtiyaç durumunda base class'taki base2 alanı protected ve
                                                                                // Base3 özelliği public olduğundan bunlara sub class'ta erişilebilir

            // *2
            Console.WriteLine($"Sub class SubMethod çalıştırıldı." +
                $"\nSub 1: {_sub1}" +
                $"\nSub 2: {Sub2}");
            Console.WriteLine($"Base 2: {_base2}\nBase 3: {Base3}\n");
        }
    }
}