Metoder som är definierade i rotklassen Object, men kan omdefinieras:
Notera att två telefonnummer är lika med varandra (med equals) om de är likadana, inte bara om de är samma objekt.class Telefonnummer implements Comparable { private int landskod, riktnummer, abonnentnummer; public Telefonnummer(int landskod, int riktnummer, int abonnentnummer) { this.riktnummer = riktnummer; this.abonnentnummer = abonnentnummer; this.landskod = landskod; } public Telefonnummer(int riktnummer, int abonnentnummer) { this(46, riktnummer, abonnentnummer); } public Telefonnummer(int abonnentnummer) { this(46, 19, abonnentnummer); } public String toString() { return "+" + landskod + "-(0)" + riktnummer + "-" + abonnentnummer; } public int compareTo(Object o) { Telefonnummer rhs = (Telefonnummer)o; if (this.landskod < rhs.landskod) return -1; if (this.landskod > rhs.landskod) return 1; if (this.riktnummer < rhs.riktnummer) return -1; if (this.riktnummer > rhs.riktnummer) return 1; if (this.abonnentnummer < rhs.abonnentnummer) return -1; if (this.abonnentnummer > rhs.abonnentnummer) return 1; return 0; } public boolean equals(Object o) { if (!(o instanceof Telefonnummer)) return false; Telefonnummer rhs = (Telefonnummer)o; return this.landskod == rhs.landskod && this.riktnummer == rhs.riktnummer && this.abonnentnummer == rhs.abonnentnummer; } public int hashCode() { int result = 17; result = 37 * result + landskod; result = 37 * result + riktnummer; result = 37 * result + abonnentnummer; return result; } } // class Telefonnummer
Utskrifter:class Hamster { private String namn; public Hamster(String namn) { this.namn = namn; } } // Hamster class Hund { private String namn; public Hund(String namn) { this.namn = namn; } public String toString() { return "Hunden " + namn; } } // Hund public class Utskriftstest { public static void main(String[] args) { Hamster huey = new Hamster("Huey"); System.out.println("huey: " + huey); Hund buster = new Hund("Buster"); System.out.println("buster: " + buster); } // main } // Utskriftstest
huey: Hamster@defa1a buster: Hunden Buster
Programmet Metodtest.java fortsätter. Klassen Metodtest:
class Hund { private String namn; public Hund(String namn) { this.namn = namn; } public String toString() { return "Hunden " + namn; } } // Hund
Hundar. fido2 och fido3 refererar till samma ("==-lika") objekt.public class Metodtest { public static void main(String[] args) { // Skapa två hundar och skriv ut dem Hund buster = new Hund("Buster"); Hund pluto = new Hund("Pluto"); System.out.println("pluto: " + pluto); System.out.println("buster: " + buster); // Prova "=="-operatorn på hundarna System.out.println("buster == buster: " + (buster == buster)); System.out.println("buster == pluto: " + (buster == pluto)); // Skapa fler hundar och skriv ut dem Hund fido1 = new Hund("Fido"); Hund fido2 = new Hund("Fido"); Hund fido3 = fido2; System.out.println("fido1: " + fido1); System.out.println("fido2: " + fido2); System.out.println("fido3: " + fido3); // Prova "=="-operatorn på hundarna System.out.println("buster == fido1: " + (buster == fido1)); System.out.println("fido1 == fido2: " + (fido1 == fido2)); System.out.println("fido2 == fido3: " + (fido2 == fido3)); System.out.println("buster == new Hund(\"Buster\"): " + (buster == new Hund("Buster"))); System.out.println("new Hund(\"Karo\") == new Hund(\"Karo\"): " + (new Hund("Karo") == new Hund("Karo")));
Utskrifter:
Slutsats: En Hund-instans är bara "==" med sig själv. Och i Java kan man inte omdefiniera operatorer, så det går inte att ändra.pluto: Hunden Pluto buster: Hunden Buster buster == buster: true buster == pluto: false fido1: Hunden Fido fido2: Hunden Fido fido3: Hunden Fido buster == fido1: false fido1 == fido2: false fido2 == fido3: true buster == new Hund("Buster"): false new Hund("Karo") == new Hund("Karo"): false
Programmet Metodtest.java fortsätter. Nu ska vi prova equals-metoden på samma hundar.
Utskrifter:System.out.println("buster.equals(buster): " + buster.equals(buster)); System.out.println("buster.equals(pluto): " + buster.equals(pluto)); System.out.println("fido1.equals(fido1): " + fido1.equals(fido1)); System.out.println("fido1.equals(fido2): " + fido1.equals(fido2)); System.out.println("fido2.equals(fido3): " + fido2.equals(fido3));
Slutsats: En Hund-instans är bara "equals" med sig själv. I Java kan man definiera en ny equals-metod för en klass, men det har vi inte gjort för Hund-klassen.buster.equals(buster): true buster.equals(pluto): false fido1.equals(fido1): true fido1.equals(fido2): false fido2.equals(fido3): true
Tänk så här: Två hundar är olika hundar, även om de har samma namn!
Programmet Metodtest.java fortsätter. Nu ska vi prova <-operatorn och compareTo-metoden på hundarna.
Slutsats: Man kan inte alls storleksjämföra hundar, vare sig med < och de andra jämförelseoperatorerna, eller med compareTo. (Såklart! Vi har ju inte skrivit någon compareTo för klassen Hund!)System.out.println("buster < pluto: " + (buster < pluto)); // Ger kompileringsfel: // Metodtest.java:56: operator < cannot be applied to Hund,Hund System.out.println("buster.compareTo(pluto): " + (buster.compareTo(pluto))); // Ger kompileringsfel: // Metodtest.java:81: cannot resolve symbol // symbol : method compareTo (Hund)
Klassen Hundras:
Klassen Hundras har en equals-metod och en compareTo-metod. Programmet Metodtest.java fortsätter. Nu ska vi prova ==-operatorn på några hundraser.
class Hundras { protected final String namn; public Hundras(String namn) { this.namn = namn; } // Hitta felet: // public Hundras(String name) { this.namn = namn; } public String toString() { return "Hundrasen " + namn; } public int compareTo(Object o) { Hundras rhs = (Hundras)o; return this.namn.compareTo(rhs.namn); } public boolean equals (Object o) { if (!(o instanceof Hundras)) return false; Hundras rhs = (Hundras)o; return this.namn == rhs.namn; } } // Hundras
Hundraser. schäfer1 och schäfer2 refererar inte till samma objekt, men till likadana ("equals-lika") objekt.Hundras pudel = new Hundras("pudel"); Hundras pitbull = new Hundras("pitbull"); System.out.println("pudel: " + pudel); System.out.println("pitbull: " + pitbull); System.out.println("pudel == pudel: " + (pudel == pudel)); System.out.println("pudel == pitbull: " + (pudel == pitbull)); Hundras schäfer1 = new Hundras("schäfer"); Hundras schäfer2 = new Hundras("schäfer"); System.out.println("pudel == schäfer1: " + (pudel == schäfer1)); System.out.println("schäfer1 == schäfer2: " + (schäfer1 == schäfer2));
Utskrifter:
pudel: Hundrasen pudel pitbull: Hundrasen pitbull pudel == pudel: true pudel == pitbull: false pudel == schäfer1: false schäfer1 == schäfer2: false
Slutsats: Även en Hundras-instans är bara "==" med sig själv.
Nu ska vi prova equals-metoden på samma hundraser:
Slutsats: En Hundras-instans är equals med sig själv, och med alla andra Hundras-instanser som har samma namn.System.out.println("pudel.equals(pudel): " + pudel.equals(pudel)); System.out.println("pudel.equals(pitbull): " + pudel.equals(pitbull)); System.out.println("schäfer1.equals(schäfer1): " + schäfer1.equals(schäfer1)); System.out.println("schäfer1.equals(schäfer2): " + schäfer1.equals(schäfer2));
Kanske ska man tänka så här: Det kan inte finnas två olika hundraser som har samma namn.
Utskrifter:
pudel.equals(pudel): true pudel.equals(pitbull): false schäfer1.equals(schäfer1): true schäfer1.equals(schäfer2): true
Programmet Metodtest.java fortsätter. Nu ska vi prova <-operatorn och compareTo-metoden på hundraserna.
Utskrifter:// System.out.println("pudel < pitbull: " + (pudel < pitbull)); // Ger kompileringsfel: // Metodtest.java:142: operator < cannot be applied to Hundras,Hundras System.out.println("pudel.compareTo(pitbull): " + (pudel.compareTo(pitbull))); System.out.println("schäfer1.compareTo(schäfer2): " + (schäfer1.compareTo(schäfer2))); // System.out.println("pudel.compareTo(pluto): " + (pudel.compareTo(pluto))); // Ett undantag kastas: // Exception in thread "main" java.lang.ClassCastException // at Hundras.compareTo(Metodtest.java:28)
Programmet Metodtest.java fortsätter:pudel.compareTo(pitbull): 12 schäfer1.compareTo(schäfer2): 0
Fortsättning på körexemplet:// Men hallå där! SAMMA namn? Är "equals"-metoden verkligen rätt? Hundras labrador1 = new Hundras(new String("Labrador")); Hundras labrador2 = new Hundras(new String("Labrador")); System.out.println("labrador1 == labrador2: " + (labrador1 == labrador2)); System.out.println("labrador1.equals(labrador2): " + labrador1.equals(labrador2));
Hundraser, mer detaljerat. Fältet namn i de objekt som refereras av schäfer1 och schäfer2 refererar till samma sträng. Fältet namn i de objekt som refereras av labrador1 och labrador2 refererar inte till samma sträng, men till likadana strängar.labrador1 == labrador2: false labrador1.equals(labrador2): false
Lärdom: Använd inte == för att jämföra om två strängar är lika. Använd equals i stället. Använd == på strängar bara om man, av någon anledning, vill kolla om det verkligen är samma strängobjekt. |
Klassen Hundras2, som använder equals i stället för == för att jämföra namn-strängarna:
Programmet Metodtest.java fortsätter:
class Hundras2 extends Hundras { public Hundras2(String namn) { super(namn); } public boolean equals (Object o) { if (!(o instanceof Hundras)) return false; Hundras rhs = (Hundras)o; return this.namn.equals(rhs.namn); } } // Hundras2
Utskrifter:// Kolla om det blev bättre med "equals" i st f "==" i "compareTo" labrador1 = new Hundras2(new String("Labrador")); labrador2 = new Hundras2(new String("Labrador")); System.out.println("labrador1 == labrador2: " + (labrador1 == labrador2)); System.out.println("labrador1.equals(labrador2): " + labrador1.equals(labrador2));
Programmet Metodtest.java fortsätter:labrador1 == labrador2: false labrador1.equals(labrador2): true
Utskrifter:// Prova det där med hashCode HashSet<Hundras> hundraser = new HashSet<Hundras>(); hundraser.add(labrador1); System.out.println("hundraser.contains(labrador1): " + hundraser.contains(labrador1)); System.out.println("hundraser.contains(labrador2): " + hundraser.contains(labrador2));
Klassen Hundras3, som dessutom har metoden hashCode:hundraser.contains(labrador1): true hundraser.contains(labrador2): false
Programmet Metodtest.java fortsätter:
class Hundras3 extends Hundras2 { public Hundras3(String namn) { super(namn); } public int hashCode() { return 42; } } // Hundras2
Slutet på utskrifterna:// Kolla om det blev bättre med en "hashCode"-metod hundraser.remove(labrador1); labrador1 = new Hundras3(new String("Labrador")); labrador2 = new Hundras3(new String("Labrador")); hundraser.add(labrador1); System.out.println("hundraser.contains(labrador1): " + hundraser.contains(labrador1)); System.out.println("hundraser.contains(labrador2): " + hundraser.contains(labrador2)); // Slutsats: Om man gör en egen "equals", // ska man också göra en egen "hashCode" } // main } // Metodtest
hundraser.contains(labrador1): true hundraser.contains(labrador2): true
En lärdom: Metoderna equals, hashCode och compareTo hör ihop. Om man skrivit en av dem, bör man ofta skriva alla tre. |
Se instruktionen.
Körexempel med den gamla textklienten:
Uppkopplad mot server ABC123 BBC123 AAC123 BBD123 ABC223 BBC323 AAC723 BBD823 A(llt)/M(edel)/N(ytt)/T(a bort)/E(xit) => A Skriv regnr: AAC123 Regnr: AAC123 Märke: Volvo År: 96 Nypris: 160000 ABC123 BBC123 AAC123 BBD123 ABC223 BBC323 AAC723 BBD823 A(llt)/M(edel)/N(ytt)/T(a bort)/E(xit) => N Skriv regnr: XYZ123 Skriv märke: Hummer Skriv nypris: 1700000 Skriv år: 2003 XYZ123 inlagd. Det gick BRA! ABC123 BBC123 AAC123 BBD123 ABC223 BBC323 AAC723 BBD823 XYZ123 A(llt)/M(edel)/N(ytt)/T(a bort)/E(xit) => E
Kör programmet javadoc, som följer med Suns SDK, och som finns på samma ställe som javac, java med flera./** En instans av klassen Hund representerar en enskild hund. */ public class Hund { /** Variabeln namn innehåller hundens namn. * Flera hundar kan ha samma namn. */ private String namn; public Hund(String namn) { this.namn = namn; } public String toString() { return "Hunden " + namn; } } // Hund
Skriv: javadoc Hund.java
Resultatet blir en HTML-sida med dokumentation för klassen.
Ett annat exempel: För ClientThread.java ger javadoc denna dokumentationssida.
Ett exempel till finns här, hos Sun. På samma webbsida finns mycket mer information om Javadoc.