2009-05-03 16 views

答えて

14

派生クラスのインスタンスだけインスタンスを作成します。これらの派生クラスは依然としてコンストラクタを呼び出す必要があり、依然として抽象クラスのメンバを呼び出すことができます。つまり、プライベートメンバを使用できます。

(...ではないひどく有用な1が、ちょうど基本的な考え方を示すこと)次に例を示します

public abstract class NamedObject 
{ 
    private final String name = name; 

    protected NamedObject(String name) 
    { 
     this.name = name; 
    } 

    public String getName() 
    { 
     return name; 
    } 
} 

public class Computer extends NamedObject 
{ 
    private final int processorSpeed; 

    public Computer(String name, int processorSpeed) 
    { 
     super(name); // See, the constructor is useful 
     this.processorSpeed = processorSpeed; 
    } 

    public String toString() 
    { 
     return getName() + " (" + processorSpeed + ")"; 
    } 
} 

私ははしばしば、一般的に組成物を好むという抽象クラスを書くと言うことはできません継承は、私がを実行するとを作成すると、私は確かにコンストラクタとプライベートメンバーを使用します。

3

抽象クラスは、いくつかのインタフェースの部分実装を提供します。その実装の一部を提供し、クライアントコード(具体的なサブクラス)が特定のもの、つまりカプセル化の原則の拡張にアクセスすることを禁止することを検討することは、完全に合理的です。

一部のメンバーをプライベートとしてマークすると、継承するクラスは保護されたメソッドを呼び出して、その部分的な実装にアクセスします。コンストラクタを提供することにより、サブクラスは、自身の構築中に親のカプセル化状態を初期化することができます。

1

インターフェイスとは異なり、データフィールドを定義する抽象クラスは、実際にはこれらのデータフィールドが割り当てられるという意味でインスタンス化されます。彼ら自身がインスタンス化されることはありません。サブクラスであるより大きなものの一部としてインスタンス化されます。したがって、サブクラスがビルドされると、スーパータイプも構築されるため、コンストラクタが必要になります。

階層に応じて、抽象クラスは意味と状態を持つことがあります。たとえば、あなたのアプリケーションが学校の場合、あなたは名前とSSNを持つ人物の概念を持つかもしれませんが、学生と教員のために異なるサブタイプがあります。両方のタイプの人が特定の状態構造(名前とSSN)を共有するため、両方のクラスでPersonクラスが拡張されます。しかし、あなたは単に人を直接インスタンス化することはありません。

0

Jonの答えに加えて、抽象クラスは、サブクラスツリーを浅くしておくと、コンポジションがまだよくなると言いたいと思います。私。いくつかの密接に関連するオブジェクトに共通の基底クラスを提供するのに最適ですが、サブクラスの巨大なツリーを作成するためではありません。

0

なぜプライベートクラスが必要ですか?私は抽象クラスをインターフェイスと混同していると思います。インタフェースとは異なり、抽象クラスは機能を保持できます。たとえば:

public class AbstractBase{ 
    private int num; 

    public AbstractBase(int number){ 
     this->num = number; 
    } 

    public int method(){ 
     return (this->num * this->templateMethod()); 
    } 

    public abstract int templateMethod(); 
} 

パブリッククラスConcreteDerivedは、この例ではAbstractBase {

public ConcreteDerived(){ 
    super(4); 
} 

public int templateMethod(){ 
    return number; //number is the result of some calculation 
} 

}

を拡張し、you'llは、明示的にAbstractBaseをインスタンス化しませんが、メンバーやコンストラクタを宣言することによって、あなたがカスタマイズすることができますクラスの機能(これはテンプレートメソッドと呼ばれます)。

0

アドホックなコードやプロトタイプを作成していると仮定すると、時々、抽象クラス(または多分、インタフェースも)をインスタンス化します。彼らは匿名内部クラス(onetwo)と呼ばれると、このようになります:

// you have this... 
public abstract class SomeClass { 
    public abstract String returnAString(); 
} 

// ...and this... 
public class OtherClass { 
    public void operate(SomeClass c) { 
     System.out.println(c.returnAString()); 
    } 
} 

// ...so you do this:  
OtherClass oc = new OtherClass(); 
// this is one of the reasons why you need to specify a constructor 
oc.operate(new SomeClass() { 
    @Override 
    public String returnAString() { 
     return "I'm an anonymous inner class!"; 
    } 
}); 

この例では、もちろん、非常に冗長ですが、ポイントを公開する必要があります。いくつかの既存のフレームワークは、この動作の多量の使用、つまり少なくともApache Wicketに依存しています。

関連する問題