2012-01-20 3 views
2

하나의 메소드에서 추상 생성자를 호출 한 다음이를 다른 하위 클래스로 전달할 수있는 다른 메소드로 전달할 수 있습니까? 즉,이 피해 갈 수추상 생성자를 실행 한 다음 하위 클래스로 캐스팅

public AbstractClass createNewAbstractClass() { 
    //do lots of checks that are the same for each sub class, 
    //including geting and checking each variable, 
    //and an exception thrown by the constructor. 
    AbstractClass abstractClassObject = new AbstractClass(var1, ...); 
    return abstractClassObject; 
} 

public SubClassOne createSubClassOneObject() { 
    SubClassOne subClassOneObject = (SubClassOne)createNewAbstractClass(var1,..); 
    return subClassOneObject; 
} 

public SubClassTwo createSubClassTwoObject() { ... 

한 가지 방법은 방법 createSubClassNObject() 오른쪽 생성자에서 사용할 수 있도록, 얻을 하나의 방법에있는 모든 변수를 확인하고 배열을 반환하는 것입니다,하지만 그것은 꽤 혼란스러워 보입니다. 그리고 그것은 각각의 create 메소드가 동일한 예외를 동일한 방식으로 검사하고 그것에 대해 동일한 작업을 수행해야한다는 것을 의미합니다. 이는 다른 메소드로 아웃소싱하려고해야하는 상황과 똑같습니다.

나는 실용적인 관점에서 흥미 롭다. 나는 내 코드를 깔끔하고 읽기 쉽도록하려고하지만, 이론적 인 관점에서 바라지 만, 실제로 가능한가? 따라서 대답이 '아니오'인 경우에도 이유를 설명해 주시겠습니까?

답변

4

이와 몇 가지 문제가 있습니다

  • 추상 클래스를 인스턴스화 할 수는; 추상 클래스의 생성자는 서브 클래스의 생성자에서만 호출 할 수 있습니다.
  • 는 부모 클래스가 추상적되지 않은 경우에도, 우리가 정말 유형 AbstractClass의 인스턴스가 때문에 실패 할 것 (SubClassOne) 캐스트는 유형 SubClassOne 아닌 인스턴스는 AbstractClass로 입력된다.

그래서 불행히도 SubClassOne을 반환하는 방법은 AbstractClass과 같은 매개 변수를 단지 super 호출을 위임 할 수있는하는 SubClassOne 생성자를 호출해야합니다.

각각의 팩토리 메소드에서 예외 처리 코드를 복제하는 것이 쉬운 방법이 없다고 생각합니다. 생성자는 다형성과 잘 일치하지 않습니다. AbstractClass을 반환하는 중앙 생성자를 가질 수 있지만 호출 할 하위 클래스 생성자에게 매개 변수 (enum, Class, 무엇이든간에)가 필요합니다.

abstract class Cow { 
    Cow() throws Exception { 
    ... // possible exceptions 
    } 
} 

class FatCow extends Cow { 
    FatCow() throws Exception { 
    super(); 
    ... 
    } 
} 

class GreenCow extends Cow { 
    GreenCow() throws Exception { 
    super(); 
    ... 
    } 
} 

enum CowType { 
    FAT_COW, GREEN_COW; 
} 

class CowMachine { 
    static Cow makeCow(CowType type) { 
    try { 
     switch (type) { 
     case FAT_COW: 
      return new FatCow(); 
     case GREEN_COW: 
      return new GreenCow(); 
     default: 
      throw new IllegalArgumentException(); 
     } 
    } catch (Exception e) { 
     ... 
     return null; 
    } 
    } 

    static Cow makeFatCow() { 
    return (FatCow) makeCow(CowType.FAT_COW); 
    } 

    static Cow makeGreenCow() { 
    return (GreenCow) makeCow(CowType.GREEN_COW); 
    } 
} 

당신은 큰 스위치 없음 문을 원하지 않는 경우, 당신은 대신 Class 객체를 받아 들일 수 있고이 느린 것이지만, newInstance를 호출합니다.

+0

좋습니다. 감사합니다. 그것은 내 머리 속에서 추상적 인 수업을 조금이라도 정리했습니다 - 제가 왜 묻고있는 것을 할 수 없는지 이해할 수 있다고 생각합니다. – DenverCoder8

관련 문제