Gå til innhold

[Løst] Instansiering ved abstrakt klasse


Anbefalte innlegg

Hei, jeg holder for tiden på med en øving i Java der vi har klasser for en Dyrehage. Den første oppgaven gikk utmerket men i den andre skulle vi gjøre om en av klassene som det er laget ArrayList av i Dyrehager til abstrakt. Siden instansiering ikke er tillatt ved bruk av en abstrakt klasse fungerer ikke metodene lengre, er det noen som har en løsning på hvordan man lager metoden registrerNyArt()?

 

Oppgaven er som følger:

 

 

En dyrehage har et register over alle artene. Hver art er registrert med norsk navn, latinsk navn og familie (latinsk). Vi deler artene inn i to hovedgrupper:

A: De artene der vi ønsker å registrere hvert enkelt individ (eks. bjørn, gorilla, osv.). Om disse artene lagrer vi antall unger, og hvorvidt arten er farlig eller ikke. Det fins mange individer av hver enkelt av disse artene. Hvert individ registreres med individnavn og fødselsdato.

B: De artene der vi forholder oss til grupper av dyr (fiskestimer, fugleflokker, osv.). Om hver gruppe skal vi lagre gruppenavn og omtrentlig antall individer i gruppen.

For enkelthets skyld antar vi nå at alle fisker og fugler tilhører gruppe B. Om fugler skal vi lagre antall egg arten får.

Her er klassediagrammet:

 

figur.png

 

(OBS: Det er ikke trykkfeil at finnArt() står to ganger i klassen Dyrehage, nærmere beskrivelse nedenfor.)

Vi har mye samarbeid her. Eksempel: Et dyrehageobjekt må samarbeide med et individobjekt for å finner fødselsdatoen til et individ.

Med andre ord: En klient som vil vite når "Bamse Brakar" er født sender spørsmålet til dyrehagen. Dyrehagen finner riktig individ (ved å sende en melding til seg selv), og sender spørsmålet videre til dette individ-objektet. Det sender svaret tilbake til dyrehagen, som sender det videre til klienten. Prøv å tegne et sekvensdiagram som viser dette (tegningen skal ikke leveres inn).

Observer at klassen Individ forholder seg til klassen DyrSomIndivider omtrent på samme måte som klassen Gruppe forholder seg til klassen DyrIGrupper.

Kildekode for klassen Art med subklasser er gitt.

Her kommer en detaljering av de tjenestene et objekt av klassen Dyrehage skal tilby (navnene svarer til navnene brukt i klassediagrammet ovenfor):

registrerNyArt(): Metoden skal ta en referanse til Art (eller subklasse av Art) som argument. Den skal returnere false hvis art med dette navn er registrert fra før, ellers skal metoden returnere true.

finnArt(), utgave 1: Metoden skal ta et artsnavn som argument og returnere en referanse til Art dersom art med dette navnet finnes. Hvis ikke returneres null.

finnArt(), utgave 2: Metoden skal ta indeks som argument (indeks i datastrukturen der artene lagres) og returnere en referanse til Art dersom gyldig indeks. Hvis ikke returneres null.

finnAntArter(): Returnerer antall arter registrert.

registrerNyttIndivid(): Metoden tar artsnavn og referanse til Individ-objekt som argumenter. Metoden returnerer false dersom ugyldig artsnavn og/eller individ med samme navn er registrert fra før. Ellers returnerer metoden true.

finnIndivid(): Metoden tar artsnavn og individnavn som argumenter. Metoden returnerer en referanse til det aktuelle Individ-objektet. Hvis et slikt ikke fins, returneres null.

finnFDatoIndivid(): Metoden tar artsnavn og individnavn som argumenter. Metoden returnerer fødselsdatoen til individet. Hvis individet ikke fins, returneres null.

registrerNyGruppe(): Metoden tar artsnavn og referanse til Gruppe-objekt som argumenter. Metoden returnerer false dersom ugyldig artsnavn og/eller gruppe med samme navn er registrert fra før. Ellers returnerer metoden true.

finnGruppe(): Metoden tar artsnavn og gruppenavn som argumenter. Metoden returnerer en referanse til det aktuelle Gruppe-objektet. Hvis et slikt ikke fins, returneres null.

finnAntallIGruppen(): Metoden tar artsnavn og gruppenavn som argumenter. Metoden returnerer antall dyr i gruppen. Hvis ugyldig artsnavn/gruppenavn, returneres -1.

Oppgave 1

Se bort fra alle subklassene til Art. Programmer klassen Dyrehage med de fire øverste metodene. Se detaljert beskrivelse av metodene over.

Lag testprogram.

Oppgave 2

Gjør klassen Art abstrakt. Hva kan grunnen være til at vi gjør denne klassen abstrakt?

Programmer venstre del av diagrammet. Det vil altså si aggregeringen "individer", med alle metoder som er knyttet til denne aggregeringen (det vil bli veldig likt med aggregeringen "grupper"). Du vil nå ha en ny klasse Individ, alle metodene i klassen Dyrehage, unntatt de tre nederste, og alle metodene i klassen DyrSomIndivider.

Utvid toString() i klassen DyrSomIndivider slik at opplysninger om alle individer blir med.

Prøv ut dette med et lite klientprogram.

Tips: Nå vil alle dyr tilhøre klassen DyrSomIndivider. Men - du vet at programmet senere skal utvides med klassen DyrIGrupper. Prøv derfor allerede nå å ta hensyn til forskjellene mellom disse to gruppene. Bruk instanceof for å finne ut om et objekt tilhører den ene eller andre klassen.

 

 

 

Her er min klasse så langt med metoden som ikke fungerer:

 

import java.util.ArrayList;
class Dyrehager{
private ArrayList<Art> arter = new ArrayList<Art>();
private ArrayList<DyrSomIndivider> individer = new ArrayList<DyrSomIndivider>();
private ArrayList<Gruppe> grupper = new ArrayList<Gruppe>();
private String navn;
public Dyrehager(String navn){
 this.navn = navn;
}
public String finnNavn(){
 return navn;
}
public boolean artDuplikat(String norskNavn, String latNavn, String latFamilie){
 boolean duplikat = false;
 for(int i = 0; i < arter.size(); i++){
  if(norskNavn == arter.get(i).getNorskNavn()){
duplikat = true;
  }
 }
 return duplikat;
}
public boolean registrerNyArt(String norskNavn, String latNavn, String latFamilie){
 if(artDuplikat(norskNavn, latNavn, latFamilie) == false){
  arter.add(new Art(norskNavn, latNavn, latFamilie));
  return true;
 }
 throw new IllegalArgumentException("Du prøver å registrere en art som finnes fra før.");
}
public String finnArt(String navn){
 for(Art art : arter){
  if(navn.equals(art.getNorskNavn())) return art.getNorskNavn();
 }
 return null;
}
public String finnArt(int indeks){
 String tekst = "";
 try{
  return arter.get(indeks).toString();
 }
 catch(IndexOutOfBoundsException e){
  tekst += "Det eksisterer ingenting på denne indeksen.";
 }
 return tekst;
}
public int finnAntArter(){
 return arter.size();
}
}
class Dyrehage{
public static void main(String[]args){
 Dyrehager d = new Dyrehager("Da Zoo");
 System.out.println(d.finnNavn());
 d.registrerNyArt("Arne", "Horus", "Horialis");
 d.registrerNyArt("Anne", "Horus", "Horialis");
 d.registrerNyArt("Panne", "Horus", "Horialis");
 System.out.println(d.finnArt("Arne"));
 System.out.println(d.finnArt("Anne"));
 System.out.println(d.finnArt("Panne"));
 System.out.println(d.finnArt("Kanne"));
 System.out.println(d.finnArt(0));
 System.out.println(d.finnArt(1));
 System.out.println(d.finnArt(2));
 System.out.println(d.finnArt(3));
 System.out.println(d.finnAntArter());
}
}

 

Her er klassen Art:

/**
* Klassen Art med subklasser.
* Liten testklient helt til slutt.
* Merk at klassene må utvides for å løse oppgaven.
*/
abstract class Art {
 private final String norskNavn;
 private final String latNavn;
 private final String latFamilie;
 /**
  * Konstruktøren Art: Ingen argumenter kan være null.
  * Ingen krav er satt til nye argumenter som kommer inn i subklassenes konstruktører.
  */
 public Art(String norskNavn, String latNavn, String latFamilie) {
if (norskNavn == null || latNavn == null || latFamilie == null) {
  throw new IllegalArgumentException("Ingen av argumentene til Art-konstruktøren kan være null");
}
this.norskNavn = norskNavn.trim();
this.latNavn = latNavn.trim();
this.latFamilie = latFamilie.trim();
 }
 public String getNorskNavn() {
return norskNavn;
 }
 public String getLatNavn() {
return latNavn;
 }
 public String getLatFamilie() {
return latFamilie;
 }
 public String toString() {
return "Norsk navn: " + norskNavn + ", latinsk navn og familie: " + latNavn
		+ ", " + latFamilie;
 }
}

 

Oppgaven gikk fint helt til Art skulle gjøres abstrakt, noen forslag? På forhånd takk!

Lenke til kommentar
Videoannonse
Annonse

Du kan ikke instansiere Art. Du må arve fra den, og instansiere den arvede klassen. her blir du tvunget til å implementere eventuelle abstrakte funksjoner (programmet vil ikke kompilere før det er gjort).

 

Takk for svar, det stemmer det. Da kom jeg isåfall litt videre. Sliter med metoden finnIndivid(), hvordan får man sjekket artsnavn fra Art mot individnavn fra Individ? Skal man eventuelt ta inn artsnavn i Individklassen?

 

er det sånn her at hvis jeg vil registrere gullfisken min, Wanda, så kan jeg det (DyrSomIndivid), og jeg kan registrere artsnavnet "gullfisk", men det blir aldri noe individ av typen Fisk ... ? Genialt ...

 

Stemmer det, det vil du uansett kunne gjøre når alle klassene er ferdige da det uansett ville vært problematisk å utelukke alle artsnavn som ikke er individer. Da må man isåfall kun tillate visse artsnavn. Det er ofte sånn.

Endret av unbreakable163
Lenke til kommentar

Takk for svar, det stemmer det. Da kom jeg isåfall litt videre. Sliter med metoden finnIndivid(), hvordan får man sjekket artsnavn fra Art mot individnavn fra Individ? Skal man eventuelt ta inn artsnavn i Individklassen?

 

Jeg går ut i fra at du snakker om finnIndivid() i Dyrehage og ikke den i DyrSomIndivider. Uansett, å sjekke artsnavn mot individnavn ville vært fullstendig ulogisk og motstridende mot hva det står i oppgaveteksten, du vil heller sjekke dem hver for seg.

finnIndivid(): Metoden tar artsnavn og individnavn som argumenter. Metoden returnerer en referanse til det aktuelle Individ-objektet. Hvis et slikt ikke fins, returneres null.

 

Her er det viktig og vite hva ett argument er for noe, hvis metoden skal ta inn artsnavn og individnavn som argumenter så betyr det at metodehodet vil se slik ut:

public Individ finnIndivid(String artsnavn, String individnavn)

 

Inni metoden kan du ta i bruk finnArt()-metoden som tar inn artsnavent og deretter ta i bruk DyrSomIndivider sin egen finnIndivid()-metode, denne vil kun trenge å ta inn individnavn.

 

Beklager så mye for lang tekst hvis jeg gikk ut i fra feil metode :p

  • Liker 1
Lenke til kommentar

Tvert i mot ... jeg har aldri sett en gullfisk som ikke har vært en fisk, for ikke å si gullfisk.

 

Jeg mener at programmene ofte blir laget slik at man kan gjøre slike ting, jeg kan jo ha en fisk som individ da det ikke er noen sjekk på det.

 

Jeg går ut i fra at du snakker om finnIndivid() i Dyrehage og ikke den i DyrSomIndivider. Uansett, å sjekke artsnavn mot individnavn ville vært fullstendig ulogisk og motstridende mot hva det står i oppgaveteksten, du vil heller sjekke dem hver for seg.

 

 

Her er det viktig og vite hva ett argument er for noe, hvis metoden skal ta inn artsnavn og individnavn som argumenter så betyr det at metodehodet vil se slik ut:

public Individ finnIndivid(String artsnavn, String individnavn)

 

Inni metoden kan du ta i bruk finnArt()-metoden som tar inn artsnavent og deretter ta i bruk DyrSomIndivider sin egen finnIndivid()-metode, denne vil kun trenge å ta inn individnavn.

 

Beklager så mye for lang tekst hvis jeg gikk ut i fra feil metode :p

 

Så klart, det tenkte jeg ikke på i det hele tatt. Takk for hjelpen.

Lenke til kommentar

Jeg mener at programmene ofte blir laget slik at man kan gjøre slike ting, jeg kan jo ha en fisk som individ da det ikke er noen sjekk på det.

Hva du mener med "slike ting" er ikke godt å vite, men at de fleste programmer kommer med bugs er riktig :-)

 

La oss si at dyrehagedirektøren har godkjent dette designet. Men så oppdager noen av de ansatte at når de søker opp et individuelt dyr som heter "Wanda" så får de ikke vite om det er en loppe eller elefant? Eller fisk? Litt upraktisk, for "Wanda" skal overføres til en annen dyrehage ... trener man en trailer, eller kan man bare putte Wanda i lomma?

 

Forsåvidt helt greit dette, om det faller utenfor systemets bruksområde ...

Endret av quantum
  • Liker 1
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...