Gender-klassen (vedlegg 1) representerer kjønnet til en person, i denne oppgaven begrenset til mann og kvinne. Klassen skal kodes slik at det ikke skal være mulig å ha andre Gender-objekter enn disse to kjønnene. En Gender-instans har et forklarende ord/navn knyttet til seg, som settes når instansen lages, og som ikke skal være direkte tilgjengelig fra andre klasser. Oppgave a)Hvilke modifikatorer bør stå foran deklarasjonen av label-feltet og konstruktøren? Begrunn svaret. Expand |
---|
| Begge disse bør være markert som private, siden de ikke skal være tilgjengelig utenfor klassen. label bør også være final, siden den ikke skal kunne endres. |
Oppgave b)Hvordan er klassen kodet så det forklarende ordet/navnet vises ved utskrift, f.eks. med System.out.println(...)? Expand |
---|
| Ved utskrift så brukes implisitt toString()-metoden, som er implementert og returnerer label. |
Oppgave c)Fullfør valueOf-metoden. Expand |
---|
| Her er det viktig å returnere et eksisterende Gender-objekt, ved å sammenligne argumentet med label-verdien i de to konstantene MALE og FEMALE. En kan også bruke switch, som i Java 8 virker med String-objekter. valueOf ligner på Integer.valueOf og Double.valueOf og må være static, siden det er unaturlig og unødvendig å kalle den på en eksisterende instans. Code Block |
---|
public static Gender valueOf(String label) {
if (MALE.label.equals(label)) {
return MALE;
} else if (FEMALE.label.equals(label)) {
return FEMALE;
}
return null;
} |
|
Person-klassen (vedlegg 1) representerer en person, med et navn (String) og et kjønn (Gender). Navnet settes kun ved opprettelsen, mens kjønnet kan settes når som helst. For å håndtere familieforhold så har et Person-objekt data om mor, far og barn. addChild-metoden brukes for å knytte et barn til en forelder, og det er ikke spesifisert andre metoder som endrer barn-forelder-koblingen. addChild både registrerer barnet og setter barnets kobling til mor eller far, avhengig av kjønnet til forelderen. Ta f.eks. kallet chris.addChild(pat), hvor pat blir registert som barnet til chris. Hvis chris er mann, så blir han registrert som pat sin far, mens hvis chris er kvinne, så blir hun registrert som pat sin mor. Oppgave d)Skriv felt, metoder og konstruktør for innkapsling av navn, kjønn, mor, og far. Bruk name, gender, mother og father som grunnlag for navngiving. Expand |
---|
| Her er litt av poenget at en må ha en konstruktør som setter navnet og utelate set-metoder for name, mother og father. Code Block |
---|
private final String name;
private Gender gender = null;
private Person father, mother;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public Gender getGender() {
return gender;
}
public void setGender(Gender gender) {
this.gender = gender;
}
public Person getMother() {
return mother;
}
public Person getFather() {
return father;
} |
|
Oppgave e)Implementer getChildCount, hasChild og getChildren, med nødvendig(e) felt. Expand |
---|
| Her må en ha riktig deklarasjon av feltet (helst Collection, sekundært List), og huske å initialisere feltet. getChildren må passe på å returnere en ny Collection, så annen kode ikke får tilgang til interne data. En må ta høyde for at gender kan være null. En kan gjerne bruke Stream-teknikken. Code Block |
---|
private Collection<Person> children = new ArrayList<>();
public int getChildCount() {
return children.size();
}
public boolean hasChild(Person child) {
return children.contains(child);
}
// alternativ
public boolean hasChild(Person child) {
return child.getFather() == this || child.getMother() == this;
}
public Collection<Person> getChildren(Gender gender) {
Collection<Person> result = new ArrayList<>();
for (Person child : children) {
if (gender == null || child.getGender() == gender) {
result.add(child);
}
}
return result;
} |
|
Oppgave f)Som en del av innkapslingen av barn-koblingen, så har vi valgt å la Person implementere Iterable<Person>-grensesnittet. Hva betyr dette for koden en kan skrive for å gå gjennom barna til en Person? Implementer metoden(e) som er påkrevd av dette grensesnittet. Expand |
---|
| Hvis en klasse implementerer Iterable, så kan referanser til denne klassen brukes på høyresiden av kolonet i en for-each-løkke, f.eks. for (Person child : person). Se også getChildren-koden over. Et (litt mindre relevant, og ikke påkrevd) alternativ er Iterable.forEach(Consumer<Person>). Dette er en såkalt default-metode (kom ikke frem i vedlegget) som en får gratis når en implementerer Iterable. Code Block |
---|
@Override
public Iterator<Person> iterator() {
return children.iterator();
} |
|
Oppgave g)Implementer addChild-metoden, basert på kravene beskrevet over og i vedlegg 1, og kravene som implisitt testes av testAddChild i PersonTest-klassen (vedlegg 1). Expand |
---|
| Code Block |
---|
public void addChild(Person child) {
if (getGender() == Gender.MALE) {
if (child.father != null) {
child.father.children.remove(child);
}
child.father = this;
} else if (getGender() == Gender.FEMALE) {
if (child.mother != null) {
child.mother.children.remove(child);
}
child.mother = this;
}
children.add(child);
} |
|
Oppgave h) |