韧
韧峰
Unregistered / Unconfirmed
GUEST, unregistred user!
最近看李维《面向对象开发实践之路Delphi版》,有些收获,但由于基础较差,有些问题李维老师说得过于简单,我实在看不明白。这里列出两个,特请各位大拿指教:
1)李老师在第4章中设计个几个类来封装读取和处理XML文件,其中有三个是TPFMManager、TPFMConfigManager、TPFMScheduleManager,TPFMManager作为另外两个类的父类存在。但是在TPFMManager类中,同时定义了ScheduleCount、ConfigCount、ScheduleItem、ConfigItem等属性,这些TPFMConfigManager和TPFMScheduleManager中也要出现,但按照实际处理的情况,ScheduleCount、ScheduleItem是与TPFMConfigManager不相关的,同样ConfigCount、ConfigItem是与TPFMScheduleManager不相关的,但现在它们均要出现在不相关的类中,是否与面向对象程序设计思想相符?
2)关于接口和虚函数来实现方法的多态性问题。第5章中讲到处理器问题,利用多态来简化客户端的调用接口,书中提到两种实现方式。
第一种是在基类中设置虚函数,然后在子类中覆盖,这样在客户端就可以只采用基类的方法就实现了实际操作方法的传递。即在基类中:
THandler=Class
...
Public
...
Perform(...);Virtual;
...
End;
在子类中
TChildHandler=Class(THandler)
...
Public
...
Perform(...);Override;
...
End;
这样在客户端就可以采用
aHandler.Perform(...)
实现所有子类中的处理情况。
第二种是采用接口技术,即先声明一个接口:
IHandler=IInterface
Perform(...);
End;
然后用THandler继承自IHandler并实现Perform(...),这时依然将Perform(...)声明为虚方法以便其子类覆盖:
THandler=Class(TObjectInterface,IHandler)
...
Public
...
Perform(...);Virtual;
...
End;
然后在子类中
TChildHandler=Class(THandler)
...
Public
...
Perform(...);Override;
...
End;
这样在客户端就可以采用
aHandler.Perform(...)
实现所有子类中的处理情况。
我不明白的是:既然基类中依然使用了虚函数,且子类的继承自基类,接口是在基类中实现的,那么采用接口的好处到底在哪里?书中对此的说明非常简单,
“由于目前在面向对象工程中,接口已经比继承加上虚方法的方式更为受到欢迎,因此使用接口似乎是比较好的选择”……
“这样一来,THandler类架构可以同时享有‘实现继承’和‘声明继承’的好处”……“使用接口的好处很多,它可以避免‘脆弱的继承问题’”(什么是“脆弱的继承问题”?这个例子中是否存在“脆弱的继承问题”?)……
“现在我们不必进入实际的实现阶段就可以在类图的备注中想象采用接口的好处”
但是具体的好处我没有发现,我觉得此后所有的实现过程与采用虚函数法没有两样。
我是直到最近才对接口有所了解,所以有很多问题看不明白,敬请各位大虾指点迷津!谢谢。
1)李老师在第4章中设计个几个类来封装读取和处理XML文件,其中有三个是TPFMManager、TPFMConfigManager、TPFMScheduleManager,TPFMManager作为另外两个类的父类存在。但是在TPFMManager类中,同时定义了ScheduleCount、ConfigCount、ScheduleItem、ConfigItem等属性,这些TPFMConfigManager和TPFMScheduleManager中也要出现,但按照实际处理的情况,ScheduleCount、ScheduleItem是与TPFMConfigManager不相关的,同样ConfigCount、ConfigItem是与TPFMScheduleManager不相关的,但现在它们均要出现在不相关的类中,是否与面向对象程序设计思想相符?
2)关于接口和虚函数来实现方法的多态性问题。第5章中讲到处理器问题,利用多态来简化客户端的调用接口,书中提到两种实现方式。
第一种是在基类中设置虚函数,然后在子类中覆盖,这样在客户端就可以只采用基类的方法就实现了实际操作方法的传递。即在基类中:
THandler=Class
...
Public
...
Perform(...);Virtual;
...
End;
在子类中
TChildHandler=Class(THandler)
...
Public
...
Perform(...);Override;
...
End;
这样在客户端就可以采用
aHandler.Perform(...)
实现所有子类中的处理情况。
第二种是采用接口技术,即先声明一个接口:
IHandler=IInterface
Perform(...);
End;
然后用THandler继承自IHandler并实现Perform(...),这时依然将Perform(...)声明为虚方法以便其子类覆盖:
THandler=Class(TObjectInterface,IHandler)
...
Public
...
Perform(...);Virtual;
...
End;
然后在子类中
TChildHandler=Class(THandler)
...
Public
...
Perform(...);Override;
...
End;
这样在客户端就可以采用
aHandler.Perform(...)
实现所有子类中的处理情况。
我不明白的是:既然基类中依然使用了虚函数,且子类的继承自基类,接口是在基类中实现的,那么采用接口的好处到底在哪里?书中对此的说明非常简单,
“由于目前在面向对象工程中,接口已经比继承加上虚方法的方式更为受到欢迎,因此使用接口似乎是比较好的选择”……
“这样一来,THandler类架构可以同时享有‘实现继承’和‘声明继承’的好处”……“使用接口的好处很多,它可以避免‘脆弱的继承问题’”(什么是“脆弱的继承问题”?这个例子中是否存在“脆弱的继承问题”?)……
“现在我们不必进入实际的实现阶段就可以在类图的备注中想象采用接口的好处”
但是具体的好处我没有发现,我觉得此后所有的实现过程与采用虚函数法没有两样。
我是直到最近才对接口有所了解,所以有很多问题看不明白,敬请各位大虾指点迷津!谢谢。