问题

何时使用 Protected 继承?

回答
使用保护继承,实际上是在构建一个“isa”关系,但又希望在子类之间共享一些实现细节,同时又能限制这些细节的直接暴露给外部世界。这就像在家族里,某些传承下来的技艺或财产,家族成员(子类)可以继承和使用,甚至在家族内部(子类之间)相互借鉴和合作,但你不会随意地把它展示给家族以外的陌生人(普通对象)。

设想一下,你在设计一个游戏角色系统。你有这样一个基础类 `Character`,里面可能封装了角色的一些基本属性,比如生命值 `health`,以及一个重要的内部逻辑,比如 `takeDamage` 方法,这个方法会处理生命值的扣减,并且可能会触发一些内部状态的变化,比如角色是否死亡。

现在,你想创建不同类型的角色,比如 `Warrior`(战士)和 `Mage`(法师)。它们都是 `Character`,都应该有生命值和承受伤害的能力。

如果 `health` 和 `takeDamage` 被声明为 `public`,那么任何地方的代码都可以直接访问和修改 `health`,也可以随意调用 `takeDamage`。这可能导致一些意想不到的副作用。比如,一个外部脚本错误地给一个 `Mage` 角色造成了巨额伤害,导致游戏逻辑混乱。

如果它们被声明为 `private`,那么子类 `Warrior` 和 `Mage` 就完全无法访问和使用 `takeDamage` 方法来处理自身受到伤害的逻辑了。你只能在 `Warrior` 和 `Mage` 类中各自重新实现一遍 `takeDamage`,这显然是重复劳动,并且失去了 `Character` 类中封装的通用逻辑。

这时,`protected` 就派上了用场。

我们将 `health` 和 `takeDamage` 声明为 `protected`。这意味着:

1. 子类可以直接访问和使用: `Warrior` 和 `Mage` 类可以无障碍地访问 `health` 属性,并且可以调用 `takeDamage` 方法来处理自己受到的伤害。这保证了它们继承了 `Character` 的核心能力,并且能够正常运作。

2. “家族内部”的共享: 更有意思的是,如果未来你又创建了一个 `Paladin`(圣骑士)类,它也是 `Character` 的子类,并且 `Paladin` 的某些技能可能需要直接操作另一个 `Character`(可能是敌对角色)的 `health`,或者调用另一个 `Character` 的 `takeDamage` 方法(比如圣骑士的某些减益技能)。在这种情况下,如果 `health` 和 `takeDamage` 是 `protected`,那么 `Paladin` 就可以做到这一点。它像是家族成员之间可以互相传递信息或协助。

3. 外部世界的隔离: 然而,如果你尝试在 `main` 函数或者其他与 `Character`、`Warrior`、`Mage`、`Paladin` 都无关的类中,直接创建 `Character` 对象,并试图访问 `character.health` 或者调用 `character.takeDamage()`,编译器会告诉你这是不允许的,因为 `protected` 成员只能被类本身以及其派生类访问。这就实现了对核心逻辑的保护,避免了外部不当的干扰。

所以,当你发现一个类封装了一些核心的、且期望被其子类共享和利用的实现细节,同时又不希望这些细节被不相关的外部代码随意触碰和修改时,保护继承(即通过 `protected` 关键字来暴露这些成员)就是一种非常合适的选择。它是在“isa”继承关系下,对实现细节进行了一层精妙的访问控制,既保留了继承的便利性,又维护了代码的安全性和封装性。

网友意见

user avatar

protected应该是用在子类实现父类的方法或者方法中使用,如果用public的,别的类还是可以使用到这个父类的方法或者成员,当使用protected的时候,只有子类能访问了,其他的类就访问不了了。

类似的话题

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有