Obiekt dziedziczący z klasy abstrakcyjnej, - jak stworzyc go w innej klasie?

0

Witam,
Zastanawiam się nad takim problemem, mam klasę abstrakcyjną, z której dziedziczą 3 inne klasy. Tworzę inny obiekt, który w zależności przechowuje (zawiera) jeden z tych 3 obiektów dziedziczących z klasy abstrakcyjnej. Jak to zrobić? XD
Przykład: Załózmy mam klasę: karta, jest to klasa abstrakcyjna, z której dziedzicza 3 inne klasy, bankomatowa, debetowa, kredytowa. I teraz robie klasę klient i chcę w zależności od wyboru usera obslugujacego program chce aby klient mial jedno z tych trzech kart.
Zastanawiam się czy w klasie klient nie zrobić pola:
private Karta Rodzajkarty;
Tylko czy to jest poprawne rozwiązanie? bo tak jakby oznacza to obiekt klasy abstrakcyjnej, a to jest zabronione.

1

Powinno być mniej więcej tak, przykład w javie.

abstract class Karta {
    public abstract String getName();
}
class KartaKredytowa extends Karta {
    @Override
    public String getName() {
        return 'Karta kredytowa';
    }
}

class KartaDebetowa extends Karta {
    @Override
    public String getName() {
        return 'Karta debetowa';
    }
}
class Klient {
  private Karta karta;
  
  public Klient(Karta karta) {
      this.karta = karta;
  }

  public void printKartaName() {
       System.out.println(karta.getName());
  }
}

Noi jak chcesz sobie korzystać z takich rzeczy to możesz coś w takim stylu

class KartaFactory {
    public static Karta createKarta() {
        switch (jakisInput) {
          case 'kred': return new KartaKredytowa();
          case 'deb': return new KartaDebetowa();
          case 'inna': return new KartaInna();
          default:
            throw new InvalidArgumentException('nie');
        }
    }
}

Karta karta = KartaFactory.createKarta();
Klient klient = new Klient(karta); 

PS: Oczywiście tą klasę KartaFactory możesz sobie zaimplementować jak chcesz.

1

@Blue_Carpet
Nie tworzysz nigdzie obiektu klasy abstrakcyjnej.

Nie możesz stworzyć obiektu klasy abstrakcyjnej dlatego że one mają metody abstrakcyjne. Gdybyś miał obiekt tej klasy i wywołał byś metodę abstrakcyjną kompilator nie wiedziałby co zrobić (metoda nie miałaby ciała). Dlatego instancjonowanie takiej klasy jest zabronione (nie możesz zrobić new Karta()).

Ale jakaś klasa dziedziczy z klasy abstrakcyjnej (np ta "KartaBankomatowa"), to ona już implementuje tą abstrakcyjną metodę i cała klasa już nie jest abstrakcyjna. Metoda ta już ma ciało. Kompilator może sobie ją spokojnie uruchomić i bez przeszkód możesz sobie instancjonować taką klasę (możesz sobie zrobić new KartaBankomatowa()).

Jednak, to że nie możesz stworzyć obiektu takiej klasy nie znaczy że nie możesz mieć obiektów tego typu. Zauważ że np takie coś zadziała:

class Human { public void metodaWspolna() {} }
class Girl extends Human { public void metodaDziewczyny() {} }
class Boy extends Human { public void metodaFaceta() {} }
Human human = new Human();
Girl girl = new Girl();
Boy boy = new Boy();

girl.metodaWspolna();    // działa
boy.metodaWspolna();     // działa
girl.metodaDziewczyny(); // działa
boy.metodaFaceta();      // działa

ale spokojnie zadziała też kod poniżej, tylko tutaj możemy się odwoływać tylko do wspólnej części. Kompilator trzyma oba obiekty w zmiennej typu Human, czyli jest to albo Human, albo Girl albo Boy. Girl i Boy dziedziczą z Human więc można je trzymać w zmiennej typu Human (na pewno mają wszystkie metody które ma też human).

Human human = new Human();
Human girl = new Girl();
Human boy = new Boy();

girl.metodaWspolna();    // działa
boy.metodaWspolna();     // działa
girl.metodaDziewczyny(); // nie działa - kompilator nie wie że girl jest Girl (jest trzymana w zmiennej Human) równie dobrze mógłby być facet, a facet może nie mieć tej metody, kompialtor nie wiedziałby co robić. Dlatego można tylko metodę wspólną.
boy.metodaFaceta();      // nie działa - to samo co wyżej

Teraz, po prostu wyobraź sobie że Human jest abstrakcyjny. Ciągle możemy stworzyć Girl oraz Boy, ponieważ one obie mają ciała. Nie możemy stworzyć human ale to nic. Zmienne typu 'Human human' będę miały albo new Girl() albo new Boy(). Girl i Boy dziedziczą z Human, więc zawsze będą miały metody wspólne (których nie miał human, bo jest abstrakcyjny) więc zawsze będzie można wykonać te metody wspólne.

Czyli podsumowując : Twój kod jest ok.

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