最近我遇到了一种需要为我的Android应用程序创建自定义VideoView的情况。我需要访问MediaPlayer对象并添加一些监听器。
不幸的是(对我而言),VideoView类的所有成员都是私有的,所以即使扩展该类也无法帮助我获取对其MediaPlayer对象(或其他任何东西)的访问权限,我不得不完全复制它我的修改课程。
嗯,虽然这听起来像是在为“艰苦的工作”而抱怨,但是在这种情况下扩展课程比较简单(因为所有的资源都可以使用......)但是这让我真的怀疑这个信息隐藏方法。 这是一种比将主要组件留给修改/访问(受保护,而非公开)更好的做法吗?我的意思是,我明白如果我扩展VideoView类,有一天他们可能会改变一些东西VideoView类和我可能有麻烦,但如果他们改变了类,我自己的(重复)版本将与VideoView类有更大的区别,而我的目标不是创建我自己的视频视图,而是扩展可用的VideoView。
答案 0 :(得分:4)
在这种情况下,我通常更喜欢composition而不是继承。
修改强>
当子类和超类都在同一个程序员的控制下时,使用继承是安全的,但实现继承可能导致脆弱的API。正如你所提到的,如果超类实现发生了变化,那么子类可能会破坏或者更糟糕 - 会无声地执行非预期的事情。
另一种方法是使私有字段引用称为组合的现有类(VideoView)的实例,并且新类中的每个实例方法都在现有类的包含实例上调用相应的方法并返回结果。这种包装方法也可以称为“装饰器”模式
答案 1 :(得分:4)
当程序员私有化时,他们会打赌没有其他人需要使用或覆盖它,因此信息隐藏会带来回报。有时赌注不会下降。他们是休息。
答案 2 :(得分:1)
我无法代表特定VideoView开发人员的推理,但如果您正在开发API,并确定某些数据所代表的状态需要始终按顺序遵循某些规则为了保持对象的完整性和预期目的,将成员变量设为私有是有意义的,这样你就可以控制它们的修改。
它确实限制了其他开发者可以做的事情,但我认为这是重点。有些事情,如果要改变它们,您会希望它在具有API治理的组中进行讨论和验证。在这种情况下,私有化是有意义的,这样对它的修改就不会在集团的监督之外失控。
我不知道有一个静态的经验法则决定什么时候需要属于这个类别,但在某些情况下我肯定能看到它的使用。
答案 3 :(得分:1)
当我阅读所有启发性答案(和评论)并评论那些我意识到我期望某些与某些课程无关的东西时。在VideoView示例中,此类已经是继承链中的最后一个。它不应该被扩展,因为它是一个逻辑单元,非常具体而且非常紧凑,用于非常特定的目的。我需要从视图和MediaPlayer获得特殊状态,这是QC目的的需要,在提供一个封闭单元的产品时(尽管源是开放的),实际上不应该考虑这些需求。这是一个合理的论据,我觉得它很令人满意。有时候不应该实现每个 OOP概念。谢谢大家的回复。