我目前正在开发一个项目,其中有很多类继承自其他类继承的其他类,依此类推。它可能比它应该更复杂,但我是一个抽象的傻瓜。
无论如何,有时我需要将getter / setter从公共更改为私有。我认为这不是一个需要,而是希望切断子类中预设的内容,但仍需要在父类中公开访问。
所以一个例子是:
Class Base {
public function set label( value:String ):void{};
}
Class A extends Base {}
Class B extends A {
public function B() {
super();
this.label = "stuff";
}
override public function set label( value:String ):void {
//this setter should not be publicly available since the label should not be possible to change in this class
}
}
目前,在这些情况下,我正在做两件事之一:
我做了一些搜索,一切似乎都指向这是不可能的,但我从未发现它明确表示这是不可能的。那么是否可以在继承的属性/函数上更改访问修饰符?
答案 0 :(得分:7)
这是不可能的,它确实不应该,因为它会导致令人困惑和不可预测的类层次结构。对于初学者来说,如果你做了类似的事情,你就会打破Liskov Substitution Principle:超类应该始终可以被派生类替换。如果另一个程序员意外地交换类型,更改API将明显地防止 - 并因此可能导致运行时错误和/或无法解释的故障。
如果您正在建模的类具有不同的行为,这会使您“隐藏”其他公共API方法,那么您可能不应该使用继承 - 或者可能以不同的方式。根据您的描述,我猜想在层次结构的更大部分中,您应该使用合成而不是继承。
答案 1 :(得分:1)
在 Marty Wallace 的评论中,这是不可能的。但这并不常见。
然而,在您使用的替代方案中,属性所有者是基类&因此,它应该始终知道派生类使用它自己的属性做的任何事情。
而不是你的黑客,我会更喜欢这样的东西:
public class Base {
protected var _isLabelUsable:Boolean = true;
public function set label( value:String ):void {
if (!_isLabelUsable)
throw new Error("Access of undefined property label.");
// Set Label here
}
}
public class A extends Base {
}
public class B extends A {
public function B() {
super();
_isLabelUsable = false;
}
}
答案 2 :(得分:0)
这些都是有效点,但...... 有些情况下它们都是无效的。 给定来自外部源的基类。比方说,mx:Panel。 它有属性'titleIcon:Class' 派生类继承所有属性和函数。但是使用它的人永远不会直接设置titleIcon,因为派生类的部分功能取决于已知的图标名称的可用性。它提供了一个属性iconName:String。设置它还将设置titleIcon。 现在如何防止人们直接设置图标? UI提供AS3和MXML的旧属性,编译器(当然)不会抱怨。
如果titleIcon是一个setter / getter对(在这种情况下,它是),而不是final,那么派生类可以覆盖setter并抛出错误,而iconName setter将图标类分配给super.titleIcon 。 但是,这很笨拙,不适用于最终的功能或变量。
如果有办法至少告诉用户界面不再提供该属性或显示警告......