1 / 62

Objekt-orientering og Java

Objekt-orientering og Java. Oppfriskning og videreføring av Java-kunnskaper. Forelesningen. Gjennomgang av grunnleggende begreper Klasser og objekter Kjøretidsmodell Spesielle Java-temaer Informasjonsskjuling Teknikker for strukturering av Java-kode Konvensjoner Refactoring-teknikker.

malina
Download Presentation

Objekt-orientering og Java

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Objekt-orientering og Java Oppfriskning og videreføringav Java-kunnskaper

  2. Forelesningen • Gjennomgang av grunnleggende begreper • Klasser og objekter • Kjøretidsmodell • Spesielle Java-temaer • Informasjonsskjuling • Teknikker for strukturering av Java-kode • Konvensjoner • Refactoring-teknikker

  3. Objekter og klasser #f34d:C1 a = 1 o = #f350 • Objekter • identitet: hvert objekt er unikt • har en tilstand i form av felt • innkapsling: tilgangen til tilstanden kan begrenses • Klasser • beskriver generelle trekk ved objekter • mal for å lage nye objekter • metoder for å se på og endre objektene • klasser er også objekter:har egen tilstand og egne metoder (og klasser!) • Objekter har én klassetilhørighet livet gjennom • Klassen definerer hva et objekt ”kan” C1:Class b = 2 o = #f34d

  4. Objekter og identitet • hvert objekt er unikt • tradisjonelt angitt med objektets adresse • identiteten kan kun sammenlignes med andre • testes med ==-operator, e.g. o1 == o2 • støtter ikke adresse-aritmetikk <=, >= og +, - • likt innhold betyr ikke lik identitet • equals-metode, e.g. ”!”.equals(s) • ”!”.equals(”!”) er alltid sant • ”!” == ”!” kan være sant! • vær varsom med egen equals-implementasjon • a.equals(b) => b.equals(a) • a.equals(b) => a.hashCode() == b.hashCode()

  5. Identitet og referanser Object o2 #f34d:C a = 1 o = #f350 • tilordning og parameteroverføring • skjer ALLTID vha. referanser (ulikt C og C++) • static boolean foo(Object o1, Object o2){ return o1 == o2;}String a = ”test”, b = a; • både foo(a, a) og foo(a, b) er da sanne • referanser er begrenset til visse typer • null • referanse til ingenting! • e.g. (a != null ? a.foo() : false) • alle objekt-variabler kan tilordnes/referer null-verdien Object o2

  6. Søppel og søppeltømming • Objekter tar plass • hver type data tar en spesifikk mengde plass • objektets plass er omtrent summen av feltene • objekter er ”i live” så lenge referanser finnes • Søppeltømming • referanser holder objekter ”i live”:Object o1 = new Object(), o2 = o1; • hva skjer når siste referanse forsvinner:o1 = null; /* her? */o2 = null; /* her! */ • søppeltømmeren (GC) kommer og tar den! • Objekter tar plass og tømming tar tid

  7. Ikke-objekt-verdier 1 3.14 true ’c’ • Såkalte ”immediate/direkte values” • tall (byte, int, float, double),brukes til aritmetikk • tegn (char, e.g. ’c’),brukes i tekst og filbehandling • sannhetsverdier (true, false),brukes i tester • direkte verdier • tar liten plass, ikke pekere, overføres direkte • syntax for konstanter, e.g. 1, 3.1415, ’c’, true • maskinnære representasjoner ograske operasjoner

  8. Ikke-objekt-verdier... 1 3.14 true ’c’ • Finnes også i objekt-drakt • Integer:a = new Integer(1) => a.intValue() == 1 • ditto for Double/doubleValue(), Character/charValue(), • Boolean:true == new Boolean(true).booleanValue() • bruk Boolean.TRUE/FALSE når Boolean-objekter trengs • Kan ikke endres, e.g. ikke støtte fornew Integer(1).setIntValue(2) • Objekt-varianten er nyttig når: • trenger referanse til ingen verdi: null • referanse til flere typer verdier: Object eller Number • arrays (int[] vs. Integer[] og liste (List))

  9. Arrays • Deklarasjon • <type>[] <variabel>; • <type> <variabel>[]; • Initialisering • <variabel> = {<elt1>, <elt2>, <elt3>, ... ,}; • Tilordning • <variabel> = new <type>[<n>]; • <variabel> = new <type>[] { <elt1>, <elt2>, <elt3>, ... , }; • Referanse • <variabel>[<n>] • Casting • (<subtype>[])(<variabel av type>) • Integer i = ((Integer[ ])(objectArray))[0]; vs. • Integer i = (Integer)((objectArray)[0]);

  10. java.lang.String ”Hello world” eller ”Hello world” • Strenger er objekter • har identitet, lokal tilstand og metoder • e.g. s1 == s2 => s1.equals(s2), ikke omvendt • triks: ”hei”.equals(s), ikke omvendt pga. null • Men: strenger kan ikke endres • s.charAt(0), men ikke s.setCharAt(0, ’c’) • betyr at like strenger kan slås sammen: ”t” == ”t” • Implisitt kreasjon av nye strenger uten new • ”a” + ”b” gir ”ab” • ”1” + 2 gir ”12” • ”objekt: ” + s gir enten ”objekt: null” eller”objekt: ” + s.toString()

  11. String gir lett mye søppel • java.lang.String er bygget på char[] • Strenger lages automatisk av +-operator • String result = ””;for (int i = 0; i < 10; i++) result = result + Integer.toString(i); • result.equals(”0123456789”) er sant • hver iterasjon lager nytt String-objekt og char[]! • StringBuffer er et godt alternativ: • StringBuffer buf = new StringBuffer(10);for (int i = 0; i < 10; i++) buf.append(i);String result = buf.toString(); • bruker mindre hukommelse og er raskere

  12. Klasser og objekter • Klasser beskriver objekter • felt / attributter • funksjoner / operasjoner / metoder • Hvert objekt er av én klasse • skapes med new <klasse>(<parametre>) • klasse-objektet retureres av o.getClass()o = new <klasse>() =>o instanceof <klasse> &&o.getClass() == <klasse>.class • nyttig ved debugging: • System.out.println(o.getClass() + ”:” + o); • objekter kan ALDRI skifte klasse o må være != null

  13. Klasse og objekt... public class C1 { public int f1; public String f2; } Refererer til felt med dott-notasjon: c1.f1 og c1.f2; Objekt Klasse #1234 : C1 f1 = 10 f2 = ”ti” Identitet ogattributter Klassedefinisjon

  14. Arving • en klasse kan bygge på en annen • nye felt og metoder legges til • metoder kan omdefineres • objektene inneholder alle feltene • C2 arver fra C1:o = new C2() =>o instanceof C2 && o instanceof C1 • Men: o.getClass() == C2.class • variabler og referanser • C1 o1 = new C1(); C2 o2 = new C2(); • o1 = o2 er lov, men ikke o2 = o1 • casting (ikke fiske) • o1 = o2; o2 = (C2)o1; // lovlig sekvens!?! • typisk: if (o instanceof C2) ((C2)o).foo(); #f34d:C2 f1 = 1 f2 = ”hei” f3 = true C1 o1 C2 o2 #f34d:C1 f1 = 1 f2 = ”hei”

  15. Arving... public class C2 extends C1 { public boolean f3; } superklassen klasse Objekt #2468 : C2 f1 = 10 f2 = ”ti” f3 = true } Klassedefinisjon C1-del } C2-del

  16. Arving... #2460 : C1 f1 = 10 f2 = ”ti” C1 o1 = new C1(); C1 o2 = new C2(); C2 o3 = (C2)o2; C1 o1 #2468 : C2 f1 = 10 f2 = ”ti” f3 = true C1 o2 } kun C1-del er synliggjennom o2 C2 o3 lov, siden o2faktisk er C2 C2 o3 = (C2)o1; // ulovlig, gir ClassCastException

  17. Konstruktor-metoder og -kall public class C1 { public int f1; public String f2; } public C1(int i, String s) { f1 = i; f2 = s; } new C1(10, ”ti”); Konstruktor-kall ogobjekt Klassedefinisjon ogkonstruktor #1234 : C1 f1 = 10 f2 = ”ti” Identitet ogattributter Først lages boksen av systemet,så kalles konstruktoren, som initialiserer feltene

  18. ... konstruktor-metoder new C1(10, ”ti”); public class C1 { public int f1; public String f2; } public C1(int i, String s) { f1 = i; f2 = s; } public C1(int i) { this(i, ”???”); } public C1(String s) { this(s.length()); } #1234 : C1 f1 = 10 f2 = ”ti” new C1(10); #1234 : C1 f1 = 10 f2 = ”???” new C1(”10”); #1234 : C1 f1 = 2 f2 = ”???” En konstruktor kan kalle en annen,vha. this(<parametre>)-konstruksjonen

  19. Initialiseringskode • Alternativ til konstruktorer • class C1 { List l = new ArrayList(); String lString = null; { l.add(”en”); lString = l.toString(); }} • Brukes typisk for å initialisere mer komplekse datastrukturer • Kjøres automatisk før konstruktor-koden aktiveres initialisering av verdi,kun uttrykk/expressions generell kjørbar kode,kan referere til felt

  20. Konstruktorer og arving public class C2 extends C1 { public boolean f3; } public C2(int i, String s, boolean b) { super(i, s); f3 = b; } new C2(10, ”ti”, true); Konstruktor-kall ogobjekt Klassedefinisjon ogkonstruktor #2468 : C2 f1 = 10 f2 = ”ti” f3 = true } C1-del kall til superklassens konstruktor } C2-del super-konstruktoren må kalles først,for å garantere gyldig tilstand

  21. Metoder • Funksjoner / operasjoner / metoder • kode som utføre ”inni” objektet • <referanse>.<metodenavn>(<parametre>), e.g. o.toString() • tilsynelatende som referanse til felt (funksjon som feltverdi!) • kan referere direkte til objektets tilstand • public String toString() { return ”f1= ” + f1 + ”, f2: ” + f2;} • new C1(”10”).toString() => ”f1=2, f2: ???” • public String toString(String prefix) { return prefix + toString(); }

  22. Metoder forts. #2468 : C2 f1 = 10 f2 = ”ti” f3 = true void foo(int delta) { f1 += delta; f3 = ! f3; } foo(1); void foo(int f1) { this.f1 = f1; f3 = ! f3; } foo(11); #2468 : C2 f1 = 11 f2 = ”ti” f3 = false

  23. Metoder... void foo(int f1) { this.f1 = f1; f3 = ! f3; } foo(11); #2468 : C2 f1 = 10 f2 = ”ti” f3 = true #2468 : C2 f1 = 10 f2 = ”ti” f3 = true this foo f1 = 11 foo : C2 this = #2468 f1 = 11

  24. Metoder... • Klasse Bfoo(A a) { a.foo(1); } • Klasse Aboolean b;bar(int i) { b = (i == 2); }foo(int f) { bar(f+1)} : A b = : B : A b = true : B foo a = : A foo f = 1 bar i = 2 • new B().foo(new A());

  25. Metoder og arving class C1 { int f1 = 0;void foo(int delta) { f1+=delta; } } class C2 extends C1 {void foo(int delta) { f1+=delta; super.foo(delta); } } new C2().foo(2); #2468 : C2 f1 = 0 foo = (int) foo = (int) super this foo delta f1 = ?

  26. Metoder og arving... #2468 : C2 foo = (int) bar = (int) foo = (int) bar = (int) class C1 { void foo(int i) { bar(i); } void bar(int i) { ... } } class C2 extends C1 {void foo(int i) { super.foo(i); super.bar(i); } void bar(int i) { ... } } new C2().foo(2); foo : C1 i foo : C2 i vs. Sekvens:C2.foo, C1.foo, C2.bar, C1.bar

  27. Polymorfi • Metodesignatur • typene til parametrene • retur-verdien(?) • eks. public void drawString(String, int, int) • Metodekall • typene til parametrene må stemme med metodesignaturen • f.eks. drawString(”Hello world”, 10, 10+10) • Automatiske konvertering av typer • int til double og float • s + o => s + o.toString(),s + i => s + Integer.toString(i)

  28. Polymorfi... • Samme metodenavn, ulik signatur • teknisk sett ulike metoder • bør ha ”samme” bruk • public int parseInt(String s, int base) { ... } ogpublic int parseInt(String s) { parseInt(s, 10);} • tilsvarende for konstruktorer (<init>) • Bruk når en vil • unngå for mange ulike navnevariasjoner • gjøre API’er hendigere å bruke

  29. Grensesnitt • Metoder = garanti om evner • Algoritmer • formuleres vha. sett av metoder: ”dersom du kan dette, kan jeg gjøre ... med deg” • et objekt har en ”rolle” ift. algoritmen • den egentlige klassen spiller ingen rolle,bare disse metodene er implementert • Klassisk eksempel: sortering • krever mulighet for skanning og sammenligning • to typiske grensesnitt: List og Comparator • List: int size, Object get, void add, void remove, ... • Comparator: int compare, boolean equals • sorteringsalgoritmen trenger kun disse som støtte

  30. Grensesnitt... • Metoder krever: • objekter som kan visse ting • Objekter tilbyr: • sett med metoder • Interface-definisjoner • samler relevante sett med metoder/evner • klasser signaliserer at de implementerer dem • objekter av klasser som implementerer List, kan brukes overalt hvor en List kreves • en klasse kan implementere flere grensesnitt, dvs. inneha flere roller

  31. Grensesnitt i Java • public interface List { public int size(); public boolean contains(Object o); public Object get(int i); public void set(int i, Object o);} • public interface Comparator { // o1 < o2 gir -1, o1 = o2 gir 0, og o1 > o2 gir 1 public int compare(Object o1, Object o2);} • Collection.sort(List, Comparator);

  32. Grensesnitt i Java... • public class IntegerList implements List, Comparator { public int size() { ... } public boolean contains(Object o) { ... } public Object get(int i) { ... } // egentlig Integer public void set(int i, Object o) { ... } // egentlig Integer public int compare(Object o1, Object o2) { int i1 = ((Integer)o).intValue(), i2 = < (Integer)o).intValue(); if (i1 < i2) return -1; else if (i1 > i2) return 1; else return 0; }} • IntegerList il = new IntegerList(); add(il, ...); add (il, ...), ... • Collections.sort(il, il); // sorter liste, med spesifikk sammenligning

  33. Abstrakte klasser • Deklarerer visse evner • Implementerer dem ikke alle selv • Kan ikke lage objekter fra klasse • ”Delvis implementert klasse”,subklasser må implementere resten • Sier eksplisitt hvilke som mangler • Kan arve metoder (forplikte seg), uten å implementere disse

  34. Abstrakte klasser... • public abstract class AbstractList implements List { public boolean contains(Object o) { for (int i =0; i < size(); i++) if (get(i).equals(o)) return true; return false; } // resten av metodene er implisitt abstrakte f.eks. public abstract int size(); // kun deklarasjon, ingen implementasjon ...} • Grensesnitt tilsvarer abstrakt klasse med kun abstrakte metoder (Merk: implements vs. extends)

  35. Grensesnitt-konstanter • Arve av grensesnitt • arv innebærer forpliktelse,ikke gjenbruk av kode • sub-klasse i praksis uavhengig av grensesnitt • Arv av konstanter • grensesnitt kan deklarere konstanter av innebygde type (integer, char, etc.) • konstantene kan nås gjennom sub-klasse • Eks. SwingConstants • LEFT/CENTER/RIGHT, TOP/MIDDLE/BOTTOM

  36. Synlighet av navn • Grensesnitt • gir frihet til reimplementasjon uten endring av ytre forpliktelser • Innkapsling • skjul alt som utsiden ikke trenger å vite • Mekanisme • redusere synlighet av navn • Kunst å la akkurat passe mye være synlig

  37. Synlighet av navn... • ”public” • navn er synlig for alle • felt og metoder ut av klasse • klasse ut av pakke(/klasse) • implisitt i interface-definisjoner • mål å redusere mengden public-navn • reduserer frihet til å endre ting siden • ”private” • navn er ikke synlig • felt og metoder synes ikke utenfor klasse • klasse synes ikke utenfor pakke(/klasse)

  38. Synlighet av navn... • ”protected” • navn er synlig for sub-klasser, via arv • delvis eksponering av detaljer • brukes ofte til hjelpemetoder,f.eks. vanlig i abstrakte klasser • gir mulighet til mer effektive sub-klasser • kan gi utilsiktede bindinger • ”” = pakke-privat • navn inni klasse synlig for alle klasser i samme pakke • brukes blant tett koblede klasser • vanligvis ikke nødvendig

  39. Pakker i Java • Samler sammenhørende klasser • Gjør det lettere å holde oversikt over store API’er • Hierarkisk pakke-struktur • java.lang. - grunnleggende klasser f.eks. Integer, String • java.util. – nyttige hjelpeklasser, f.eks. List • java.awt. – ”gamle” GUI-klasser (inkl. java.awt.event.) • javax.swing. – ”moderne” GUI-klasser (javax angir java-utvidelse) • javax.swing.tree – klasser knyttet til JTree (men ikke JTree selv) • ... • Tilsvarer mappestruktur  Meget viktig • filnavn = klassenavn • mappe = pakke • mappehierarki = pakkehierarki

  40. Pakker i Java... • En klasses egentlige navn inneholder pakkenavnet • java.lang.String • java.util.List • javax.swing.JTree; • To måter å referere til en klasse • fullt navn, f.eks. java.lang.List • kombinasjon av import og kortnavn • import java.lang.List; • List l = new java.util.ArrayList(); • import • samles i toppen av fil (før klassedeklarasjonen) • liste med import-setninger gir nyttig oversikt over avhengigheter • importere hele pakker vha. import <pakkenavn>.*;

  41. Jar-filer • Java ARchive • enkeltfil med mappestruktur inni • innpakning av applikasjons pakkestruktur • Kjøring av Java-applikasjon krever • tilgang til mappestruktur med .class-filer (kompilerte java-filer) • jar-fil med tilsvarende katalogstruktur • CLASSPATH (eller –classpath/cp direktiv) • refererer til nødvendige mapper og jar-filer • refererer til mappen som inneholder toppnivå-pakken • må være komplett, slik at alle klasser kan lokaliseres • java –cp vips/classes;jar1.jar;jar2.jar • vanlig at prosjektmappe inneholde src-mappe • kompiler til classes-mappe

  42. Static-modifikator • Klasse som mal for objekter • identitet, feltverdier og initialiseringskode • konstruktorer og metoder håndterer tilstanden • Klassen er også selv et objekt • har navn, ikke identitet • har felt og initialiseringskode • har metoder, men ikke konstruktorer • ”Static” angir felt, kode og metoder av type 2 • Kode kjører i kontekst av klasse, ikke objekt • ”vanlige” klasser er implisitt static

  43. Static-modifikator... • class C { private static List allCs = new ArrayList(); public C() { allCs.add(this); } public static List getAll() { return allCs;}} • new C(); • C.getAll().size() == 1; #:ArrayList C:Class allCs = #:C class

  44. Nøstede klasser • Klasser inni klasser • klasse C1 er konteksten til klasse C2 • to tilfeller, med eller uten static • Static indre-klasse • som vanlig klasse, men spesiell type synlighet • dott-notasjon brukes for benevning • C1.C2 objekt = new C1.C2(); • greit å bruke for å samle kode i en fil

  45. Indre-klasser • Klasse (C2) definert inni annen klasse (C1) • kode i C2 ser navn definert i C1 • C2 arver ikke fra C1, men kan arve fra andre • C2-objekter • inneholder som vanlig egne ogarvede egenskaper • eksisterer alltid i konteksten av C1-objekt • kan referere direkte eller indirekt til C1 sine egenskaper • Bruksområder • et objekt uløselig knyttet til ett annet objekt • behov for å skjule klassen

  46. Indre-klasser... • public class C1 { String n = ””; public C1(String s) { n = s;} public class C2 { public C2() { ... } public getName() { return n;} } public C2 createC2() { return new C2(); }} • new C1(”hal”).createC2().getName() => ”hal” implisitt referanse tilkontekst-objekt #:C1 n = ”hal” C1 #:C2 createC2 getName

  47. Komplisert tilfelle ”ser” C1 fra to kanter • public class C1 { String n = ””; public C1(String s) { n = s;} public class C2 extends C1 { public C2(String s) { super(s); } public getName() { return this.C1.n + n;} } public C2 createC2(String n) { return new C2(n);}} • new C1(”hal”).createC2(”9000”).getName() => ”hal9000” #:C2 n = ”hal” #:C1 n = ”hal” C1 this this createC2 getName kontekstuelt felt vs. arvet

  48. Anonyme indre-klasser • Indre-klasse • har annen klasse som kontekst • arver (extends) eller implementerer (implements) annen klasse • Anonym variant • navnløs klasse defineres i konstruktor-kall • direkte (re)implementasjon av metoder • To typer bruk • direkte implementasjon av grensesnitt • variant av eksisterende (evt. abstrakt) klasse • Svært hendig, men kan virke forkludrende

  49. Anonyme indre-klasser... • List l = new ArrayList(); • ... • Collection.sort(l, new Comparator() { // implementasjon av metode public int compare(Object o1, Object o2) { return o1.toString().compareTo(o2); }}); // vanlig å glemme

  50. Anonyme indre-klasser... • public class MyFrame extends JFrame { public MyFrame() { add(new JPanel() { public void paint(Graphics g) { System.out.println(”paint!”); }}) }}

More Related