物件導向課程心得Part2

物件導向心得Part2
今天先整理一小部分,明天繼續整理會有Part3
廢話就不多說了直接來看

存取修飾詞
父類別=>方法加上 virtual ,子類別就可以 override

而外補充
衍生類別 override後,該衍生類別別又被別人繼承
所以原本override的方法還可以繼續override
並不是只有 virtual  => override
    也有可能 virtual======> override==========> override
                  (classA)     (ClassB:ClassA)          (ClassC:ClassB)

        
另外講到override,一定也要跟各位講一下method hiding (方法遮蔽) 
{   
    class Program
    {
        static void Main(string[] args)
        {
            Class1 C1 = new Class2();
            C1.Test();  //答案會是 Class1
            
            Class2 C2 = new Class2();
            C2.Test(); //答案會是 Class2
            Console.Read();
            
            //為什麼一樣都是New Class2,結果卻不同?
            //仔細看一下我的Class2,為什麼繼承我卻沒有override test方法
            //這邊使用了遮蔽,一旦使用遮蔽方法
            //就會讓 = 號的左邊的型別來決定到底應該呼叫誰            
        }
    }

    class Class1
    {
        public virtual void Test()
        {
            Console.WriteLine("Class1");
        }
    }

    class Class2 : Class1
    {
        public new void Test()
        {
            Console.WriteLine("Class2");
        }
    }
}

那麼遮蔽如果非必要千萬不要亂用,因為會搞死人
而且使用遮蔽一定要寫註解
否則接手你Code的人會死得很慘
如果你一天到晚繼承來繼承去的 virtual  override 遮蔽
混搭使用,那看你Code會很痛苦
那什麼情況需要用到遮蔽??
Bill老師舉了個例子
當你有用Third party
而這個Third party有個方法寫錯,對方也不能馬上改給你,這時候你可以使用遮蔽
繼承之後,將同名的方法使用遮蔽
在呼叫時讓等號左邊的型別來決定要該呼叫誰,這個時候至少你改完是可以馬上Work的
但這不是長解
最終還是要提供Third party的方法改對,才是真正問題


委派 delegate

委派是一個型別,可以宣告在命名空間底下
宣告委派型別,這邊你可以把委派當成Class,而初始時需要丟同型別的方法
最後Invoke時丟指定的參數型別
//[做單一委派]
namespace ConsoleApplication1
{
    public delegate void SomeAction(string message);

    class Program
    {
        static void Main(string[] args)
        {
            SomeAction d = new SomeAction(Test);
            d.Invoke("Mickey");
            Console.Read();
        }
        public static void Test(string message)
        {
            Console.Write(message);
        }
    }
}
//[多重委派]
//使用 +=
//你可以把委派視為一個工作清單,可以一直加入相同回傳型別的方法
//一旦第一個方法做完,就會接續做第二個方法
//直到把委派給delegate的方法都做完,當然要移除事件可以用 -=
namespace ConsoleApplication1
{
    public delegate void SomeAction(string message);

    class Program
    {
        static void Main(string[] args)
        {
            SomeAction d = Test;
            d += Test2;
            d.Invoke("Mickey");
            Console.Read();

        }
        public static void Test(string message)
        {
            Console.WriteLine(message +"ABC");
        }

        public static void Test2(string message)
        {
            Console.WriteLine(message + "123");
        }
    }
}
//[利用委派傳遞方法]
//由內部啟用,由外部來決定要做什麼事情
namespace ConsoleApplication1
{
    public delegate void SomeAction(string message);
    class Class1
    {
        public void DoAction(SomeAction action, string message)
        {
            action.Invoke(message);
        }

    }
}

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Class1 obj = new Class1();
            SomeAction d = Show;
            d += Show2;
            obj.DoAction(d, "Test");
            Console.Read();

        }
        public static void Show(string text)
        {
            Console.WriteLine("Mickey" + text);
        }

        public static void Show2(string text)
        {
            Console.WriteLine("從外面決定要做什麼事情" + text);
        }
    }
}

以上先介紹到委派,讓各位對委派有些認識,後續會講自訂委派
事件與委派匿名函示的差異
物件導向課程心得Part3