2012-02-23 17 views
15

mam klasy A, z abstrakcyjnej metody doAction (klasy bazowej obj) spodziewa się param typu klasy bazowejPrzechodząc Klasa pochodna sposobu, który musi zastąpić oczekując klasy bazowej

public class A { 
    //.... 
    abstract void doAction(BaseClass obj); 
    //.... 
} 

Teraz mam inny klasa B, która musi przedłużyć A. Jednakże metoda doAction B wymaga użycia obiektu DerivedClass, który rozszerza BaseClass.

public class B extends class A { 
    //.. 
    void doAction(DerivedClass obj) { 
      obj.callMethodAvailableOnlyInDerivedClass(); 
     } 

} 

jaki sposób obsłużyć tę sytuację, gdy trzeba przekazać param typu DerivedClass metody mają być nadpisane, gdy jest on spodziewa się klasy bazowej?

Dzięki!

Odpowiedz

20

dokonać klasę bazową Generic:

public class A<T extends BaseClass> { 
    //.... 
    abstract void doAction(T obj); 
    //.... 
} 

i podklasę sparametryzować z klasy pochodnej:

public class B extends A<DerivedClass> { 
    //.. 
    void doAction(DerivedClass obj) { 
     obj.callMethodAvailableOnlyInDerivedClass(); 
    } 
} 

Bez leków generycznych, to nie możliwe, ponieważ B złamie umowę A: A akceptuje dowolny rodzaj BaseClass, ale ty powinieneś B tylko zaakceptować konkretna podklasa. To nie jest zgodne z Liskov principle.

+0

+1 dla zasady Liskov. Pierwszy raz słyszę o tym, dzięki! – GETah

+1

A jeśli masz kilka takich metod działających na różne obiekty ?! –

4

Można użyć:

public abstract class A<T extends BaseClass> { 
//.... 
abstract void doAction(T obj); 
//.... 
} 


public class B extends class A<DerivedClass> { 
//.. 
void doAction(DerivedClass obj) { 
     obj.callMethodAvailableOnlyInDerivedClass(); 
    } 

} 
1

Nie ma Contra-Variance parametrów w java, ponieważ nie jest bezpieczny.

Załóżmy masz A a = new B();

A potem powołać a.doAction(new BaseClass()) Co się stało?

Spowoduje to błąd czasu wykonywania, ponieważ B nie wie "co" z BaseClass. java chce tego uniknąć - więc nie ma kowariancji parametrów.

Powiązane problemy