【问题标题】:Java class inheritance and blocking superclass methodsJava 类继承和阻塞超类方法
【发布时间】:2013-06-20 22:48:28
【问题描述】:

我目前正在制作一个简单的插件程序。我的问题是我不想让插件访问所有基本插件字段/方法。例如:

public abstract class BasePlugin {
    private int x; //Mysterious x
    public abstract void update(); //update func that may need x, but can't change it
    protected final int getX() {return x;} //x accessor
}

除非您意识到无法设置 x,否则这将起作用。

我能做什么?我想让子类(插件)无法更改 x,但让它读取值。在创建时值应该至少可以访问一次(这就足够了)。

编辑:构造函数在大多数情况下都有效,但如果我有例如:

public abstract class BasePlugin {
    private List<int> x; //Mysterious x
    public abstract void update(); //update func that may need x, but can't change it
    protected final List<int> getX() {return x;} //x accessor
    public BasePlugin(List<int> y) {x = y;}
}

public class Plugin {
    public Plugin(List<int> y)
    {
        super(y);
        y.remove(0); //Will it work?
    }
}

【问题讨论】:

  • 有什么问题?那行得通
  • 您希望它在施工时设置吗?如果是这样,这很容易解决。
  • 我无法以任何方式设置 X。或者我只是不知道怎么做。
  • @MichaelMyers 将其设置在构造中就足够了,正如我所说的(创建时一次)。

标签: java class inheritance superclass


【解决方案1】:

抽象类允许有构造函数,所以你可以为BasePlugin创建一个无参数的构造函数:

public abstract class BasePlugin {
    private int x; //Mysterious x
    public BasePlugin() {
        x = 42;
    }
    public abstract void update(); //update func that may need x, but can't change it
    protected final int getX() {return x;} //x accessor
}

现在当一个插件被创建时,x 被设置为 42。你甚至不需要对插件进行任何代码更改就可以让它们使用这个构造函数。


要回答已编辑的问题:如果 x 是一个 List 并且您不希望插件修改它,您的构造函数应该复制它并将其包装在 unmodifiable list 中。否则,任何插件都可以调用getX().add(myObject)

public BasePlugin(List<int> y) {
    List<int> temp = new ArrayList<int>();
    Collections.copy(temp, y); // shallow copy of the list
    this.x = Collections.unmodifiableList(temp);
}

现在如果插件的构造函数是

public Plugin(List<int> y)
{
    super(y);
    y.remove(0); //Will it work?
}

它不会影响 BasePlugin 的列表。

【讨论】:

  • 好的。如果参数是更复杂的对象,比如 List 怎么办?然后用户仍然可以在 super(x) 之后对其进行编辑。
  • @kittyPL:列表是可变的,所以如果您有访问器并且不希望插件修改列表,则无论如何您都必须将其包装在 unmodifiable list 中。
  • 正是我需要的!谢谢!接受您的答案,因为它很完美,仍然支持其他答案,因为他们也解决了第一部分。
  • @kittyPL 请注意,即使在 basePlugin 类中也不能修改列表,如果您尝试添加或删除,则会抛出 UnsopportedOperationException
【解决方案2】:

您可以添加一个构造函数来让子类初始化您的属性:

public abstract class BasePlugin {
    private int x; //Mysterious x

    public BasePlugin(int x) {
        this.x = x;
    }

    public abstract void update(); //update func that may need x, but can't change it
    protected final int getX() {return x;} //x accessor
}

【讨论】:

    【解决方案3】:

    您可以使用构造函数注入。

    public abstract class BasePlugin{
    
      private int x;
    
      public BasePlugin(int x){
       this.x=x;
      }
    
      public abstract void update(); //update func that may need x, but can't change it
      protected final int getX() {return x;} //x accessor
    
    }
    

    在你的孩子身上

    public class Plugin extends BasePlugin{
    
    
      public Plugin(int x){
        super(x);
      }
    
    }
    

    【讨论】:

    • 你必须实现你的 deep clone() 方法..或转换 unmodifiableList
    猜你喜欢
    • 2011-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-06-24
    • 1970-01-01
    • 2015-03-14
    • 2021-05-04
    • 2011-05-26
    相关资源
    最近更新 更多