由一个UnitTest联想到的关于abstract class的一些知识点

突然想起来写点自己对abstract class的一点感悟,是因为早上项目中要完成一个抽象类的UnitTest。大家知道抽象类是不能实例化的,那怎样进行测试呢?其实很简单,这个是一个Mock的思想,我们再建的测试类中建一个内部类,这个内部类继承要测的abstract class,这样就解决了抽象类不能实例化的问题。

在建这个内部类的时候,我们需要面对的一个问题就是抽象类的构造函数。如果你装了Resharper,它会很智能的帮你生成构造函数,代码如下:

1     public abstract class AbstractViewModel
2     {
3         //注意访问控制符是protected
4         protected AbstractPlaceholderParameterViewModel(string parameterName)
5         {
6             ......
7         }
8     }
    [TestClass]
    public class ViewModelTest
    {
        [TestMethod]
        public void TestMethod1()
        {
        }


        private class TestViewModel : AbstractViewModel
        {
            public TestViewModel(string parameterName)
                : base(parameterName)
            {
            }
        }
    }

这段代码有两点要注意:

1. 抽象类的构造函数为protected,这是Resharper里面推荐的,没必要开成public就不要开,abstract类根本不能实例化,开了永远也用不到

2. 继承类中构造函数必须继承抽象类中的构造函数,即使继承类中你重载了构造函数,但每个重载的构造函数都要继承抽象类的构造函数

        private class TestViewModel : AbstractViewModel
        {
            public TestViewModel(string parameterName)
                : base(parameterName)
            {
            }
            public TestViewModel(string parameterName, int value)
                : base(parameterName)
            {
            }
        }

面向对象语言为什么要这样设计呢?我们可以猜一猜:抽象类中是可以有实现的,其构造函数中可能做了初始化等工作,如果不继承它的构造函数,那初始化工作什么时候做呢?所以一定要继承抽象类的构造函数。

这里我们又想到抽象类可以包含实现的成员,未实现的成员隐含的是virtual属性,子类实现时必须用override关键字,否则编译时会出现warning,当然也可以使用new关键字屏蔽warning。

如果有特殊需求,要让子类和父抽象类都有某个方法,且父类中该方法已实现,在调用时要使用父类中的方法必须指明base.XXX(),否则将默认使用子类中的方法,这点大家可以去看MSDN。我总结出来的是:只要用到父类就是base.XXX(),不管它三七二十一肯定没错。

突然又想到一个问题:抽象类是否可以继承实体类?
抽象类当然可以继承实体类啦,why not?

http://www.cnblogs.com/ado-geek/archive/2012/05/17/2506666.html这篇文章里欧一段提到“抽象类当然可以继承实体类,但是有个条件,条件是实体类必须要有明确的构造函数”,我百思不得其解,求知情人赐教!!!

posted @ 2012-07-24 13:44  Evan Hua  阅读(1505)  评论(0编辑  收藏  举报