2015-03-13 16 views
5

Mam naprawdę proste pytanie:Klasa abstrakcyjna - Super Konstruktor (Java)

Załóżmy, że mam klasę abstrakcyjną, która reprezentuje osobę na pasku.

public class Person { 
    protected String firstName; 
    protected String lastName; 

    public Person(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 
} 

Mam również 2 klasy, które rozszerzają osobę, powiedzmy klasę dla barmanów i klasę dla klientów.

W klasie dla klientów chcę również int reprezentujący jego wiek jako pole. W klasie barmanów, nie mamy.

Ponadto, dla klasy klienta, chcę metodę isAdult().

public class Bartender extends Person { 
    public Bartender(String firstName, String lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 
} 

public class Customer extends Person { 
private int age;  

    public Customer(String firstName, String lastName, int age) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
     this.age = age; 
    } 
} 

teraz mam 2 pytania: „niejawny Super konstruktor pasażera() jest niezdefiniowane musi jawnie wywołać inny konstruktor”

1) To nie działa jak dostaję komunikat. Co to dokładnie oznacza? 2) Dla isAdult() metoda, czuję się jak najlepszym sposobem na to jest wprowadzenie go w klasie abstrakcyjnej osoba taka jak ta:

public abstract boolean isAdult(); 

a następnie wdrożyć go do Barmanów powracających zawsze prawdziwe i dla Klientów sprawdzanie ich wieku.

Innym sposobem jest wdrożenie go z klasy Osoba bezpośrednio tak:

public boolean isAdult() { 
    return (this instanceof Bartender || age > 18); 
} 

Czy to praca i którędy będzie lepiej?

Odpowiedz

5

Osoba ma zdefiniowany parametr przy użyciu konstruktora i brak domyślnego konstruktora bez parametrów. Ponieważ Super konstruktora klasy podrzędne muszą być zawsze nazywany w konstruktorze dziecka, a ponieważ osoba nie ma domyślnego konstruktora, trzeba wyraźnie nazywają go w konstruktorze dziecko:

public Bartender(String firstName, String lastName) { 
    super(firstName, lastName); 

    // don't do this: 
    // this.firstName = firstName; 
    // this.lastName = lastName; 
} 

i

public Customer(String firstName, String lastName, int age) { 
    super(firstName, lastName); 
    this.age = age; 
} 

Jeśli chodzi o isAdult(), możesz po prostu mieć tę metodę w klasie Klienta i nie mieć jej w Barmanie. Ewentualnie, jeśli super musi mieć tę metodę, możesz rzucić wyjątek, jeśli ktoś zadzwoni na barmana, ponieważ nie powinien być nazywany w ten sposób.

0

Na pierwsze pytanie zauważ coś: podczas tworzenia klasy jest automatycznie tworzony domyślny konstruktor tej klasy. Jeśli utworzysz inny konstruktor, musisz musi utworzyć więc domyślny ("domyślny" tutaj jest bez parametrów) sam, ponieważ Java myśli, że wiesz, co robisz teraz. Tak, wystarczy dodać go w klasie Person:

public Person(){} 
0

Do pierwszego pytania, zobacz Poduszkowiec Pełna odpowiedzi węgorze męska; dla twojego drugiego pytania, myślę, że powinieneś dać Person "wiek" (każda osoba ma wiek) i logiczną implementację isAdult. Jeśli Bartender jest naprawdę Person, powinien mieć wiek. Dlatego nie sądzę, że powinieneś być w stanie założyć, że Bartender jest osobą dorosłą.Niezależnie od tego, jaka masz logikę, która nazywa się Person#isAdult, należy założyć, że true w przypadku, gdy Person jest Bartender.

1

Odpowiedź na 1: Java faktycznie zawsze wywołuje konstruktor nadklasy. Np

class Super{ 
} 

class Base extends Super{ 
    public Base(){ 
      //super() will always be called implicitly if a defaultconstructor is provided by Super 

      //do something else 
    } 
} 

Dzieje się tak, ponieważ struktura klasy bazowej składa się z konstrukcji klasy bazowej i jednej z nadrzędnej. Bez inicjowania struktury superklasy przez wywołanie konstruktora superklasy mogą wystąpić błędy. Ponieważ osoba nie dostarcza domyślnego konstruktora, ale musi zostać zainicjalizowana w każdym razie, musisz jawnie wywołać superkonstruktora z dwoma parametrami.

Odpowiedź 2: Oba działałyby dobrze, ale ja (i wszyscy, jak mam nadzieję) bardzo polecam implementowanie go oddzielnie w klasach pochodnych, aby zachować wszystko rozszerzalne, czyste, czytelne iz tysięcy innych powodów.

0

Druga część pytania: Dokonaj streszczenia isAdult() w klasie nadrzędnej, podaj konkretne implementacje w klasach dla dzieci. Jeśli okaże się, że kilka klas potomnych ma podobną implementację, możesz rozważyć umieszczenie tej implementacji w klasie nadrzędnej i odpowiednio ją zastąpić.

Klasy rodzicielskie nigdy nie powinny wiedzieć o swoich klasach dzieci, dlatego należy unikać sprawdzania przez rodziców dzieci.

Powiązane problemy