2010-05-27 4 views
0

첫째, 질문 제목에 대해 유감 스럽지만 문제를 더 잘 설명 할 수는 없습니다. 자유롭게 변경할 수 있습니다 :)이 간단한 계층 구조 Java 문제에 대한 최선의 접근 방법은 무엇입니까?

자,이 추상 클래스 Box은 몇 가지 생성자, 메소드 및 일부 개인 변수를 구현합니다. 그런 다음 BoxABoxB과 같은 몇 가지 하위 클래스가 있습니다. 이 두 가지 모두 여분의 일을 구현합니다.

다른 추상 클래스 ShapeSquareCircle과 같은 몇 가지 하위 클래스가 있습니다. BoxA 내가 Shape 개체의 목록이 필요하지만, 난 단지 Square 객체가 BoxA로 이동의 목록 만 Circle 객체가 BoxB에 들어갈 '의 목록에 있는지 확인해야 BoxB 모두 들어

.

(각 상자에) 그 목록은

, 나는 또한 get()set() 방법 및 addShape()removeShape() 방법이 필요합니다.

알아둬야 할 또 다른 중요한 점은 각각의 상자가 생성 될 때 각각 BoxA 또는 BoxB이고 각각 ​​각각 Shape 목록이 동일하다는 것입니다. 예를 들어 Square의 이름이 ls이고 두 개의 BoxA이라는 객체가 boxA1boxA2 인 경우를 예로 들어 보겠습니다. 무엇을해도 boxA1boxA2은 모두 ls 목록이어야합니다.

내 생각 : 목록으로

public abstract class Box { 
    // private instance variables 

    public Box() { 
     // constructor stuff 
    } 

    // public instance methods 
} 

public class BoxA extends Box { 
    // private instance variables 

    private static List<Shape> list; 

    public BoxA() { 
     // constructor stuff 
    } 

    // public instance methods 

    public static List<Square> getList() { 
     List<Square> aux = new ArrayList<Square>(); 

     for(Square s : list.values()) { 
      aux.add(s.clone()); // I know what I'm doing with this clone, don't worry about it 
     } 

     return aux; 
    } 

    public static void setList(List<Square> newList) { 
     list = new ArrayList<Square>(newList); 
    } 

    public static void addShape(Square s) { 
     list.add(s); 
    } 

    public static void removeShape(Square s) { 
     list.remove(list.indexOf(s)); 
    } 
} 

객체의 유형에 대해 동일해야합니다, 나는 static로 선언하고 그 목록에 근무하는 모든 방법은 static이다. 자, BoxB의 경우 클래스는 목록 항목과 거의 동일합니다. 나는 SquareTriangle으로 바꾸고 문제가 해결되었습니다. 따라서 각각의 BoxA 개체가 생성 될 때 목록은 하나만 같을 것입니다. BoxB 개체가 만들어지기는하지만 각기 다른 유형의 목록이있는 경우에도 마찬가지입니다.

그래서 내 문제는 무엇입니까? 글쎄, 나는 코드를 좋아하지 않는다 ... BoxABoxB에 대해 getList(), setList(), addShape() 및는 기본적으로 반복된다. 목록이 보유 할 객체의 유형 만 다르다. 어떻게 든 모든 방법을 "중복"하는 것을 피하고 싶었습니다.

나는 대신 수퍼 클래스 Box에서 할 수있는 방법을 생각할 수 없다. 또한 Square 또는 Triangle 대신 Shape을 사용하여 정적으로 처리하려고하면 목록이 모든 BoxABoxB 개체 중 하나 일 뿐이므로 하나만 사용해야하지만 각 하위 클래스는 Box이어야합니다.

어떻게 다르게 할 수 있습니까?

P.S : 내가하는 일에 대해 정확한 영어 단어를 모르기 때문에 실제 사례를 설명 할 수 없으므로 방금 상자와 모양 예제를 사용했지만 기본적으로 동일합니다.

+0

Box를 제네릭 형식으로 제안했지만 일반 정적 메서드는 사용할 수 없습니다. – Powerlord

+0

리스트가 정적이 아닌 경우 제네릭을 사용할 수 있습니다. 상자를 생성하고 상자 생성자에서 목록을 전달하는 팩토리를 만듭니다. – Beothorn

+0

그건 여전히 상자 당 목록을 만들 것이고 나는 그것을 원하지 않을 것입니다. 그렇지 않니? 어쨌든, 나는 그런 것을 배우지 않았으므로 그것을 사용하지 않아야한다. –

답변

1

당신은 같은 것을 시도 할 수 :

abstract class Box<E extends Shape> { 

    abstract protected List<E> getList(); 

    abstract protected void setList(List<E> list); 

    protected static <T extends Shape> List<T> getCommon(Box<T> box) { 
     List<T> aux = new ArrayList<T>(); 
     for (T s : box.getList()) { 
      aux.add((T) s.clone()); 
     } 
     return aux; 
    } 

    protected static <T extends Shape> void setCommon(Box<T> box, List<T> newList) { 
     // do something on newList here if needed as common functionality 
     box.setList(new ArrayList<T>(newList)); 
    } 
} 
class BoxA extends Box<Square> { 
    private static List<Square> list; 

    @Override 
    protected List<Square> getList() { 
     return list; 
    } 

    @Override 
    protected void setList(List<Square> list) { 
     this.list = list; 
    } 

    public static List<Square> get() { 
     return getCommon(new BoxA()); 
    } 

    public static void set(List<Square> newList) { 
     setCommon(new BoxA(), newList); 
    } 
} 

그것은 hackish 약간의를하지만 당신은 몇 가지 일반적인 기능을 유지하기 위해 상위 클래스를 사용할 수 있습니다. 당신은 여전히 ​​자식 클래스에서 최종 메소드를 가져야 할 것이다.하지만 부모 메소드가 현재 메소드의 새로운 인스턴스를 제공하는 부모 메소드를 호출하므로, 부모 메소드가 그로부터 일반적인 타입을 추론 할 수있다. getList()setList()은 Box의 type 매개 변수를 허용 할 수 있도록 고정되어 있지 않으며 외부에 표시되지 않도록 보호되어 있습니다. 부모는 자식에 속한 변수에 대한 공통 작업을 수행 할 수 있도록 개인 확장 변수 (각 확장 클래스에 있어야 함)에 대한 getter 설정자 역할을합니다. 또한 부모 타입 파라미터를 통과하면서

get()set() 방법 및 사용 new BoxA() (또는 new BoxB())는 정적 목록에 대한 액세스를 허용한다. 리스트가 정적이기 때문에 어떤 인스턴스가 그것을 반환하는지는 중요하지 않습니다. 공통적 인 메소드는 클래스에없는 자체 매개 변수입니다. 실제로 BoxA 내에서 getCommon(new BoxB())으로 전화 할 수 있으므로 올바른 전화를 걸 수 있는지 확인하는 것이 좋습니다.

관련 문제