Commit 002fa3b5 authored by Børge Haugset's avatar Børge Haugset
Browse files

nytt arv/abstrkt

parent 41d41a6a
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";
}
}
......@@ -5,6 +5,7 @@ import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ClassGetClass {
......@@ -17,8 +18,26 @@ public class ClassGetClass {
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");
cls = Class.forName("uke13.arv.bok.Bok");
System.out.println("Class found= "+ cls.getName());
System.out.println("Package found= "+ cls.getPackage());
......@@ -28,13 +47,14 @@ public class ClassGetClass {
// System.out.println(method);
}
// Dette under er ikke pensum, men tenker det kan være med å klargjøre hva vi snakker om:
// 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()[0]);
Bok bok = (Bok) cls.getConstructors()[0].newInstance("Tittel");
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();
}
......
......@@ -8,6 +8,10 @@ public class MyObject {
// return super.toString();
}
public void lala() {
}
public static void main(String[] args) {
MyObject mo = new MyObject();
System.out.println(mo);
......@@ -15,9 +19,9 @@ public class MyObject {
Object o = new Object();
System.out.println(o.toString());
// Hva gjør den nå?
// // Hva gjør den nå?
Object o2 = new MyObject();
System.out.println(o2.toString());
MyObject mo2 = (MyObject) o2;
}
}
......@@ -9,7 +9,8 @@ public class NameValidationException extends IllegalArgumentException{
this.illegalName = illegalName;
}
// Merk at vi ikke har noen toString() her. Det har ingen unntak, så vi må helt opp til Throwable
// 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().
......
......@@ -31,8 +31,8 @@ public class Person {
}
// Trenger ikke returnere noe, den utløser unntak hvis den finner noe.
// Unntaket skriver ikke automatisk ut, men det
// Det skrives ut der en fanger opp feilen, se catch i main.
// Unntaket skriver ikke automatisk ut, men det skrives ut der en fanger opp feilen,
// se catch i main.
private void checkName(final String name) {
for (int i = 0; i < name.length(); i++) {
final char c = name.charAt(i);
......@@ -55,7 +55,7 @@ public class Person {
System.out.println(c.contains(new Person("Anne"))); // Nope
System.out.println(c.contains(new Person("Per"))); // Yay, siden alt vi sjekker for likhet er navnet.
// Lysark 21
// Lysark NameValidationException
Person p2 = new Person("Per Berg-Hansen"); // Lovlig grunnet indexOf-sjekken.
Person p3 = new Person("Per@Hansen"); // ulovlig
System.out.println(p.getName());
......
package uke13.arv;
// Records har ingen kostruktører, gettere eller settere.
// Records har ingen konstruktører, gettere eller settere.
// Ingen verdier kan endres, det er kun lagring. OG den har
// automatisk likhetskontroll som sjekker alle felt.
public record Point(double x, double y) {
......
......@@ -8,6 +8,37 @@ public class UnderstandEquals {
this.streng = ting;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((streng == null) ? 0 : streng.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
UnderstandEquals other = (UnderstandEquals) obj;
if (streng == null) {
if (other.streng != null)
return false;
} else if (!streng.equals(other.streng))
return false;
return true;
}
public static void main(String[] args) {
// Kommentarer for utvidelse nederst
......
package uke13.arv.bok;
public class Bok {
private String tittel;
private String specialCharacters = " -,.%";
public Bok() {
}
public Bok(String tittel) {
setTittel(tittel);
}
public String getTittel() {
return tittel;
}
protected String getToStringAttributes() {
return "tittel=" + tittel; }
@Override
public String toString() {
return getToStringAttributes();
}
public void setTittel(String tittel) {
if (!isValidTittel(tittel)) {
throw new IllegalArgumentException(tittel+" er ikke en gyldig boktittel.");
}
this.tittel = tittel;
}
public boolean isValidTittel(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 utløse unntak
// For isValidTitle()
Bok bok3 = new Bok("Titten tei på eventyr");
System.out.println(bok3);
Bok ordbok = new Ordbok("Engelsk-norsk ordbok", 33);
Bok tegneseriealbum = new Tegneseriealbum("Asterix og romerne", 43);
// Vi kan ikke kalle tegneseriealbum.getAntallStriper, men siden toString kaller
// toString overskygget i Tegneseriealbum vises det allikevel:
System.out.println(tegneseriealbum);
// Arv arver også hva de er er:
System.out.println("ordbok er en Bok: "+(ordbok instanceof Bok));
System.out.println("ordbok er en Ordbok: "+(ordbok instanceof Ordbok));
System.out.println("ordbok er classen Bok: "+(ordbok.getClass() == Bok.class));
System.out.println("ordbok er classen Ordbok: "+(ordbok.getClass() == Ordbok.class));
// Substitusjonsprinsippet:
Bok bok4 = new Ordbok();
bok.setTittel("Egentlig ikke noen ordbok");
System.out.println(bok4.toString()); // Hva skjer her?
Bok bok5 = new Ordbok("Ikke ordbok", 234);
System.out.println(bok5.toString()); // Hva skjer her?
}
}
package uke13.arv.bok;
public class Ordbok extends Bok{
int antallOrd;
public Ordbok() {
super();
}
public Ordbok(String tittel, int antallOrd) {
super(tittel);
this.antallOrd = antallOrd;
}
public void setAntallOrd(int antallOrd) {
this.antallOrd = antallOrd;
}
public int getAntallOrd() {
return antallOrd;
}
// Skygger over Bok.getToStringAttributes(), men bruker den!
protected String getToStringAttributes() {
return super.getToStringAttributes() + ", antallOrd=" + antallOrd;
}
public static void main(String[] args) {
Bok bok = new Ordbok();
bok.setTittel("Lawrence of Arabia");
System.out.println(bok);
Ordbok ordbok = new Ordbok("Nynorsk ordbok", 654);
System.out.println(ordbok);
}
}
package uke13.arv.bok;
public class Tegneseriealbum extends Bok {
int antallStriper;
public Tegneseriealbum(String tittel, int antallStriper) {
super(tittel); // Merk at vi bruker Bok sin konstruktør, for å sjekke tittelkorrekthet
this.antallStriper = antallStriper;
}
public int getAntallStriper() {
return antallStriper;
}
// Denne kalles når en Bok kalles med toString().
protected String getToStringAttributes() {
return super.getToStringAttributes() + ", antallStriper=" + antallStriper;
}
public void setAntallStriper(int antallStriper) {
this.antallStriper = antallStriper;
}
}
package uke13.arv.bok_avansert;
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) {
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);
Bok ordbok = new Ordbok("Engelsk-norsk ordbok", 33);
Bok tegneseriealbum = new Tegneseriealbum("Asterix og romerne", 43);
// Vi kan ikke kalle tegneseriealbum.getAntallStriper, men siden toString kaller
// toString overskygget i Tegneseriealbum vises det allikevel:
System.out.println(tegneseriealbum);
}
}
package uke13.arv.bok_avansert;
public class Ordbok extends Bok {
int antallOrd;
public Ordbok(String tittel, int antallOrd) {
super(tittel); // Merk at vi bruker Bok sin konstruktør, for å sjekke tittelkorrekthet
this.antallOrd = antallOrd;
}
public int getAntallOrd() {
return antallOrd;
}
public void setAntallOrd(int antallOrd) {
this.antallOrd = antallOrd;
}
public void setTittel(String tittel) {
// 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;
}
public static void main(String[] args) {
Ordbok ordbok = new Ordbok("Nynorsk ordbok", 98543);
System.out.println(ordbok);
// Ordbok ordbok2 = new Ordbok("Nynorsk ordbøk", 98543);
// System.out.println(ordbok2);
System.out.println(ordbok instanceof Bok);
System.out.println(ordbok.getClass().equals(uke13.arv.bok_avansert.Bok.class));
System.out.println(ordbok.getClass().equals(uke13.arv.bok_avansert.Ordbok.class));
// Substitusjonsprinsippet, kan vi bruke dette fullstendig her?
// Vi kan ikke bruke Ordbok for å lage alle slags bøker, da vi har krav for tittel
// Vi setter altså større krav til en tittel her enn for en Bok. Da virker ikke substitusjonsprinsippet
// I tillegg krever vi antallOrd i konstruktøren...
// Se https://stackoverflow.com/questions/56860/what-is-an-example-of-the-liskov-substitution-principle
// Bok bok = new Ordbok(""); // Går jo ikke.
// En bedre løsning er å bruke abstrakte klasser, og/eller interface.
}
}
package uke13.arv.bok_avansert;
public class Tegneseriealbum extends Bok {
int antallStriper;
public Tegneseriealbum(String tittel, int antallStriper) {
super(tittel); // Merk at vi bruker Bok sin konstruktør, for å sjekke tittelkorrekthet
this.antallStriper = antallStriper;
}
public int getAntallStriper() {
return antallStriper;
}
// Denne kalles når en Bok kalles med toString().
protected String GetToStringAttributes() {
return super.GetToStringAttributes() + ", antallStriper=" + antallStriper;
}
public void setAntallStriper(int antallStriper) {
this.antallStriper = antallStriper;
}
}
package uke13.arv.bok_feil;
public class Bok {
String title;
public Bok(String title) {
System.out.println("Bok.Contructor");
setTitle(title);
}
boolean isValidTitle(String tittel) {
System.out.println("Bok.isValidtitle");
if (tittel.equals("Invalid")) return false;
return true;
}
public void setTitle(String tittel) {
System.out.println("Bok.setTitle");
if (isValidTitle(tittel))
this.title = tittel;
}
@Override
public String toString() {
return this.title;
}