1

我目前正在做一个项目,我有大量的类继承自其他类,这些类继承自其他类等等。它可能比它应该的更复杂,但我是抽象的傻瓜。

无论如何,有时我需要将 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
    }
}

目前,在这些情况下,我正在做两件事之一:

  1. 覆盖 setter 以不执行任何操作或将其设置为默认值,以便它仍然可以更新/渲染/任何内容
  2. 抛出一个错误,说它在该类中不可用

我做了一些搜索,一切似乎都表明这是不可能的,但我从未发现它明确指出这是不可能的。那么是否可以更改继承属性/函数的访问修饰符?

4

3 回答 3

7

这是不可能的,而且确实不应该,因为它会导致混乱和不可预测的类层次结构。对于初学者来说,如果你做了这样的事情,你就会打破Liskov 替换原则:超类应该始终可以被它的派生类替换。更改 API 显然可以防止这种情况发生 - 如果另一个程序员不小心交换了类型,则可能会导致运行时错误和/或莫名其妙的故障。

如果您正在建模的类具有不同的行为,从而使您“隐藏”其他公共 API 方法,您可能不应该为此使用继承 - 或者可能以不同的方式使用。根据您的描述,我猜想在您的层次结构的大部分中,无论如何您可能应该使用组合而不是继承。

于 2013-02-18T03:44:53.793 回答
1

由于马蒂华莱士的评论中的原因,这是不可能的。但这并不是一件不寻常的事情。

但是,在您使用的替代方案中,属性所有者是基类,因此它应该始终知道派生类对其自身属性所做的任何事情。

因此,我更喜欢这样的东西,而不是你的 hack:

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; 
        }       
    }
于 2013-02-18T03:46:52.687 回答
0

这些都是有效的点,但是......在某些情况下它们都是无效的。给定一个来自外部源的基类。比如,mx:Panel。它具有属性 'titleIcon:Class' 派生类继承了所有属性和功能。但是使用它的人永远不能直接设置 titleIcon,因为派生类的部分功能取决于已知图标名称的可用性。它提供了一个属性 iconName:String。设置它也会设置titleIcon。现在如何防止人们仍然直接设置图标?UI 为 AS3 和 MXML 提供旧属性,编译器(当然)不会抱怨。

如果 titleIcon 是 setter/getter 对(在本例中是),而不是 final,则派生类可以覆盖 setter 并引发错误,而 iconName setter 会将图标类分配给 super.titleIcon。但是,这很笨拙,不适用于最终函数或变量。

如果有办法至少告诉 UI 不再提供该属性或显示警告...

于 2017-07-05T17:28:17.587 回答