好吧,我这个菜鸟确实是常常在用面向过程的思想在考虑问题,在编写程序。现在我已经摈弃了自己对java语言个人的偏见,而是用平等公平的态度看待java和C++。他们各有千秋,各有乾坤的。
好吧,入正题。假设有这么个基类:
public class Base {
public Base(int arg){
this.arg = arg;
}
void show(){
switch(arg){
case 1:
System.out.println("this is 1");
break;
case 2:
System.out.println("this is 2");
break;
case 3:
System.out.println("this is 3");
break;
}
}
private int arg;
}
一个很常见的基类,基类中的函数show就是根据arg的值输出不同的信息。我相信很多很多的人应该是写过这个程序的。我也是,但是,我没有将这个程序和面向对象语言的多态结合起来。其实,细细的一想,这就是多态,就是根据arg值得不同而产生不同的响应。
基于这个考虑,下面将采用多态的思想将show的switch语句进行重构:
1.基类
public abstract class _Base {
public _Base(int arg){
this._arg = arg;
}
protected int _arg;
public abstract void show();
}
2.派生类1
public class _ExtBase1 extends _Base{
public _ExtBase1(int arg) {
super(arg);
}
@Override
public void show() {
System.out.println("this is 1");
}
}
3.派生类2
public class _ExtBase2 extends _Base{
public _ExtBase2(int arg) {
super(arg);
}
@Override
public void show() {
System.out.println("this is 2");
}
}
4.派生类3
public class _ExtBase3 extends _Base{
public _ExtBase3(int arg) {
super(arg);
}
@Override
public void show() {
System.out.println("this is 3");
}
}
可以看到switch的三种case转化为了相应的子类了。采用_Base类的多态性,完全可以做到根据arg值得不同,而输出不同的信息的。下面是测试:
public class _BaseTest {
_Base base1 = new _ExtBase1(1);
_Base base2 = new _ExtBase2(2);
_Base base3 = new _ExtBase3(3);
@Before
public void before(){
}
@After
public void after(){
}
@Test
public void test() {
base1.show();
base2.show();
base3.show();
}
}
上述完全是一个面向过程到面向对象的转变:将每个case分支都作为一个子对象,然后用java语言的多态性去动态绑定。这样做确实是带来了性能上的损失,但是在当今的CPU计算能力而言,这是可以忽略的,而它带来的好处却很有用:
- 分支的增减只要继续派生即可;
- 子类代表了一个case,比必须用type去硬编码的case语句更加具有可读性;
- 代码的可读性增强,使得分支的维护性增加;
- 面向对象的思想更加符合人看世界的方式;
- 避免了漏写break语句造成的隐蔽错误;