私が集めたものから、クラスに特定のプライベート フィールド (およびメソッド) を強制的に使用させたいと考えています。インターフェイスは public/static/final フィールドとメソッドのみを宣言するため、抽象クラスが必要です。正しい??
私は最初の大きな Java プロジェクトを始めたばかりで、後で自分を傷つけないようにしたいと思っています :)
私が集めたものから、クラスに特定のプライベート フィールド (およびメソッド) を強制的に使用させたいと考えています。インターフェイスは public/static/final フィールドとメソッドのみを宣言するため、抽象クラスが必要です。正しい??
私は最初の大きな Java プロジェクトを始めたばかりで、後で自分を傷つけないようにしたいと思っています :)
両方を提供することはかなり一般的であるため、最終的には次のようになります。
public interface Sendable {
public void sendMe();
}
と
public abstract class AbstractSender implements Sendable {
public abstract void send();
public void sendMe() {
send(this.toString());
}
}
そうすれば、抽象クラスのデフォルトの実装に満足している人は誰でも、多くのコードを書き直すことなくすばやくサブクラス化できますが、より複雑なことを行う必要がある人 (または別の基本クラスから継承する必要がある人) は、引き続き実装できます。インターフェイスとプラグアンドプレイです。
特定のプライベート フィールドまたはメソッドの使用を強制したくない場合。一般に、実装は気にせず、インターフェイスを気にします。そのため、いくつかのインターフェイスでいくつかのメソッドを定義し (必要な量に応じて)、それらを実装するクラスを定義します。これはおそらく将来的にあなたを傷つけることはほとんどありません.
プライベート フィールドとメソッドは、サブクラスでは使用できません (それらが内部クラスでもある場合を除く)。ただし、それらを保護することはできます。
インターフェースはまさにそれを定義します - 実装クラスの外の世界とのインターフェース (コントラクト)。(抽象であろうとなかろうと) スーパークラスの public メソッドも同じことを行います。サブクラスに特定のプライベートメンバーを要求するべきではありません.OOPが回避しようとしている実装を指定しようとしています.
スーパークラスでいくつかの共有動作を定義したい場合は、抽象クラスを使用しますが、そのクラスは単独で立つことはできません (サブクラス化する必要があります)。共有動作には独自の状態が必要な場合があります。その場合、プライベート フィールドを定義でき、それだけが使用できるプライベート メソッドもある場合があります。
抽象クラスから継承しても、そのプライベート フィールド/メソッドにはアクセスできません。
クラスに特定のプライベート フィールド (およびメソッド) を強制的に使用させたい
あなたの質問のこの部分は疑問です: なぜあなたはこれをやりたいと思いますか?
プライベート メンバーはサブクラスからは見えず、インターフェイスはパブリック インターフェイスを定義するため、唯一の選択肢は抽象クラスを使用することです...しかし、誰もがこれをやりたいと思う理由は思いつきません
正解です。ただし、必ずしもどちらか一方の決定であるとは限りません。インターフェイスと共にスケルトン実装を提供することで、インターフェイスと抽象クラスの利点を組み合わせることができます。このアプローチの非常に興味深い説明は、Effective Java, 2nd Ed. にあります。、項目 18 (「抽象クラスよりもインターフェイスを優先する」)。
そのとおりです。インターフェースは一般消費用です。また、プライベート実装は抽象 (または具象) クラスにある必要があります。
どちらを選択するか迷っている場合は、インターフェイスの側で間違いを犯すことをお勧めします。抽象クラスであるはずのインターフェイスを使用する方が、その逆よりも優れています。
インターフェイスは、動作の契約を定義します。属性ではなく、それが必要なのです。
サブクラスに特定のメソッドを定義させたい場合は、インターフェイスを使用するとうまくいきます。他の人が言ったように、それはサブクラスがそれを行う方法についてではなく、それがそれを行うという事実だけです。
クラスで別のクラスの特定のフィールドまたはメソッドを使用する場合は、それらを保護されていると宣言できます。
public abstract class A {
protected Object thing;
}
同じパッケージ内の別のクラスからアクセスできます (クラス A を拡張している場合もそうでない場合もあります)
A a = new A();
a.thing.toString();
ただし、別のクラスにそれを使用するように「強制」するのではなく、「有効にする」のと同じです。