2010-12-01 2 views
1

필자에게는 수퍼 클래스 Shape가 있으며 Triangle, Square 등의 클래스는 Shape를 확장합니다. 현재 두 가지 문제가 있습니다.Java의 서브 클래스에 메소드 위임

  1. 내 방법 Triangle extends Shape이 컴파일되지 않습니다. 삼각형이 아닌 모양을 반환해야합니다.
  2. 이 방법을 숨기고 싶습니다. Shape 상위 클래스에서만 호출 할 수 있어야합니다.
public class Shape { 
    public static Shape createShapeFromXML(String xml) { 
    String type = parse(xml); 
     if (type.equals("Triangle") { 
     Triangle.createShapeFromXML(xml); 
     } else if (...) { 
     // ... 
    } 
    } 
} 

public class Triangle extends Shape { 
    public static Triangle createShapeFromXML(String xml) { 
    .... 
    } 
} 

public static void main(String[] args) { 
    String xml = ... 
    Shape s = Shape.createShapeFromXML(xml); 
} 

이러한 문제를 해결하는 방법은 수 있습니까?

답변

6

수퍼 클래스에 하나의 정적 메서드를 유지하고 적절한 Shape 서브 클래스를 반환하지 않는 이유는 무엇입니까? 삼각형은 Shape와 관계가 있기 때문에 서명은 그대로 유지됩니다.

당신은 당신이 원하는 액세스 제한을 얻을 수있는 슈퍼 클래스 개인의 방법을 만들 수 ...

또 다른 방법은 Factory 패턴을 사용하는 것입니다. 당신은 ShapeFactory를 가질 수 있습니다. XML 파싱을 생성하는 것이 Shape 클래스의 관심사가 아니기 때문에 이것은 좋은 생각입니다. 우려를 분리하십시오. 위키피디아 링크는 패턴을 설명하는 데 유용하지만 간단한 예를 원할 수 있습니다. this을 참조하십시오.

+1

특히 이것은 추상적 인 공장의 예라고 생각합니다. 나는 GoF가 그들을 두 개의 분리 된 패턴으로 분류 한 이유를 정말로 모른다. –

+0

공장 패턴에 +1. 그것은 형태 클래스 책임 fopr 객체 생성 –

+0

@ Karl : FactoryMethod와 AbstractFactory의 기본적인 차이점은 FactoryMethod가 클래스 계층 구조 (추상 기본 클래스) 내부에서 호출되는 반면 AbstractFactory는 외부에서 사용된다는 점입니다. (GoFBook은 FactoryMethod가 "클래스 기반"이지만 AbstractFactory는 "객체 기반"이라는 말로이 사실을 암시합니다.) - JavaRanch FAQ에서. –

1

코드를 컴파일하려면 public static Shape createShapeFromXML(String xml)을 Triangle 클래스로 선언해야합니다.

 

public class Shape { 

    public static void main(String[] args) { 
      String xml = "Triangle"; 
      Shape s = Shape.createShapeFromXML(xml); 
      System.out.println(s.toString()); 
    } 

    public static Shape createShapeFromXML(String xml) { 
     Shape aShape = null; 

     if (xml.equals("Triangle")) { 
     aShape = Triangle.createShapeFromXML(xml); 
     } 
     return aShape; 
    } 
} 

class Triangle extends Shape { 

    public static Shape createShapeFromXML(String xml) { 
     return new Triangle(); 
    } 

    @Override 
    public String toString() { 
     return "Triangle"; 
    } 
} 

 

The System.out.println (s.toString()); main 메소드 출력에서 ​​"Triangle"은 삼각형 모양이 생성되었음을 증명합니다.

2

// 2. I want to hide this method. It should only be callable from superclass Shape

구현을 잠 그려면 Shape 메서드 final을 만들 수 있습니다. 심지어 하위 클래스 유형 (예 : Triangle)을 반환하는 오버로드 된 메서드는 컴파일러에 의해 플래그가 지정됩니다.

public static final Shape createShapeFromXML(String xml) { ... } 

편집 :

:

public class Shape { 
    public static final Shape createShapeFromXML(String xml) { 
     if (xml.equals("Triangle")) {//removed parse for demo compliation 
     return Triangle.createShapeFromXML(xml); 
     } else { 
     return new Shape(); 
     } 
    } 
} 

public class Triangle extends Shape{ 
    public static Triangle createShapeFromXML(String xml) { 
     return new Triangle(); 
    } 
} 

위의 컴파일러 오류가 발생합니다 컴파일하려고 : 증거

코멘트에 대화에 응답

, 나는 다음과 같은 제공

mybox:src akf$ javac Triangle.java 
Triangle.java:3: createShapeFromXML(java.lang.String) in Triangle cannot override createShapeFromXML(java.lang.String) in Shape; overridden method is static final 
    public static Triangle createShapeFromXML(String xml) { 
           ^
1 error 

이것은 JLS을 참조하여 설명 할 수 있습니다. 두 부분 (분류 방법에 의해) 8.4.6.2 숨지

:

If a class declares a static method, then the declaration of that method is said to hide any and all methods with the same signature in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class.

하고 8.4.3.3 final 방법에서 :

A method can be declared final to prevent subclasses from overriding or hiding it. It is a compile-time error to attempt to override or hide a final method.

함께 두 퍼팅 정적 메서드의 서명에 final을 추가하면 해당 메서드가 하위 클래스에 의해 숨겨지지 않도록 보호됩니다.컴파일시 검사를 시행합니다.

+0

정적 메서드를 재정의 할 수 없으므로 'final'은 그대로 사용합니다. – ColinD

+0

그것은 합법적 인 것이며, 아마도 '숨김'은 무시 된 것보다 더 나은 용어입니다. 'final'은 동일한 시그니쳐를 가진 메소드가 서브 클래스에서 구현되는 것을 금지하기 때문에, 컴파일러는 숨어있는 메소드에 플래그를 지정합니다. – akf

+0

@afk : 실제로는 그렇지 않습니다. – ColinD

관련 문제