返回介绍

4.8 总结

发布于 2025-02-24 22:44:38 字数 1230 浏览 0 评论 0 收藏 0

超类的对象和子类是相似的,但是在表现形式上并不相同。子类正常情况下会有更详尽的陈述更多的方法 - 他们被超类对象的版本专用指定。

我们使用超类对象的表示的拷贝来作为子类对象表示的开始,即,子类对象通过把它的组成部分增加到超类对象的末尾被表示。

一个子类继承了超类的方法:因为一个子类对象的起始部分看起来像超类对象,我们可以上抛并且看到一个指向子类对象的指针作为一个指向我们能够传递超类方法的超类对象。为了避免显性转换,我们使用 void* 作为通用指针来声明所有方法的参数。

继承可以被看成一个多态机制的根本形式:一个超类方法接受不同类型,它自己的类和所有子类命名的对象。然而因为对象都佯装成超类对象,方法仅仅在每个对象的超类部分起作用,并且它将,因此从不同的类对于对象不会起不同的作用。

动态链接方法能够从一个超类继承或在子类中重写 - 对于子类通过无论何种函数的指针被放进类型描述符来决定。因此,对于一个对象如果动态链接方法被调用,我们总能够访问属于对象真正的类的方法即使指针上抛到一些超类上。如果动态链接方法被继承,它只能在子类对象的超类部分起作用,因为它的确不知道子类的存在。如果一个方法被重写,子类的版本能够访问整个对象,他甚至可以通过显性的超类的类型描述符的使用来调用它关联的超类的所有方法。

特别注意,对于超类的表示,构造器首先回调超类的构造器直到最终的祖先以便于每个子类的构造器仅仅处理它自己的对类的扩展。每个超类析构器应该先删除它的子类的资源然后调用超类的析构器等等直到最终的祖先。构造器的调用顺序是从祖先到最终的子类,析构器的发生则正好是相反的顺序。

我们的策略还是有点小毛病的:在通常情况下我们不应该从一个构造器中调用动态链接方法,因为对象也许并没有完全被初始化好。在构造器被调用之前 new() 把最终的类型描述符插入到一个对象中,作为一个构造器在相同的类中是没有必要的访问方法的。安全的技术是在相同的类中对于构造器通过内部的名字来调用方法,也就是说,对于点,我们调用 Points_draw() 而不是 draw()

为了鼓励信息隐藏,我们使用了三个文件对类的实现。接口文件包含了抽象的数据类型描述,表示文件包含了对象的结构,实现文件包含了方法和初始化类型描述的代码。一个接口文件包含了超类接口文件并且被实现和任何应用所包含。一个表示文件包含了超类的表示文件并且仅仅被实现所包含。

超类的部分不应该直接的在子类中被引用。相反,对于每个部分我们能够既提供静态链接访问和尽可能的修改方法,也能对于超类的表示文件增加适当的宏。函数符号使得使用文本编辑器或调试器去跟踪可能的信息泄露或不变量的破坏更简单。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文