2012-01-02 4 views
4

실제로 자바 디자인 패턴에 대한 책을 읽고 그리고 난 내가, 추상 클래스에 캐스트 나 퍼즐 코드를 건너 왔어요 복합 패턴에 대한 장에서 초보자 :추상 클래스로 캐스트 ... 어떻게 가능합니까?

http://www.amazon.com/Design-Patterns-Java-TM-Software/dp/0321333020/ 오전, 나는 또한이 하위 클래스가 추상 수퍼 클래스의 생성자를 호출 할 때 어떤 일이 발생하는지 잘 이해하지 못한다면 제발 나를 도와주세요 !!

내가 (설정 방문) 우리가 isTree 슈퍼 클래스 메소드가있는 동안 그의 추상 슈퍼 클래스 에 주조 후 서브 클래스의 isTree 메서드를 호출 할 수있는 방법

 MachineComponent c = (MachineComponent) i.next(); 
     if (visited.contains(c) || !c.isTree(visited)) 

isTree에 대해서 이야기 캐스트 추상?

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에서 서브 클래스해야합니다. 솔직히, "인터페이스"는 자바에서 훨씬 더 유용합니다. 그러나 추상적 인 클래스 *는 OP의 예를 포함하여 많은 경우에 중요합니다. – paulsm4

1

Q :

다음은 두 클래스의 조각입니다 당신이 추상 클래스로 캐스팅 할 수 있습니까?

A : 물론 가능합니다.

이 할 수없는 것은입니다. do는 추상 클래스의 추상 메소드를 호출합니다. (주석 섹션에서 삽입 - Andrew Barber- 아래) - 실제로 하위 클래스에서이 클래스의 구체적인 구현을 호출하고 있습니다.

+6

그래 ... 완전히 사실이 아니다. – mre

+2

@mre, 그것에 대해 사실이 아닌 것은 무엇입니까? 추상 메소드에는 코드가 없으므로 전화 할 것이 무엇입니까? – Paul

+1

이것은 사실입니다. 응답자와 다른 용어를 따지면 어떤 사람들이 그렇게 생각하지 않을 수도 있습니다. 추상 함수를 호출한다고 생각하면 실제로 하위 클래스에서이 함수의 구체적인 구현을 호출합니다. –

2

글쎄, Cat은 추상적 클래스 Animal의 서브 클래스입니다.

고양이가이기 때문에 CatAnimal으로 변환 할 수 있습니다. 정상적인 동물은 동물의 기능을 가지고 있기 때문에 모든 일을합니다.

추상 클래스의 서브 클래 싱은 동일합니다. 서브 클래스이기 때문에 은 ""입니다.

동물 목록을 동물원으로 정의 할 수 있지만 개와 고양이가있을 수 있습니다. 결국 그들은 모두 동물입니다.

CatAnimal으로 캐스팅해도 실제로는 Cat이 줄어들지 않습니다. 다른 동물을 치료할 것처럼 코드를 처리하도록 지정하십시오. 당신이 고양이를 좋아하지 않는 경우

편집
(나도하지 않음), 나를 Wikipedia article about inheritance로 리디렉션 할 수 있습니다. 추상 클래스는 캐스트 할 수 없다면 쓸모가 없습니다.

4

isTree는 추상적 인 클래스에 대해서만 추상입니다. 클래스가 비 추상화로 초기화 된 후에는 추상화로 캐스팅하면 메모리가 변경되지 않습니다. 따라서 추상 클래스에서 메서드를 호출하면 효과적으로 구현에서이를 호출합니다.

유용한 이유는 추상 구현을 통해 서브 클래스를 전달하는 이유입니다.

문자열 클래스에 '길이'메소드가 있다고 가정 해 보겠습니다. 가능한 모든 String 유형 하위 클래스에 대해 함수를 가질 필요가 없습니다. 대신 'length'구현을 가진 기본 (추상) 문자열로 캐스팅 한 다음 전달합니다.

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"); 
    } 
} 
관련 문제