2014-06-16 2 views
3

나는 서브 클래스가 SubclassA, SubclassBSubclassA 인 서브 클래스가 SubSubClass 인 추상 클래스 Entity을 보유하고 있습니다. Java에서 객체를 동적으로 전송 하시겠습니까?

class SomeClass{ 
    void doSomething(Entity e){..} 
    void doSomething(SubclassA e){..} 
    void doSomething(SubclassB e){..} 
    void doSomething(SubSubClass e){..} 
} 

가 나는 List<Entity> list 있습니다

은 또한 다음과 같습니다 클래스 SomeClass의 객체 someObject 있습니다. 이 목록의 모든 항목은 someObject.doSomething으로 전달됩니다.

for(Entity entity : list){ 
    someObject.doSomething(entity); 
} 

점은 참조 형은 항상 Entity 때문에 doSomething(Entity e) 항상 상관없이 현재 Entity의 실제의 형태가 무엇인지, 호출되지 않습니다이다. 이 문제를 해결하려면 캐스팅해야합니다 (예 : someObject.doSomething((SubclassB)entity)).

instanceof 작업 없이는 어떤 구체적인 유형이든 개체를 동적으로 캐스팅 할 수 있는지 궁금합니다.

이렇게 할 방법이 없다면 내 상황을 어떻게 처리하겠습니까?

답변

5

플립가, 추가 할 receiveWork (또는 당신이 그것을 이름을 원하는대로) Entity와 그 서브 클래스에 (아마도이 ​​Runnable 또는 다른 실행 단위를 기대하는) 방법을하고 foreach 루프에서이 메소드를 호출합니다. 다형성이 당신을 위해 일하게하십시오.

1

개인적으로, 단 하나의 doSomething(Entity e) 함수를 작성한 후 instanceof을 사용하여 서브 클래스를 결정하십시오. 죄송합니다. 문제를 해결할 수있는 솔루션을 제공 할 수 없습니다. 귀하의 프로젝트에 대한 더 많은 정보를 알지 못한다면 그것은 제가 생각하기에는 간단하고 충분한 해결책 일 것 같습니다. 희망이 도움이!

0

이것은 OO 원칙을 위반하는 것처럼 느껴집니다.

이러한 메서드가 하위 클래스에 위임되지 않는 이유는 무엇입니까?

doSomething을 Entity에 첨부하고 재정의하면이 Someclass의 메소드가 단순히 엔티티를 가져 와서 entity.doSomething()을 호출 할 수 있습니다. 그러면 자동으로 적절한 메소드가 호출됩니다. 다형성을 통해.

4

자신이 물건을 던지기를 원한다면 아마도 이미 잘못했을 것입니다.

실수로 객체에 무엇인가를하는 코드를 작성하려고합니다. 대신 객체 자체에서 수행하는 방법을 가르쳐야합니다. 이것은 oop의 핵심 교리입니다. 이 당신이 원하는 경우 지금

class Entity { 

    public void action(SomeClass c) { 
     c.doSomething(this); 
    } 
} 

class SubclassA extends Entity { 

    public void action(SomeClass c) { 
     c.doSomething(this); 
    } 
} 

class SubclassB extends Entity { 

    public void action(SomeClass c) { 
     c.doSomething(this); 
    } 
} 

class SubSubClass extends SubclassA { 

    public void action(SomeClass c) { 
     c.doSomething(this); 
    } 
} 

class SomeClass { 

    void doSomething(Entity e) { 
     System.out.println("Do something (Entity) with an " + e.getClass()); 
    } 

    void doSomething(SubclassA e) { 
     System.out.println("Do something (SubclassA) with an " + e.getClass()); 
    } 

    void doSomething(SubclassB e) { 
     System.out.println("Do something (SubclassB) with an " + e.getClass()); 
    } 

    void doSomething(SubSubClass e) { 
     System.out.println("Do something (SubSubClass) with an " + e.getClass()); 
    } 
} 

public void test() { 
    List<Entity> list = new ArrayList<>(); 
    list.add(new Entity()); 
    list.add(new SubclassA()); 
    list.add(new SubclassB()); 
    list.add(new SubSubClass()); 
    SomeClass someObject = new SomeClass(); 
    for (Entity entity : list) { 
     entity.action(someObject); 
    } 
} 
0

, 나는 모르겠지만, 당신이 instanceof를 사용하지 않기 때문에, 나는 개인적으로 모든 캐스팅 것 :

은이 얼마나 간단한 참조 엔티티를 가장 낮은 하위 클래스로 내려 받고 잘못된 객체를받는 경우 예외를 throw하는 doSomething 메서드를 사용합니다. 그런 다음 예외가 발생하면 잡을 수 있습니다. catch 블록에서 메서드에 동일한 개체 (한 수준 위로 캐스팅 됨)를 전달합니다.이 당신이 원하는 것 무엇이며,이 중첩 된 시도의 catch 블록의 무리를 사용하지만 여전히 솔루션의 경우

for(Entity entity : list){ 
    try { 
     doSomething((SubSubclass)entity); 
    } catch (SomeException e) { 
     try { 
     doSomething((SubClassA)entity); //I believe that this throws a ClassCastException of the object is actually a SubClassB... 
     } catch (SomeException e) { 
     try { 
      //etc. etc... 

다시, 나도 몰라.

관련 문제