Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Expand
titleDel 4 – Arv (15%)

I denne delen skal du bruke arv for å håndtere ulike typer svar på en ryddigere måte. Det skal være én klasse for frie tekst-svar kalt StringQuestion, en klasse for tekst-svar med svar-alternativer kalt StringOptionsQuestion, og en klasse for ja/nei-spørsmål kalt BooleanQuestion. Det som er felles for disse klassene, f.eks. håndtering av selve spørsmålsteksten, skal samles i Question-superklassen. Bortsett fra at Question-klassen ikke skal kunne instansieres, så skal bruken av den være som i del 3, inkludert de to askQuestion- og checkQuestion-metodene fra del 2. Prøv å strukturere klassene dine, så det blir minst mulig duplisert kode. Du står selvsagt fritt til å definere andre metoder som trengs i løsningen din.

 En del av koden vil være lik tidligere kode. Du kan selv velge om du vil skrive den på nytt, eller beskrive presist hvordan tidligere skrevet kode(tekst) kopieres inn i de nye klassene.

Oppgave a)

 Implementer først Question-superklassen og de tre klassene StringQuestion, StringOptionsQuestion og BooleanQuestion kun med konstruktører.

Expand
titleLF

 Her er det viktig å identifisere at Question-klassen bør være abstrakt og deklarere både askQuestion- og checkAnswer (abstrakt). Question-klassen bør ha en konstruktør for å sette spørsmålet og implementere askQuestion. Subklassene må ta inn spørsmålet i sine konstruktører og bruke super(…) for å sette spørsmålet. Koden forøvrig bør være omtrent den samme som i del 2.

Code Block
languagejava
themeEclipse
public abstract class Question {
	private String question;
	protected Question(String question) {
		this.question = question;
	}
	public void askQuestion(PrintStream out) {
		out.println(question);
	}
	
	public abstract boolean checkAnswer(String answer);
}
public class StringQuestion extends Question {
	private String answer;
	
	public StringQuestion(String question, String answer) {
		super(question);
		this.answer = answer;
	}
	@Override
	public boolean checkAnswer(String answer) {
		return this.answer.equals(answer);
	}
}

Vi har her valgt å arve fra StringQuestion, for å gjenbruke mest mulig logikk.

Code Block
languagejava
themeEclipse
public class StringOptionsQuestion extends StringQuestion {
	private List<String> options;
	
	public StringOptionsQuestion(String question, String answer, Collection<String> options) {
		super(question, answer);
		if (! options.contains(answer)) {
			throw new IllegalArgumentException("Svaret er ikke et av alternativene!");
		}
		this.options = new ArrayList<String>(options);
	}
	@Override
	public void askQuestion(PrintStream out) {
		super.askQuestion(out);
		int num = 1;
		for (String option : options) {
			out.println(num + ". " + option);
			num++;
		}
	}
	@Override
	public boolean checkAnswer(String answer) {
		try {
			int num = Integer.valueOf(answer);
			if (thissuper.answer.equalscheckAnswer(options.get(num - 1))) {
				return true;
			}
		} catch (IndexOutOfBoundsException e) {
		} catch (NumberFormatException e) {
		}
		return super.checkAnswer(answer);
	}
}

Denne klassen bør passe på å bruke boolean for å lagre svaret.

Code Block
languagejava
themeEclipse
public class BooleanQuestion extends Question {
	
	private boolean answer;
	public BooleanQuestion(String question, boolean answer) {
		super(question);
		this.answer = answer;
	}
	@Override
	public boolean checkAnswer(String answer) {
		return (this.answer ? "ja" : "nei").equals(answer);
	}
}

 

Oppgave b)

 Implementer de to metodene askQuestion og checkAnswer, slik at alle Question-objekter (egentlig instanser av en av de tre andre klassene) i praksis virker som i del 2.

Expand
titleLF

Løsningen er vist over.

 

Oppgave c)

 Reimplementer metoden i Quiz for for innlesing av spørsmål fra fil, slik at den virker med de nye Question-subklassene.

Expand
titleLF

 Her er det stor sett samme kode som i del 3, men merk at en må instansiere de ulike subklassene til Question og vite når de ulike variantene skal brukes. Det er greit å referere til tidligere skrevet kode, for å spare tid og plass.

Code Block
languagejava
themeEclipse
public void init(Reader input) throws IOException {
	BufferedReader reader = new BufferedReader(input);
	while (reader.ready()) {
		String question = reader.readLine();
		if (question == null || question.trim().length() == 0) {
			break;
		}
		String answer = reader.readLine();
		Collection<String> options = new ArrayList<String>();
		while (reader.ready()) {
			String line = reader.readLine();
			if (line == null || line.trim().length() == 0) {
				break;
			}
			options.add(line);
		}
		if (answer.equals("ja") && options.size() == 0) {
			addQuestion(new BooleanQuestion(question, true));
		} else if (answer.equals("nei")") && options.size() == 0) {
			addQuestion(new BooleanQuestion(question, false));
		} else if (options.size() > 0) {
			addQuestion(new StringOptionsQuestion(question, answer, options));
		} else {
			addQuestion(new StringQuestion(question, answer));
		}
	}
}

Lenke til løsningskode: Question.java, BooleanQuestion.java, StringQuestion.java, StringOptionsQuestion.java, Quiz.java (og eksempelfila sample.txt)

 

...