Commit d62582e3 authored by Jostein Hjortland Tysse's avatar Jostein Hjortland Tysse
Browse files
parents 9ca48b27 036b0ac6
package uke12.listener.stocks_forelesning;
public class Observer implements IObserver{
public Observer(Observable observable) {
observable.addObserver(this);
}
public void update(Observable observable, String name) {
System.out.println("Ny endring i "+name+": "+
observable.getStockValue(name));
}
}
package uke12.listener.stocks_forelesning;
public class RunMe {
public static void main(String[] args) {
Observable observable = new Observable();
Observer observer = new Observer(observable);
observable.updateStock("Equinoor", 500);
observable.updateStock("Equinoor", 50);
observable.updateStock("Frosta skotthyll&poff", 50);
}
}
package uke12.extra_listener;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
public class FileObserver implements IObserver {
IObservable iObservable = new Observable();
public FileObserver(IObservable observable) {
this.iObservable = observable;
observable.addObserver(this);
}
@Override
public void update(IObservable observable, String name) {
try (PrintWriter printWriter = new PrintWriter(new BufferedWriter(new FileWriter("Fil.txt", true)))) {
printWriter.print("Lagret ny aksje: "+name+" ("+observable.getStock(name)+")\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
package uke12.extra_listener;
public interface IObservable {
public void updateStock(String name, double value);
public void addObserver(IObserver observer);
public void removeObserver(IObserver observer);
public double getStock(String name);
}
package uke12.extra_listener;
public interface IObserver {
public void update(IObservable observable, String name);
}
package uke12.extra_listener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Random;
public class Observable implements IObservable, Runnable{
Collection<IObserver> observers = new ArrayList<>();
HashMap<String, Double> stocks = new HashMap<>();
Random random = new Random();
@Override
public double getStock(String name) {return stocks.get(name);}
public void updateStock(String name, double value) {
stocks.put(name, stocks.getOrDefault(name, 0.0) + value);
notifyListener(name);
}
private void notifyListener(String name) {
for (IObserver observer : observers) {
observer.update(this, name);
}
}
@Override
public void removeObserver(IObserver observer) {
this.observers.remove(observer);
}
@Override
public void addObserver(IObserver observer) {
this.observers.add(observer);
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(1000);
List<String> names = List.of("Equinoor", "DnBee", "Slemdal Skotthyllforening ASA");
double moneys = random.nextDouble(10)-5;
updateStock(names.get(random.nextInt(names.size())), moneys);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
package uke12.extra_listener;
import java.text.DecimalFormat;
public class PrintObserver implements IObserver{
IObservable observable;
DecimalFormat df = new DecimalFormat("##.#");
public PrintObserver(IObservable observable) {
this.observable = observable;
observable.addObserver(this);
}
@Override
public void update(IObservable observable, String name) {
System.out.println(name+": "+df.format(observable.getStock(name)));
}
}
package uke12.listener_forelesning;
// Eksempelet er litt utvidet fra forelesning, og dekker interface av begge typer.
public class RunMe {
public static void main(String[] args) {
Observable observable = new Observable();
PrintObserver observer = new PrintObserver(observable);
FileObserver fileObserver = new FileObserver(observable);
observable.updateStock("Equinoor", 500);
observable.updateStock("Equinoor", 50);
observable.updateStock("Frosta SkottHyllLag", 50);
Thread thread = new Thread(observable);
thread.start();
System.out.println("Da venter vi!");
}
}
package uke13.abstrakt.bok;
public abstract class Bok {
private String tittel;
private int antallSider;
protected Bok(String tittel, int antallSider) {
super();
this.tittel = tittel;
this.antallSider = antallSider;
}
protected String toStringHelper() {
return "tittel=" + tittel + ", antallSider=" + antallSider;
}
@Override
public String toString() {
return getSjanger() + "[" + toStringHelper() + "]";
}
protected abstract String getSjanger();
public String getTittel() {
return tittel;
}
public int getAntallSider() {
return antallSider;
}
public static void main(String[] args) {
var roman = new Roman("Kurt koker hodet", 65); // Her støtter vi dog at forfatter er null...
System.out.println(roman);
var roman2 = new Roman("Kurt koker hodet", 65, "Erlend Loe");
System.out.println(roman2);
Bok bok = new Tegneseriealbum("Maus", 295);
System.out.println(bok);
}
}
package uke13.abstrakt.bok;
public class Roman extends Bok {
private String forfatter;
public Roman(String tittel, int antallSider) {
super(tittel, antallSider);
}
public Roman(String tittel, int antallSider, String forfatter) {
super(tittel, antallSider);
this.forfatter = forfatter;
}
protected String getSjanger() {
return "Roman";
}
protected String toStringHelper() {
return "forfatter=" + forfatter + ", " + super.toStringHelper();
}
}
package uke13.abstrakt.bok;
public class Tegneseriealbum extends Bok {
public Tegneseriealbum(String tittel, int antallSider) {
super(tittel, antallSider);
}
@Override
protected String getSjanger() {
return "Tegneseriealbum";
}
}
package uke13.arv;
import java.util.ArrayList;
import java.util.Collection;
public class Biblioteksprogram {
public static void main(String[] args) {
Bok bok = new Bok("Vanlig bok");
Bok bok2 = new Bok("Uvanlig bok");
Ordbok ordbok = new Ordbok("Nynorsk ordbok",12431);
Tegneseriealbum tegneseriealbum = new Tegneseriealbum("Asterix",250);
/*
* Lager en Collection samling som tar imot alle typer Bok, enten
* de er Bok eller subklasser av Bok. Legg merke til at når en skriver ut
* toString() av alle versjonene så skrives informasjon også om antallOrd
* og antallStriper ut, siden Bok.toString kaller GetToStringAttributes.
* Denne metoden skygges over i subklassene, og håndterer både superklassen
* sin informasjon gjennom super.GetToStringAttributes samt sine egne variable!
*/
Collection<Bok> samling = new ArrayList<>();
samling.add(bok);
samling.add(bok2);
samling.add(ordbok);
samling.add(tegneseriealbum);
// Gammel måte å skrive ut bøkene i samlingen:
System.out.println("For-løkke:");
for (Bok sluttBok : samling) {
System.out.println(sluttBok); // Kaller Bok.toString(). Se nedenfra!
}
// Streamsmåte å skrive ut alle bøkene:
System.out.println("\nStreams:");
samling.forEach(System.out::println);
// Filtrere ut bøkene som er ordbøker, caste dem til
// Ordbok for å gjøre synlig flere metoder, og skrive
// ut antall ord. På streamsmåten:
System.out.print("\nOrdboka i samlingen har så mange ord: ");
samling.stream()
.filter(b -> b instanceof Ordbok)
.map(b -> (Ordbok) b)
.forEach(b -> System.out.println(b.getAntallOrd()));
// Denne skal feile når den kommenteres ut:
// var foo = new SluttOrdbok("tittel",12);
// System.out.println(foo);
// En boktittel som feiler fordi den inneholder et tegn som ikke er lovlig:
// SluttBok feilbok = new SluttBok("Denne tittelen sk@l utløse unntak");
/*
* For å vise hvordan typen til en variabel og det faktiske objektet
* fungerer lager vi en Bok som instansieres av en Ordbok. Da får vi ikke
* tilgang på antallOrd så lenge en ikke gjør om objektet (caster) til
* en Ordbok. Da bør vi først sjekke om objektet er en instanceOf Ordbok:
*/
Bok casteBok = new Ordbok("Engelsk-norsk ordbok",44443);
System.out.print("Tittel: "+casteBok.getTittel()); // Det går fint, filteret er Bok.
if (casteBok instanceof Ordbok) {
System.out.println(", antall ord: "+((Ordbok)casteBok).getAntallOrd()); // Nå går det!
}
}
}
package uke13.arv;
public class Bok {
private String tittel;
private String specialCharacters = " -,.%";
private String ulovligeBokstaver = "#¤([]){]}";
@Override
public String toString() {
// Den første skriver bare ut for bok. Men dersom du lager en
// ny metode, kaller den, og den kan skygges over av subklasser,
// da kan en ende opp med en fin løsning. Når du kaller toString
// på en Ordbok vil den ende opp i Bok.toString() siden Ordbok ikke
// implementerer denne. Kallet vil allikevel rutes tilbake til
// Ordbok.GetToStringAttributes()!
// return "Bok [tittel=" + tittel + "]";
return GetToStringAttributes();
}
protected String GetToStringAttributes() {
return "tittel=" + tittel; }
public Bok() {
super();
}
public Bok(String tittel) {
setTittel(tittel);
}
public String getTittel() {
return tittel;
}
public void setTittel(String tittel) {
// System.out.println("Bok.setTittel");
for (int i = 0; i < tittel.length(); i++) {
char c = tittel.charAt(i);
if (! (Character.isLetter(c) || Character.isDigit(c) ||
specialCharacters.indexOf(c) >= 0)) {
return;
}
}
if (!isValidTitle(tittel)) {
throw new IllegalArgumentException(tittel+" er ikke en gyldig boktittel.");
}
this.tittel = tittel;
}
public boolean isValidTitle(String tittel) {
// System.out.println("Bok.isValidTittel");
for (int i = 0; i < tittel.length(); i++) {
char c = tittel.charAt(i);
if (! (Character.isLetter(c) || Character.isDigit(c) ||
specialCharacters.indexOf(c) >= 0)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
Bok bok = new Bok("Titten tei på eventyr");
System.out.println(bok);
// Sjekk av tittel i setTitle, som kalles i konstruktøren
Bok bok2 = new Bok("Hei{");
System.out.println(bok2); // Vil bli null
// For isValidTitle()
Bok bok3 = new Bok("Titten tei på eventyr @");
// System.out.println(bok3);
}
}
package uke13.arv;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ClassGetClass {
public ClassGetClass() {
System.out.println("Jeg er laget!");
}
public static void main(String[] args) {
Class cls;
try {
// GetClass()
ClassGetClass cgc = new ClassGetClass();
cls = cgc.getClass();
System.out.println("class: "+cls);
System.out.print("cls == ClassGetClass.class: ");
System.out.println(cls == ClassGetClass.class);
System.out.println("cls == Object.class: "+cls.equals(Object.class));
// Hva er forskjellen med denne og den over?
System.out.print("cgc instanceof ClassGetClass: ");
System.out.println(cgc instanceof ClassGetClass);
System.out.print("cgc instanceof Object: ");
System.out.println(cgc instanceof Object);
// Forskjellen er at instanceof også returnerer true for en subklasse.
// Linjen over returnerer _klasseobjektet_, ikke en instans av klassen.
cls = Class.forName("uke13.arv.bok.Bok");
System.out.println("Class found= "+ cls.getName());
System.out.println("Package found= "+ cls.getPackage());
// Det under brukes gjerne i 'reflective programming', som ikke er en viktig ting dette kurset
Method[] methods = cls.getMethods();
for (Method method : methods) {
// System.out.println(method);
}
// Dette under er ikke viktig pensum, men tenker det kan være med å klargjøre hva vi snakker om:
// Vi kan bruke dette til blant annet å instansiere objekter ved kjøretid. Også for 'reflection'
System.out.println("Antall konstruktører i Bok: "+cls.getConstructors().length);
System.out.println("Den første konstruktøren: "+cls.getConstructors()[1]);
var bok = (uke13.arv.bok.Bok) cls.getConstructors()[1].newInstance("Tittel");
System.out.println("Bok: "+bok);
} catch (ClassNotFoundException | IllegalArgumentException | SecurityException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
package uke13.arv;
public class MyObject {
@Override
public String toString() {
return "Hei";
// return super.toString();
}
public void lala() {
}
public static void main(String[] args) {
MyObject mo = new MyObject();
System.out.println(mo);
Object o = new Object();
System.out.println(o.toString());
// // Hva gjør den nå?
Object o2 = new MyObject();
System.out.println(o2.toString());
MyObject mo2 = (MyObject) o2;
}
}
package uke13.arv;
public class NameValidationException extends IllegalArgumentException{
private final Person person;
private final String illegalName;
public NameValidationException(final Person person, final String illegalName) {
this.person = person;
this.illegalName = illegalName;
}
// Merk at vi ikke har noen toString() her. Det har ingen unntak, så vi må helt opp til Throwable
// (se F4)
@Override
// Denne skrives ut i catch-metoden i person. Via Throwable sin getLocalizedMessage().
public String getMessage() {
return illegalName + " is illegal for " + person;
}
}
package uke13.arv;
public class Ordbok extends Bok {
int antallOrd;
String test = "foo"; // brukes bare til å vise et problem, se linje 24.
public Ordbok(String tittel, int antallOrd) {
super(tittel);
// System.out.println("Ordbok.Kons, etter super");
this.antallOrd = antallOrd;
}
public int getAntallOrd() {
return antallOrd;
}
public void setAntallOrd(int antallOrd) {
this.antallOrd = antallOrd;
}
public void setTittel(String tittel) {
/* Bare et eksempel på at test her ikke er initiert, som vist på de siste
* foilene i arv. Kommenter ut for å se at variabelen test ikke blir
* initiert. Hvorfor? Som forelest vil super-konstruktøren initieres
* før variablene settes i hoveddelen av objektet. Problemet er at super-
* konstruktøren kaller en metode setTittel, som er overskygget i Ordbok.
* Da vil denne kalles FØR variabelen test er definert, og vil dermed bli
* null. Litt teknisk, men siden det er forelest beskriver jeg eksempelet.
*/
// System.out.println("test blir ikke initiert: "+test);
// System.out.println("Ordbok.setTittel");
if (! isValidTitle(tittel))
throw new IllegalArgumentException(tittel +
" er ikke rett navn på en ordbok");
// this.tittel = tittel; // Men da tester en ikke for feil tegn... Da må en:
super.setTittel(tittel);
}
// isValidTitle overskygger Bok sin, men den sjekker på noe annet...
// Det nye kravet er at en ordbok må slutte på "ordbok". Vi må allikevel
// også huske på å sjekke at den følger super sine krav, så det kan sjekkes først:
public boolean isValidTitle(String tittel) {
// System.out.println("Ordbok.isValidTitle");
if (! super.isValidTitle(tittel)) {
return false;
}
return tittel.endsWith("ordbok");
}
// Denne kalles når en Bok kalles med toString().
protected String GetToStringAttributes() {
return super.GetToStringAttributes() + ", antallOrd=" + antallOrd;
}
}
package uke13.arv;
import java.util.ArrayList;
import java.util.Collection;