Polimorphism z interface/extends

0

Hej,

Mam oto taką hierarchię class i problem z nimi związany, co w nich jest to jest nieważe, coś tam mają w sobie ale nie o to chodzi :) :

// dwa interfejsy
interface Patient;
interface PatientExt extends Patient;

// dwie klasy
class CPatient implements Patient;
class CPatientExt extends CPatient implements PatientExt;

// i problem związany z dodawaniem powyzszych obiektów do mapy, która tak wygląda na chwilę obecną
private HashMap<Integer, ArrayList<? extends Patient>> roomStorage = new HashMap<Integer, ArrayList<PatientExt>>();

nie wiem czy dobrze rozumiem, ale taki zapis dla ArrayList jest:
"PatientExt" extends "Patient"
?

Drugi problem jest z dodawanie czegos to tej mapy, bo krzaczy sie ze nie umie konwersji zrobic:
np. gdy patient jest superklasa Patient

roomStorage.get(room).add(patient);

byłbym wdzieczny jakbyście mnie nakierowali na poprawny to rozumowania :)
Dzięki za pomoc.

3

Trafiłeś na problem Kowariancji i Kontrwariancji.
W uproszczeniu - z typami generycznymi i dziedziczeniem jest tak, że albo łatwo wyciągać... albo łatwo wkładać. Ale ciężko oba naraz (z dziedziczeniem).
ArrayList<? extends Patient> - to znaczy, że jest to lista czegoś co przynajmniej jest Patient (więc np ArrayList<PatientExt> pasuje, bo PatientExt dziedziczy po Patient) . Ale możesz potencjalnie miec też klasę PatientExtAlt (któta też, pechowo, extends Patient.) więc ArrayList<PatientExtAlt> też pasuje.
A kompilator wie tylko, że jest cos co dzidziczy po Patient... ale nie wie co. (Tyle dokładnie oznacza ta deklaracja: ArrayList<? extends Patient>).

Czyli mógłbys w kodzie zrobić tak:

private HashMap<Integer, ArrayList<? extends Patient>> roomStorage = new HashMap<Integer, ArrayList<PatientExt>>();

//a gdzieś chwilkę potem:
private HashMap<Integer, ArrayList<PatientExtAlt>> roomStorageAlternative = new HashMap<Integer, ArrayList<PatientExtAlt>>();
// i jescze chwile potem:

roomStorage =  roomStorageAlternative; 

I to ma ciekawe konsekwencje.

W związku z tym, cokolwiek wyciągasz z tej listy (roomStorage)... to luzik. wiadomo, że to przynajmniej Patient. Fajnie.

Ale pechowo jak chcesz wkładać.. to nie bardzo bo to lista czegoś co dziedziczy po Patient.. ale nie możesz włożyć PatientExt... bo może akutat jest to lista od PatientExtAlt (kompilator nie wie).

Inaczej. Popatrz na ten kod co podałem z podstawieniem. Gdyby kompilator Ci pozwolił wstawić PatientExt.... to co by było w mapie roomStorageAlternative ?
Znalazłby się tam obiekt od czapki (typu PatientExt), nie pasujący do hierarchii dziedziczenia (bo to list PatientExtAlt - a one nie są kompatybilne). Szach mat.

Gdybyś napisał:

private HashMap<Integer, ArrayList<PatientExt>> roomStorage = new HashMap<Integer, ArrayList<PatientExt>>(); to problemu ze wstawieniem do listy byś nie miał.

Ale za to nigdy potem nie podstawisz sobie w kodzie:
roomStorage = new HashMap<Integer, ArrayList<Patient>>();
ani
roomStorage = new HashMap<Integer, ArrayList<PatientExtAlt>>();

A mając kod jak masz ArrayList<? extends Patient> - akurat te podstawienia się da zrobić.

Gdybyś z kolei napisał zupełnie odwrotnie:
private HashMap<Integer, ArrayList<? super PatientExt>> roomStorage = new HashMap<Integer, ArrayList<Patient>>();
To również mógłbyś spokojnie wsadzić tego PatientExt przez add.
ale za to wyciąganie z tej mapy PatientExt będzie trudne (będziesz dostawał typ Object).

Czyli albo rybka albo pipka.

0

Jak wyżej napisał @jarekr000000 dopadły cię tu problemy kowariancji i kontrawariancji typów. Niemniej da się tu coś zaradzić, byleby nie używać ? a zamiast tego generycznie parametryzować te twoje klasy. Popatrz że możesz mieć np.

public class Storage<T extends Patient> {
    private final Map<Integer, List<T>> roomStorage = new HashMap<>();

    public void add(T patient, int room){
        roomStorage.get(room).add(patient);
    }

    public static void main(String[] args){
        Storage<Patient> storage = new Storage<>();
        storage.add(new CPatientExt(),1);
        storage.add(new CPatient(),2);
    }
}

I nigdzie nie ma jakiegoś wielkiego problemu, niemniej musisz pamiętać że w takim zapisie wyciąganie czegokolwiek z listy w tej klasie będzie ograniczone do interfejsu Patient! Wygodniej byłoby jakbyś pokazał konkretnie kod który ci się sypie, bo klasa generyczna i generyczne metody mimo wszystko czasem pozwalają trochę tą sytuacje uratować.

0

Wracając do problemu ma się on następująco:
mam klasę, którą muszę wypełnić:

public class WardExt extends AbstractWardExt { /* impl */ }

i ona ma w sobie

HashMape <Integer, ArrayList< Patient/PatientExt> >  // gdzie Integer to room, a ArrayList to lista pacjentow w tym pokoju

i ta klasa dziedziczy po AbstractWardExt dwie funkcje, które dodają do HashMapy powyżej pacjentów:

patientAdmission(CPatient, int room)  { /* tutaj logika ogranicza sie do sprawdzenia czy pacjent juz istnieje w roomStorage czy nie, jesli nie to go dodajemy */
patientAdmission(CPatientExt, int room) { /* jak wyzej */

w skrócie po prostu dodają do room jakiegoś pacjenta, z tym, że CPatientExt ma informacje o chorobie i tym się tylko różni od CPatient.
Każdy pacjent ma unikatowe ID (zmienna static).
@Shalom mógłbym to zrobić jak powyżej podaliście, ale niestety nie mam tak prosto bo mam już szablon, który muszę wypełnić (WardExt)
Stworzyłem HashMape aby to ogarnąć jak najprościej, tylko cały czas mam te problemy z (incompatible type) jak zrobiłem

 public class WardExt <T extends Patient> extends AbstractWardExt {
   HasMap <Integer, ArrayList< T > > roomStorage = new HashMap< Integer, ArrayList< T > >() ;

   patientAdmission(CPatient patient, int room) {
       roomStorage.get(room).add(patient);      // tutaj sypie errorami
   }
}

mógłbym stworzyć dodatkową klasę, która by ogarnęła roomStorage, a w sobie miała dwie różne listy.
Ale wtedy miałbym problem z jeszcze dodatkowymi funkcjami jakie mam do zaimplementowania, gdzie też by się pojawiły problemy z kompatybilnością typów:

patientDischarge(CPatient)      // tu tylko bazowa klasa do usuwania pacjentów z roomStorage po ID

oraz getPatients który zwraca zbiór CPatient

Set<CPatient> getPatients()

i getAdmissionHistory który zwraca wszystkich pacjentow jaki kolwiek byli obslugiwani przez patientAdmission()

 List<Patient> getAdmissionHistory()

Dlatego kombinuję z różnymi typami dla HashMap aby to zrobić jak najbardziej optymalnie.
Dzięki za pomoc.

0
  1. Podaj kod który powoduje problem i który się kompiluje, bo inaczej nie da się przetestować i powiedzieć o co chodzi!
  2. Nie możesz zrobić tak jak wyżej bo dodawanie / operacje na liście powinny wszędzie używać T a nie konkretnych klas.
    Ty cały czas nie rozumiesz chyba że w javie List<Base> NIE JEST zwiazane w zaden sposób z List<Derived>. Typy generyczne sie w ten sposób nie zachowują. Dlatego trzeba wiązać je parametrami generycznymi bo zupełnie inaczej to wygląda kiedy masz List<T> a T extends Base.
0

@2. Jeszcz nie kminie do końca tych generycznych typów, dla tego takie problemy z tym mam i próbuję je rozkminic :)

@1. Ogólnie mój kod tak wygląda:

// tutaj przy WardExt dodany T extends Patient ale rzuca błedem
 public class WardExt <T extends Patient> extends AbstractWardExt {
	private Map<Integer, Integer> hospitalStorage;  // Map<key=room, value=bed limit>
    private HashMap<Integer, ArrayList<T>> roomStorage;    // Map<key=room, value=list of patients>
    private List<Patient> admissionList;
	
	// mr constructor
	public WardExt() {
		roomStorage = new HashMap<Integer, ArrayList<T>>();
        admissionList = new ArrayList<>();
	}

    @Override
	public void setLimits( Map<Integer, Integer> max ) {
		hospitalStorage = max;

        for (Map.Entry<Integer, Integer> hospitalEntry : hospitalStorage.entrySet()) {
            roomStorage.put(hospitalEntry.getKey(), new ArrayList<>());
        }
	}

@Override
	public boolean patientAdmission( Patient patient, int room ) {
if(roomStorage.containsKey(room) && patient != null) {
			// phase 1, check whether patient exists in any room
			for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
				for(Patient tmpPatient : roomEntry.getValue()) {
					if(tmpPatient.getID() == patient.getID()) {
                        return false;   // no need to add new patient, patient exists
                    }
				}
			}
			
			// phase 2, check room limit
			int roomLimit = hospitalStorage.get(room).intValue();
            int numOfPatientsInSpecificRoom = roomStorage.get(room).size();
            if(numOfPatientsInSpecificRoom >= roomLimit) { 
				return false;  // we don't have place for patient
			}
// phase 3, adding patient to the room
            roomStorage.get(room).add(patient);
			
			// phase 4, adding patient to the history
			admissionList.add(patient);
			return true;
		}
		
		return false;
	}
}

    @Override
	public boolean patientAdmission( PatientExt patient, int room ) {
		if(roomStorage.containsKey(room) && patient != null) {
			// phase 1, check whether patient exists in any room
			for(Map.Entry<Integer, ArrayList<PatientExt>> roomEntry : roomStorage.entrySet()) {
				for(Patient tmpPatient : roomEntry.getValue()) {
					if(tmpPatient.getID() == patient.getID()) {
                        return false;   // no need to add new patient, patient exists
                    }
				}
			}
			
			// phase 2, check room limit
			int roomLimit = hospitalStorage.get(room).intValue();
            int numOfPatientsInSpecificRoom = roomStorage.get(room).size();
            if(numOfPatientsInSpecificRoom >= roomLimit) { 
				return false;  // we don't have place for patient
			}

// phase 3, adding patient to the room
            roomStorage.get(room).add(patient);     // error 
			
			// phase 4, adding patient to the history
			admissionList.add(patient);
			
			return true;
		}
		
		return false;
	}

	@Override
	public boolean patientDischarge( Patient patient ) {
		if(patient != null) {
            for(Map.Entry<Integer, ArrayList<PatientExt>> roomEntry : roomStorage.entrySet()) {
                for(Patient tmpPatient : roomEntry.getValue()) {
                    if(tmpPatient.getID() == patient.getID()) {
                        roomStorage.get(roomEntry.getKey()).remove(tmpPatient);
                        return true;
                    }
                }
            }
        }

        return false;
	}

	public Set<Patient> getPatients() {
		List<Patient> tmpList = new ArrayList<Patient>();
			
		for(Map.Entry<Integer, ArrayList<PatientExt>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
				tmpList.add(tmpPatient);
			}
		}
			
		// sorting 
		Collections.sort(tmpList, new Comparator<Patient>() {
			@Override
			public int compare(Patient o1, Patient o2) {
					Integer p1_age = new Integer(o1.getAge());
					Integer p2_age = new Integer(o2.getAge());
					
					if ( p1_age > p2_age ) {
						return 1;
					} else if ( p1_age < p2_age ) {
						return -1;
					} else {
						return 0;
					}
				}
		});
			
		Set<Patient> tmpSet = new LinkedHashSet<Patient>();
			
		for(Patient tmpPatient : tmpList) {
			tmpSet.add(tmpPatient);
		}
			
		return tmpSet;		
	}
	
    @Override
	public Set<Patient> getPatients( int room ) {
        if(roomStorage.containsKey(room)) {
			List<Patient> tmpList = new ArrayList<Patient>();
			
			for(Patient tmpPatient : roomStorage.get(room)) {
				tmpList.add(tmpPatient);
			}
			
			// sorting 
			Collections.sort(tmpList, new Comparator<Patient>() {
				@Override
				public int compare(Patient o1, Patient o2) {
					Integer p1_age = new Integer(o1.getAge());
					Integer p2_age = new Integer(o2.getAge());
					
					if ( p1_age > p2_age ) {
						return 1;
					} else if ( p1_age < p2_age ) {
						return -1;
					} else {
						return 0;
					}
				}
			});
			
			Set<Patient> tmpSet = new LinkedHashSet<Patient>();
			
			for(Patient tmpPatient : tmpList) {
				tmpSet.add(tmpPatient); 
			}

			return tmpSet;
        }

        return null;
	}

    @Override
	public Map<Integer, Integer> getRoomsState() {
        Map<Integer, Integer> roomState = new HashMap<>();

        for(Map.Entry<Integer, ArrayList<PatientExt>> roomEntry : roomStorage.entrySet()) {
            roomState.put(roomEntry.getKey(), roomEntry.getValue().size());
        }
        return roomState;		
	}
	
	public List<Patient> getAdmissionHistory() {
		return admissionList;
	}
 public interface Patient {
	long getID();
	int getAge();
}

// obsluga choroby jeszcze nie zaimplementowana
public interface PatientExt extends Patient {
	public enum IsolationLevel {
		FULL, NOT_REQUIRED, COMPARE_DISEASE_CODE;
	}
	public IsolationLevel getIsolationLevel();
	public long getDiseaseCode();
}
0

Nie do końca rozumiem tój problem
A gdybyś tak centralnie olał te generyki - to co by było źle?


public class WardExt  extends AbstractWardExt {
   private Map<Integer, Integer> hospitalStorage;  // Map<key=room, value=bed limit>
   private HashMap<Integer, ArrayList<Patient>> roomStorage;    // Map<key=room, value=list of patients>
   private List<Patient> admissionList;

   // mr constructor
   public WardExt() {
      roomStorage = new HashMap<>();
      admissionList = new ArrayList<>();
   }

   @Override
   public void setLimits( Map<Integer, Integer> max ) {
      hospitalStorage = max;

      for (Map.Entry<Integer, Integer> hospitalEntry : hospitalStorage.entrySet()) {
         roomStorage.put(hospitalEntry.getKey(), new ArrayList<>());
      }
   }

   @Override
   public boolean patientAdmission( Patient patient, int room ) {
      if(roomStorage.containsKey(room) && patient != null) {
         // phase 1, check whether patient exists in any room
         for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
               if(tmpPatient.getID() == patient.getID()) {
                  return false;   // no need to add new patient, patient exists
               }
            }
         }

         // phase 2, check room limit
         int roomLimit = hospitalStorage.get(room).intValue();
         int numOfPatientsInSpecificRoom = roomStorage.get(room).size();
         if(numOfPatientsInSpecificRoom >= roomLimit) {
            return false;  // we don't have place for patient
         }
// phase 3, adding patient to the room
         roomStorage.get(room).add(patient);

         // phase 4, adding patient to the history
         admissionList.add(patient);
         return true;
      }

      return false;
   }
}

   @Override
   public boolean patientAdmission( PatientExt patient, int room ) {
      if(roomStorage.containsKey(room) && patient != null) {
         // phase 1, check whether patient exists in any room
         for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
               if(tmpPatient.getID() == patient.getID()) {
                  return false;   // no need to add new patient, patient exists
               }
            }
         }

         // phase 2, check room limit
         int roomLimit = hospitalStorage.get(room).intValue();
         int numOfPatientsInSpecificRoom = roomStorage.get(room).size();
         if(numOfPatientsInSpecificRoom >= roomLimit) {
            return false;  // we don't have place for patient
         }

// phase 3, adding patient to the room
         roomStorage.get(room).add(patient);     // error

         // phase 4, adding patient to the history
         admissionList.add(patient);

         return true;
      }

      return false;
   }

   @Override
   public boolean patientDischarge( Patient patient ) {
      if(patient != null) {
         for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
               if(tmpPatient.getID() == patient.getID()) {
                  roomStorage.get(roomEntry.getKey()).remove(tmpPatient);
                  return true;
               }
            }
         }
      }

      return false;
   }

   public Set<Patient> getPatients() {
      List<Patient> tmpList = new ArrayList<Patient>();

      for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
         for(Patient tmpPatient : roomEntry.getValue()) {
            tmpList.add(tmpPatient);
         }
      }

      // sorting
      Collections.sort(tmpList, new Comparator<Patient>() {
         @Override
         public int compare(Patient o1, Patient o2) {
            Integer p1_age = new Integer(o1.getAge());
            Integer p2_age = new Integer(o2.getAge());

            if ( p1_age > p2_age ) {
               return 1;
            } else if ( p1_age < p2_age ) {
               return -1;
            } else {
               return 0;
            }
         }
      });

      Set<Patient> tmpSet = new LinkedHashSet<Patient>();

      for(Patient tmpPatient : tmpList) {
         tmpSet.add(tmpPatient);
      }

      return tmpSet;
   }

   @Override
   public Set<Patient> getPatients( int room ) {
      if(roomStorage.containsKey(room)) {
         List<Patient> tmpList = new ArrayList<Patient>();

         for(Patient tmpPatient : roomStorage.get(room)) {
            tmpList.add(tmpPatient);
         }

         // sorting
         Collections.sort(tmpList, new Comparator<Patient>() {
            @Override
            public int compare(Patient o1, Patient o2) {
               Integer p1_age = new Integer(o1.getAge());
               Integer p2_age = new Integer(o2.getAge());

               if ( p1_age > p2_age ) {
                  return 1;
               } else if ( p1_age < p2_age ) {
                  return -1;
               } else {
                  return 0;
               }
            }
         });

         Set<Patient> tmpSet = new LinkedHashSet<Patient>();

         for(Patient tmpPatient : tmpList) {
            tmpSet.add(tmpPatient);
         }

         return tmpSet;
      }

      return null;
   }

   @Override
   public Map<Integer, Integer> getRoomsState() {
      Map<Integer, Integer> roomState = new HashMap<>();

      for(Map.Entry<Integer, ArrayList<Patient>> roomEntry : roomStorage.entrySet()) {
         roomState.put(roomEntry.getKey(), roomEntry.getValue().size());
      }
      return roomState;
   }

   public List<Patient> getAdmissionHistory() {
      return admissionList;
   }
0

funkcja patientAdmission() nie umiała dodać Patient do mapy:

private HashMap<Integer, ArrayList<Patient>> roomStorage;    // Map<key=room, value=list of patients>

roomStorage.get(room).add(patient); // ok jak patient to Patient
roomStorage.get(room).add(patient); // incompatibile types bo patient to PatientExt

tak czy tak mi wywalalo blad :/

0

Dziwne... U mnie działa :-)
Do listy Patient możesz jak najbardziej dodać obiekt typu PatientExt

0

A na odwrót jak HashMap ma liste PatientExt też ? :)

Poza tym później już się krzaczy, jak trzeba np wyciągnąć liste PatientExt z listy która jest Patient w HashMap :)

0

No właśnie to jest ten problem - biznesowy, którego nie rozumiem.
Czemu chcesz mieć liste PatientExt ?

Jak chcesz mieć generyczną klasy implementujące - dobrą dla Patient a i dobrą dla PatientExt to musisz to zrobić mniej więcej tak:

// tutaj przy WardExt dodany T extends Patient ale rzuca błedem
public class WardExt <T extends Patient> extends AbstractWardExt {
   private Map<Integer, Integer> hospitalStorage;  // Map<key=room, value=bed limit>
   private HashMap<Integer, ArrayList<T>> roomStorage;    // Map<key=room, value=list of patients>
   private List<Patient> admissionList;

   // mr constructor
   public WardExt() {
      roomStorage = new HashMap<Integer, ArrayList<T>>();
      admissionList = new ArrayList<>();
   }

   @Override
   public void setLimits( Map<Integer, Integer> max ) {
      hospitalStorage = max;

      for (Map.Entry<Integer, Integer> hospitalEntry : hospitalStorage.entrySet()) {
         roomStorage.put(hospitalEntry.getKey(), new ArrayList<>());
      }
   }


   @Override
   public boolean patientAdmission( T patient, int room ) {
      if(roomStorage.containsKey(room) && patient != null) {
         // phase 1, check whether patient exists in any room
         for(Map.Entry<Integer, ArrayList<T>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
               if(tmpPatient.getID() == patient.getID()) {
                  return false;   // no need to add new patient, patient exists
               }
            }
         }

         // phase 2, check room limit
         int roomLimit = hospitalStorage.get(room).intValue();
         int numOfPatientsInSpecificRoom = roomStorage.get(room).size();
         if(numOfPatientsInSpecificRoom >= roomLimit) {
            return false;  // we don't have place for patient
         }

// phase 3, adding patient to the room
         roomStorage.get(room).add(patient);     // error

         // phase 4, adding patient to the history
         admissionList.add(patient);

         return true;
      }

      return false;
   }

   @Override
   public boolean patientDischarge( T patient ) {
      if(patient != null) {
         for(Map.Entry<Integer, ArrayList<T>> roomEntry : roomStorage.entrySet()) {
            for(Patient tmpPatient : roomEntry.getValue()) {
               if(tmpPatient.getID() == patient.getID()) {
                  roomStorage.get(roomEntry.getKey()).remove(tmpPatient);
                  return true;
               }
            }
         }
      }

      return false;
   }

   public Set<T> getPatients() {
      List<T> tmpList = new ArrayList<T>();

      for(Map.Entry<Integer, ArrayList<T>> roomEntry : roomStorage.entrySet()) {
         for(T tmpPatient : roomEntry.getValue()) {
            tmpList.add(tmpPatient);
         }
      }

      // sorting
      Collections.sort(tmpList, new Comparator<Patient>() {
         @Override
         public int compare(Patient o1, Patient o2) {
            Integer p1_age = new Integer(o1.getAge());
            Integer p2_age = new Integer(o2.getAge());

            if ( p1_age > p2_age ) {
               return 1;
            } else if ( p1_age < p2_age ) {
               return -1;
            } else {
               return 0;
            }
         }
      });

      Set<T> tmpSet = new LinkedHashSet<T>();

      for(T tmpPatient : tmpList) {
         tmpSet.add(tmpPatient);
      }

      return tmpSet;
   }

   @Override
   public Set<T> getPatients( int room ) {
      if(roomStorage.containsKey(room)) {
         List<T> tmpList = new ArrayList<T>();

         for(Patient tmpPatient : roomStorage.get(room)) {
            tmpList.add(tmpPatient);
         }

         // sorting
         Collections.sort(tmpList, new Comparator<T>() {
            @Override
            public int compare(Patient o1, Patient o2) {
               Integer p1_age = new Integer(o1.getAge());
               Integer p2_age = new Integer(o2.getAge());

               if ( p1_age > p2_age ) {
                  return 1;
               } else if ( p1_age < p2_age ) {
                  return -1;
               } else {
                  return 0;
               }
            }
         });

         Set<T> tmpSet = new LinkedHashSet<T>();

         for(T tmpPatient : tmpList) {
            tmpSet.add(tmpPatient);
         }

         return tmpSet;
      }

      return null;
   }

   @Override
   public Map<Integer, Integer> getRoomsState() {
      Map<Integer, Integer> roomState = new HashMap<>();

      for(Map.Entry<Integer, ArrayList<T>> roomEntry : roomStorage.entrySet()) {
         roomState.put(roomEntry.getKey(), roomEntry.getValue().size());
      }
      return roomState;
   }

   public List<Patient> getAdmissionHistory() {
      return admissionList;
   }
}

BTw. pomijam, że kod, delikatnie ujmując, można "uprościć". Ale najpierw trzeba wyjaśnić co właściwie chcesz osiągnąć.

0

Popróbuje z sugestiami, a chcę osiągnąc poprawne wpisywanie/czytanie Patient i PatientExt do tej/z tej HashMapy w dużym skrócie ;)

0

Więc jeszcze raz - jeśli masz HashMapę<CośTam, Patient> czy tez hashMap<CośtTam, List<Patient>> - to jak najbardziej możesz tam wpisywać Patient i PatientExt.
Żadne twoje generyki Ci nie są potrzebne. I to w prostych przypadkach wystarcza.

Gorzej jak chcesz "ładnie" wyciągnąć PatientExt.

0

@jackoi jeśli musisz gdzieś wyciągać z List<Patient> obiekty PatientEx to znaczy ze poważnie coś zwaliłeś w designie i problem nie jest w generykach tylko pomiędzy monitorem i krzesłem...
Niemniej ja nadal nie rozumiem gdzie jest twój problem konkretnie. Potrafisz pokazać konkretny kod który się nie kompiluje?

0

@Shalom już podawałem wcześniej, w zadaniu które musze napisać mam obsługiwać Patient i PatientExt, a funkcje które zwracają liste pacjetnów to zwracają Set<Patient> i List<Patient>

0

No ok ale to NIE POWODUJE żadnych problemów. Do List<Patient> możesz dodać zarówno Patient jak i dowolną jego podklasę. Więc jeszcze raz pytam: gdzie jest problem? Pokaż kod który nie działa bo póki co dyskusja jest bezcelowa...

0

@Shalom
chyba problem ogarnąłem i mi już się to w końcu kompiluje z taką mapą:

HashMap<Integer, ArrayList<Patient>> = new HashMap<Integer, ArrayList<Patient>>

działa i dodaje Patient i PatientExt

teraz jeszcze ogarne PatientExt z jego dodatkowymi właściwościami i powinno być git.
Takze jak na razie dzięki za pomoc, jak coś znów mi się wykrzaczy to dodam cały kod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1