日期:2014-05-17  浏览次数:20987 次

请教,为什么C#中常常实例化子类,定义却是父类类型
如题,看很多源代码中都是实例化子类,然后定义的是它的父类类型,不明白这样做有什么好处呢。
我写了个大致例子
 public partial class Form1 : Form
    {
        private father _father;
        public Form1()
        {
            InitializeComponent();
            this._father = new sun();
        }
    }

    abstract class father
    {
        protected int a = 10;
        public void b()
        {
        }
        protected abstract void c();
    }
    class sun : father
    {
        public void d()
        {
        }
        protected override void c()
        {
        }
    }
_father 对象定义的即是父类的类型,但实际上是实例化了子类。很奇怪为什么常常这样做,这样做有什么好处呢,在什么情况下需要这么做呢?在这里向大家请教了

------解决方案--------------------
因为要面对抽象,依赖倒置

具体在往下讲不了,没有实战你不太可能理解为啥要如此。只能泛泛的告诉你“依赖倒置原则”是对象核心设计原则之一,其重要性大过博客园推烂的设计模式

这玩意需要在实战中真正搞过对象设计才有机会悟到,想明白。单纯看概念解释,只能感觉像看啥子卡耐基一样,似乎好像有点道理哦,但是又用不你自己身上。
------解决方案--------------------
会不会哪天有多出来 sonA,sonB,sonC ....,都是father的子类。
假如程序本来用的你的son类,现在要用sonA,或者sonB,或者sonC,是不是换一个你得改一下代码!
按照开放封闭原则,这不好。
如果程序里用的是father类,就不用改了。
程序本来是依赖son,或者sonA,或者sonB,或者sonC,
改用father后,程序只依赖父类father了,反而是你的子类是依赖父类father的,这样依赖就倒过来了。
------解决方案--------------------
楼主去看看依赖倒置原则,DIP,Dependency Inverse Principle

DIP的表述是:

1、高层模块不应该依赖于低层模块,二者都应该依赖于抽象。
 2、抽象不应该依赖于细节,细节应该依赖于抽象。

这里说的“依赖”是使用的意思,如果你调用了一个类的一个方法,就是依赖这个类,如果你直接调用这个类的方法,就是依赖细节,细节就是具体的类,但如果你调用的是它父类或者接口的方法,就是依赖抽象,

所以DIP说白了就是不要直接使用具体的派生类,不要直接用派生类的引用去调用派生类的方法,而是用它的父类的引用去调用派生类的方法,这样就是依赖于抽象,不依赖具体,

------解决方案--------------------
至于DIP有什么好处,楼主可以百度一下,一个说法是:

使用传统过程化程序设计所创建的依赖关系,策略依赖于细节,这是糟糕的,因为策略受到细节改变的影响。依赖倒置原则使细节和策略都依赖于抽象,抽象的稳定性决定了系统的稳定性。

其实简单的说,DIP的好处就是解除耦合,用了DIP之后,调用者就不知道被调用的代码是什么,因为调用者拿到的是父类的引用,它不知道具体指向哪个子类的实例,更不知道要调用的方法具体是什么,所以,被调用代码被偷偷换成另一个子类之后,调用者不需要做任何修改,

这就是解耦了,被调用代码修改之后,对调用者没有影响,