th_*_*_gs 4 language-agnostic oop overriding subclass
虽然我在ObjC中编码,但这个问题是故意与语言无关的 - 它应该适用于大多数OO语言
假设我有一个"Collection"类,我想创建一个继承自"Collection"的"FilteredCollection".过滤器将在对象创建时设置,从中开始,类将表现为"集合",过滤器应用于其内容.
我做事明显的方式和子类Collection.我覆盖了所有的访问器,并且认为我已经做了一个非常干净的工作 - 我的FilteredCollection看起来应该像一个Collection,但是对象是'in'它对应于我的过滤器被过滤掉给用户.我想我可以愉快地创建FilteredCollections并将它们作为集合传递给我的程序.
但我来测试 - 哦不 - 它不起作用.深入调试器,我发现这是因为某些方法的Collection实现调用了重写的FilteredCollection方法(例如,在迭代其对象时,Collection依赖于"count"方法,但现在它正在获取过滤后的计数,因为我重写了count方法以给出正确的外部行为).
这有什么不对?为什么感觉某些重要原则被侵犯,尽管它也感觉OO'应该'以这种方式工作?这个问题的一般解决方案是什么?有吗?
顺便说一下,我知道这个问题的一个好的"解决方案"就是在将对象放入集合之前对其进行过滤,而不必更改Collection,但是我想问一个更普遍的问题比那 - 这只是一个例子.更普遍的问题是不透明超类中的方法依赖于可能由子类更改的其他方法的行为,以及在您希望子类化对象以更改此类行为的情况下该怎么做.
Tho*_*mas 11
Collection你继承的那个有一定的合同.类的用户(包括类本身,因为它可以调用自己的方法)假定子类服从合同.如果你很幸运,合同在其文件中明确无误地指明......
例如,合同可以说:"如果我添加一个元素x,然后迭代集合,我应该x回来".您的FilteredCollection实施似乎违反了该合同.
这里还有另一个问题:Collection应该是一个接口,而不是一个具体的实现.实现(例如TreeSet)应该实现该接口,当然也遵守其合同.
在这种情况下,我认为正确的设计不是继承Collection,而是FilteredCollection围绕它创建一个"包装器".可能FilteredCollection不应该实现Collection接口,因为它不遵守通常的集合合同.