2016-11-28 6 views
0

私は、抽象クラスのプライベートフィールドにアクセスし、抽象クラスを拡張しているクラスでそれを使用する正しい方法が何であるかを調べようとしています。以下は抽象クラスのフィールドにアクセスする正しい方法は?

Processクラス(抽象)私の抽象クラスです:

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オブジェクトを使用していますどのように1つの方法です。

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(); 
    } 
} 

私はProcessConsumerオブジェクトを作る際にpropsプロパティを使用したいが、私はpropsオブジェクトを使用するための正しい方法は何か混乱していますか?私は実行メソッドの中で抽象クラスのgetPropsメソッドを呼び出して使用する必要がありますか?それともコンストラクタに入れてビルドしますか?

違いとは何ですか?

+0

プライベートのポイントは、拡張クラスや他のクラスではなく、クラス自体のコードからアクセスできないことです。あなたがそれにアクセスできるようにしたいのであれば、それを保護する必要があります。しかし、何らかの保護されたまたは公共のアクセサーを作るのが良い。 – vextorspace

答えて

1

両方のソリューションが機能します。 しかし、私は完全に他のソリューションを使用します:だから、プロセスは一つだけ、パブリックメソッドを持っている

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メソッドの最終を作るので、誰もそれをオーバーライドすることができませんでした。 もう1つの実行方法でパラメータを取得します。

+0

このソリューションをありがとう。このアプローチのメリットは何ですか? – john

+0

SubクラスはgetPropsメソッドとgetProcessNameメソッドをオーバーライドできません。 – idefixcert

+0

SubクラスはgetPropsメソッドとgetProcessNameメソッドをオーバーライドできません。 Process < - ProcessA < - ProcessAA、プロセスAAがgetPropsをオーバーライドする場合はどうなりますか...この解決策ではこれは不可能です。延長のために開いていますが、変更のためにcolsed。 (オープン/クローズドの原理という意味ではありません) – idefixcert

1

抽象クラスを拡張すると、サブクラスはプライベートフィールドを継承しますが、それらはアクセスできません。プライベートフィールドは、定義されたクラスのスコープでしかアクセスできないため、superを使用してアクセスします。あなたはthisの母としてsuperで見ることができます:

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を使用することによって。 A protectedフィールドはプライベートfieldと似ていますが、継承され、サブクラスによってアクセス可能です。だからthis.someProtectedField(ゲッター関数ではないことに気付く)の代わりにsuper.getSomePrivateField()

と呼ぶことができます。私はこれがあなたが尋ねていることであり、十分に明確にしてくれることを願っています。

+0

これは私が求めていることではありません。私の質問は、私のサブクラスで抽象クラスの 'props'にアクセスする方法でした。抽象クラスのgetメソッドを呼び出して、それを実行メソッドで使用する必要がありますか?または、私はそれが私のサブクラスで渡されるとすぐにコンストラクタで使用する必要があります。 – john

+0

は 'super.getProps()'を使います。スーパークラスに 'getProps()'というメソッドを定義して、そのメソッドを返すようにしました。私は 'processName'についての例を挙げましたが、あなたは' ProcessA'クラスの私の実行メソッドで言うことを意味する小道具 – vlatkozelka

+0

のために同じものを使うことができます、この行 'Properties props = getProps();'は 'Properties props = super 'でなければなりません。 – john

関連する問題