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

arv

parent ee864636
package 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 arv;
public class Bok {
private String tittel;
private String specialCharacters = " -,.%";
// Vi sjekket først for ulovlige bokstaver, men gikk over til å sjekke for
// lovlige ting: bokstaver, tall og specialCharacters (se over)
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(String tittel) {
// System.out.println("Bok.kons");
setTittel(tittel);
}
public String getTittel() {
return tittel;
}
public void setTittel(String tittel) {
// System.out.println("Bok.setTittel");
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;
}
}
package arv;
public class ClassGetClass {
public static void main(String[] args) {
Class cls;
try {
cls = Class.forName("arv.ClassGetClass");
System.out.println("Class found= "+ cls.getName());
System.out.println("Package found= "+ cls.getPackage());
} catch (ClassNotFoundException e) {
System.out.println(e.getLocalizedMessage());
e.printStackTrace();
}
}
}
package 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;
}
@Override
// Denne skrives ut i catch-metoden i person. Via Throwable sin getLocalizedMessage().
public String getMessage() {
return illegalName + " is illegal for " + person;
}
}
package 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 (! isValidTittel(tittel))
throw new IllegalArgumentException(tittel +
" er ikke rett navn på en ordbok");
// this.tittel = tittel; // Men nå tester en ikke for feil tegn... Da må en:
super.setTittel(tittel);
}
// isValidTittel 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 isValidTittel(String tittel) {
// System.out.println("Ordbok.isValidTitle");
if (! super.isValidTittel(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 arv;
public class Person {
// Lag den helt vanilla i foil 17, utvid med setName etc i foil 25
// Ta dog med toString i 17
// Legg til equals-sjekk før og etter implementering av equals i Person
private String name;
public Person(final String name) {
setName(name);
}
public String getName() {
return name;
}
public void setName(final String name) {
checkName(name);
this.name = name;
}
// Trenger ikke returnere noe, den utløser unntak hvis den finner noe.
// Unntaket skriver ikke automatisk ut, som sagt på forelesning (overtrøtt...)
// 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);
// System.out.println("'"+c+"'");
// System.out.println(" .-".indexOf('%'));
if (! (Character.isLetter(c) || " -".indexOf(c) >= 0)) {
throw new NameValidationException(this, name);
}
}
}
public static void main(final String[] args) {
try {
Person p = new Person("Per Hansen");
Person p2 = new Person("Per@Hansen");
System.out.println(p.getName());
} catch (final NameValidationException e) {
// Test F3 på getLocalizedMessage under. Da ender du opp på Throwable-klassen.
// Denne igjen kaller getMessage. Den er beskrevet i NameValidationException,
// og som sagt på forelesning vil den overskygge andre getMessage. Dermed skrives
// den ut. Se foil 25 om arv.
System.out.println(e.getLocalizedMessage());
}
}
}
package arv;
public class Point {
double x,y;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public Point(double x, double y) {
super();
this.x = x;
this.y = y;
}
public static void main(String[] args) {
Point p1 = new Point(2.3, 3.4); // x er like, y ikke.
Point p2 = new Point(2.3, 3.7);
System.out.println("equal: "+p1.equals(p2));
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(x);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Point other = (Point) obj;
// Vi sjekker, som sagt på forelesning, bare for verdien av x her:
if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
return false;
return true;
}
}
package arv;
public class Tegneseriealbum extends Bok {
int antallStriper;
public Tegneseriealbum(String tittel, int antallStriper) {
super(tittel);
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 arv;
public class UnderstandEquals {
String ting;
public UnderstandEquals(String ting) {
this.ting = ting;
}
public static void main(String[] args) {
String s1 = new String("Hallo");
String s2 = new String("Hallo");
System.out.println(s1.equals(s2));
UnderstandEquals u1 = new UnderstandEquals("Hallo");
UnderstandEquals u2 = new UnderstandEquals("Hallo");
System.out.println(u1.equals(u2));
System.out.println(u1);
System.out.println(u2);
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((ting == null) ? 0 : ting.hashCode());
return result;
}
// Hva skjer med sammenlikning av u1 og u2 når du fjerner denne?
@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 (ting == null) {
if (other.ting != null)
return false;
} else if (!ting.equals(other.ting))
return false;
return true;
}
// Prøv å fjerne denne metoden, se hva toString skriver ut da. Jo, Object sin!
@Override
public String toString() {
// Prøv dette for moro skyld:
// System.out.println(super.toString());
return "UnderstandEquals [ting=" + ting + "]";
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment