【问题标题】:Right way to access fields of an abstract class?访问抽象类的字段的正确方法?
【发布时间】:2016-11-28 22:31:21
【问题描述】:

我试图找出访问抽象类的私有字段的正确方法,然后在扩展抽象类的类中使用它。

下面是我的抽象类

流程类(抽象):

public abstract class Process implements Runnable {
  private final Properties props;
  private final String processName;

  public Process(String processName, Properties props) {
    this.processName = processName;
    this.props = props;
  }

  public abstract void shutdown();

  public Properties getProps() {
    return props;
  }

  public String getProcessName() {
    return processName;
  }
}

以下是我扩展上述抽象类并使用props Properties 对象的一种方式。

ProcessA 类:

public class ProcessA extends Process {
  private ProcessConsumer<byte[], byte[]> consumer;

  public ProcessA(String processName, Properties props) {
    super(processName, props);
  }

  @Override
  public void run() {
    // is this the right way?
    String processName = getProcessName();
    Properties props = getProps();
    consumer = new ProcessConsumer<>(props);

    // .. some other code with try catch block
    // using processName and consumer
  }

  @Override
  public void shutdown() {
    consumer.wakeup();
  }
}

下面是我扩展上述抽象类和使用属性对象的第二种方法。

ProcessB 类:

public class ProcessB extends Process {
  private final ProcessConsumer<byte[], byte[]> consumer;

  public ProcessB(String processName, Properties props) {
    super(processName, props);
    // is this the right way to use props object?
    this.consumer = new ProcessConsumer<>(props);
  }

  @Override
  public void run() {
    String processName = getProcessName();

    // .. some other code with try catch block
    // using processName and consumer
  }

  @Override
  public void shutdown() {
    consumer.wakeup();
  }
}

我想使用props 属性来制作ProcessConsumer 对象,但我很困惑使用props 对象的正确方法是什么?我应该在 run 方法中的抽象类上调用 getProps 方法然后使用它吗?或者只是把它放在构造函数中并在那里构建它?

有什么区别,什么是正确的方法?

【问题讨论】:

  • 私有的意义在于它不能在任何地方访问,只能从类本身的代码中访问,而不是在扩展类或其他类中。如果您确实希望能够访问它,则应该对其进行保护。不过,最好制作某种受保护的或公共的访问器。

标签: java oop abstract-class


【解决方案1】:

当您扩展抽象类时,子类会继承私有字段,但它们无法访问。因为私有字段只能在定义它们的类的范围内访问。

所以要初始化您使用super 的私有字段,以及访问它们。你可以把super看成this的妈妈:

public abstract class AbstractProcess{
    private final String processName;
    public AbstractProcess(String name){
        processName = name;
    }

    public String getName(){
        return processName;
    }

}




public class MyProcess extends AbstractProcess{

     public MyProcess(ProcessName name){
        //like you did is true
        super(name);

     }

    //now to access them
    public String getName(){
        return super.getName();
    }

}

您还可以使用 protected 来绕过整个私有+继承的事情。 protected 字段类似于私有 field,但可以被子类继承和访问。所以你可以直接调用this.someProtectedField(注意它不是一个“getter”函数)而不是super.getSomePrivateField()

我希望这是您要问的,并且我已经说得够清楚了。

【讨论】:

  • 这不是我要问的。我的问题是如何在我的子类中访问我的抽象类的props。我应该在抽象类上调用 get 方法,然后在我的 run 方法中使用它吗?或者我应该在我的子类中传递它后立即在构造函数中使用它。
  • 使用super.getProps()。在返回 props 的超类中定义了一个名为 getProps() 的方法。我举了一个关于 processName 的例子,但是你可以用同样的例子来做道具
  • 你的意思是说在我的ProcessA类的run方法中,Properties props = getProps();这一行应该是Properties props = super.getProps();
  • 是的,应该这样做
  • 好的,现在你的建议与我在ProcessB 课堂上所做的有什么区别。正如您在我的ProcessB 类中看到的那样,我直接在构造函数中使用props 对象(已通过)并仅在此处构建我的ProcessConsumer。哪个是对的?
【解决方案2】:

您的两种解决方案都可以。 但我会使用完全不同的解决方案:

 public abstract class Process implements Runnable {
    private final Properties props;
    private final String processName;

    public Process(String processName, Properties props) {
        this.processName = processName;
        this.props = props;
    }

    protected abstract void shutdown();
    protected abstract void run(String processName, Properties props);

    @Override
    public final void run() {
        run(processName, props);
    }

}

public class ProcessA extends Process {
    private ProcessConsumer<byte[], byte[]> consumer;

    public ProcessA(String processName, Properties props) {
        super(processName, props);
    }

    @Override
    public void shutdown() {
        consumer.wakeup();
    }

    @Override
    protected void run(String processName, Properties props) {
        consumer = new ProcessConsumer<>(props);
    }
}

所以进程只有一个公共方法, 您将 run 方法设置为最终方法,因此没有人可以覆盖它。 您在另一个运行方法中获取参数。

【讨论】:

  • 感谢您的解决方案。这种方法有什么好处?
  • 子类无法覆盖 getProps 和 getProcessName 方法。
  • Sub 类无法覆盖 getProps 和 getProcessName 方法。想想 Process
猜你喜欢
  • 1970-01-01
  • 2019-07-09
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多