由一个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这篇文章里欧一段提到“抽象类当然可以继承实体类,但是有个条件,条件是实体类必须要有明确的构造函数”,我百思不得其解,求知情人赐教!!!