To jest moje pierwsze pytanie, mam nadzieję, że jest wystarczająco użyteczne, zarówno dla czytelników, jak i dla mnie! Przez ostatnie dwa dni szukałem go w Google przez cały ten czas.Oddanie ogólnej klasy nadrzędnej do podklasy
mam abstrakcyjny model i pamięci masowej klasy, z którego beton klasy modelu i magazynowania są pochodne:
abstract class Food {}
abstract class FoodStorage<T extends Food> {
abstract void setFood(T food);
}
class Apple extends Food {}
class Basket extends FoodStorage<Apple> {
@Override
void setFood(Apple apple) {
// Save that apple to the basket
}
}
żaden problem. Teraz chciałbym móc zadzwonić pod numer save()
bezpośrednio na instancję Apple
, zachowując ją do jej Basket
(bez konieczności zawracania sobie głowy koszem) i zaimplementować ją w klasach abstrakcyjnych. Najlepszym Mam jeszcze znaleźć to:
abstract class Food<T extends Food<T,S>,
S extends FoodStorage<T,S>> {
abstract S getStorage();
void save() {
getStorage().setFood((T)this); // <---- Unchecked cast warning
}
}
abstract class FoodStorage<T extends Food<T,S>, S extends FoodStorage<T,S>> {
abstract void setFood(T food);
}
class Apple extends Food<Apple,Basket> {
Basket basket = new Basket(); // or Basket.getInstance();
@Override
Basket getStorage() {
return basket;
}
}
class Basket extends FoodStorage<Apple,Basket> {
@Override
void setFood(Apple apple) {
// Save that apple to the basket
}
}
który pracuje, ale IntelliJ daje mi ostrzeżenie o niesprawdzony oddanych w save()
. Rzeczywiście, przesyłam od Food<T,S>
do T
.
Pytanie: w jaki sposób mogę zaimplementować ten apple.save()
w sposób bezpieczny?
Nie chcę żadnych symboli zastępczych pojawiających się w kodzie klienta, więc zmiana abstract void setFood(T food);
na abstract <Z extends Food<T,S>> void setFood(Z food);
nie jest rozwiązaniem. (Oczywiście unikam też SupressWarnings("unchecked")
).
Jestem świadomy Java Generics, how to avoid unchecked assignment warning when using class hierarchy?, Generics cast issue i The get-put principle, ale nadal nie mogę się z tym pogodzić.
Z góry dziękuję!
co próbujesz zrobić to odlewania klasa nadrzędna obj to klasie potomnej obj, teraz powinno to być niezaznaczone ostrzeżenie, ale musisz przekazać argument, który rozszerza Food i rzuca go na klasę potomną, jak Apple lub Banana ... Gdybym był tobą, zrobiłbym to void save() { getStorage(). setFood (this);} 'i nadpisanie tej metody w każdej klasie rozszerza jedzenie. tak więcej kodu, ale bardziej solidnego projektu:/ –
Powiązane: [Czy istnieje sposób, aby odnieść się do bieżącego typu ze zmienną typu?] (http://stackoverflow.com/questions/7354740/is-there-a-way- to-refer-to-the-current-type-with-a-type-variable) –
(Dzięki za edycję Andersa) – wehlutyk