2012-01-02 8 views
4

私は実際にJavaでデザインパターンについての本を読んでいると私は初心者です:)抽象クラスにキャスト...これはどのように可能ですか?

http://www.amazon.com/Design-Patterns-Java-TM-Software/dp/0321333020/私は私を困惑コードに出くわした複合パターンについての章では、抽象クラスへのキャストを、私も持っていますサブクラスが抽象スーパークラスのコンストラクタを呼び出すときに何が起こるのかよく分かりません。

私が話していますキャストはisTreeである(設定が訪問した)

isTreeスーパークラスのメソッドがある一方で、我々は彼の抽象スーパー にキャストした後、サブクラスの isTreeメソッドを呼び出すことができますどのように
 MachineComponent c = (MachineComponent) i.next(); 
     if (visited.contains(c) || !c.isTree(visited)) 

抽象?

package com.oozinoz.machine; 
/* 
* Copyright (c) 2001, 2005. Steven J. Metsker. 
*/ 

import java.util.*; 
import com.oozinoz.iterator.ComponentIterator; 

/** 
* Objects of this class represent either individual machines or composites of 
* machines. 
*/ 

public abstract class MachineComponent { 

    /* 
    * Subclasses implement this to support the isTree() algorithm. 
    */ 

    protected abstract boolean isTree(Set s); 

    // rest of class omitted 
} 

2:

package com.oozinoz.machine;  
/* 
* Copyright (c) 2001, 2005. Steven J. Metsker. 
*/ 

import java.util.*; 
import com.oozinoz.iterator.ComponentIterator; 
import com.oozinoz.iterator.CompositeIterator; 

/** 
* Represent a collection of machines: a manufacturing line, a bay, or a 
* factory. 
*/ 

public class MachineComposite extends MachineComponent { 
    protected List components = new ArrayList(); 

    /** 
    * @param visited a set of visited nodes 
    * @return true if this composite is a tree 
    * @see MachineComponent#isTree() 
    */ 

    protected boolean isTree(Set visited) { 
     visited.add(this); 
     Iterator i = components.iterator(); 
     while (i.hasNext()) { 
      MachineComponent c = (MachineComponent) i.next(); 
      if (visited.contains(c) || !c.isTree(visited)) 
       return false; 
     } 
     return true; 
    } 

    // rest of class omitted 
} 
+1

あなただけ –

答えて

8

これは、実行時の型(実際の型)とコンパイル時の型の区別です。

実際のオブジェクトインスタンスは実際に抽象メソッドのすべてを実装するMachineComponentの非抽象サブクラスであるため、抽象クラスMachineComponentへの型キャストは問題ありません。

抽象的なMachineComponentクラスは、割り当てられた変数のコンパイル時の型です。しかし、その抽象クラスで実際のインスタンスを作成(または作成)することはできません。

+2

@ wrscheider99 - 絶対に正しい。実際、それは抽象クラスの定義です。具体的なインスタンスを作成することはできません。具体的なインスタンスを作成するには、ORDERでサブクラス化する必要があります。率直に言って、「インターフェース」は、Javaではるかに役立つ傾向があります。しかし、抽象クラス*はOPの例を含む多くの場合重要です。 – paulsm4

1

Q:ここ

は、2つのクラスの抜粋です、あなたは抽象クラスにキャストすることはできますか?

A:もちろん、可能です。

あなたはができません。は、抽象クラスの抽象メソッドを呼び出します。 (コメント欄から挿入 - アンドリュー・バーバー - 下) - 実際には、サブクラスでその具体的な実装を呼び出しています。

+6

そうでファイル全体をダンプするつもりなら、完全に...正しくコードをフォーマットしてください。違います。 – mre

+2

@mre、それについて本当ではないですか?抽象メソッドにはコードがないので、何を呼び出すでしょうか? – Paul

+1

これは真実ですが、回答者とは違う言葉を練習している人もいます。あなたが抽象関数を呼んでいると思うなら、あなたは実際にそのサブクラスでそれを具体的に実装しています。 –

2

さて、抽象クラスAnimalのサブクラスであるCatを取ってみましょう。

猫は動物あるので、あなたはAnimalCatをキャストすることができます。それは動物の機能を持っているので、それは正常な動物が行うすべてを行います。

抽象クラスのサブクラス化は同じです。 はサブクラスなので「」と簡単に使用できます。

動物のリストを動物園として定義することはできますが、犬と猫を持つことができます。結局のところ、両方とも動物です。

CatAnimalにキャストしても、それほど実際にはCatのようにはなりません。他の動物を治療するようにコードを伝えるように伝えるだけです。あなたは猫が好きではない場合

編集
(私はどちらかしていない)、私はWikipedia article about inheritanceにリダイレクトしましょう。あなたがそれらをキャストできない場合、抽象クラスは役に立たないでしょう。

4

isTreeは、抽象クラスの抽象クラスです。クラスが非抽象として初期化されると、それを抽象クラスにキャストしてもそのメモリは変更されません。したがって、抽象クラスでメソッドを呼び出すと、具体的な実装で効果的に呼び出されます。

なぜそれが有用なのかは、抽象実装を介してサブクラスを渡すためです。

文字列クラスに 'length'メソッドがあるとします。すべての可能なString型サブクラスに関数を持たせる必要はありません。代わりに、 'length'実装を持つ基本(抽象)Stringにキャストし、それを渡します。

3

OK - さんは、もう一度試してみましょう:

Q:あなたは抽象クラスにキャストすることはできますか?

A:確かに - もちろん、あなたができる

例えば:

public class UseAbstract 
{ 
    public static void main (String[] args) 
    { 
    // Instantiate an abstract class 
    AbstractPet myDog = new Dog(); 
    myDog.sound(); 

    // Instantiate a concrete class 
    Cat myCat = new Cat(); 
    myCat.sound(); 

    // Cast a concrete class to an abstract class 
    AbstractPet somePet = (AbstractPet)myCat; 
    somePet.sound(); 
    } 
} 

abstract class AbstractPet 
{ 
    void sound() 
    { 
    System.out.println ("eek"); 
    } 
} 

class Dog extends AbstractPet 
{ 
    void sound() 
    { 
    System.out.println ("Woof"); 
    } 
} 

class Cat extends AbstractPet 
{ 
    void sound() 
    { 
    System.out.println ("meow"); 
    } 
} 
関連する問題