Presentasjon lastes. Vennligst vent

Presentasjon lastes. Vennligst vent

Objekt-orientering og Java Oppfriskning og videreføring av Java-kunnskaper.

Liknende presentasjoner


Presentasjon om: "Objekt-orientering og Java Oppfriskning og videreføring av Java-kunnskaper."— Utskrift av presentasjonen:

1 Objekt-orientering og Java Oppfriskning og videreføring av 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 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” #f34d:C1 a = 1 o = #f350 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 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 #f34d:C a = 1 o = #f350 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 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, , ’c’, true –maskinnære representasjoner og raske operasjoner ’c’true

8 Ikke-objekt-verdier... 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 for new 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 )) ’c’true

9 Arrays Deklarasjon – [] ; Initialisering – = {,,,...,}; Tilordning – = new [ ]; – = new [] {,,,..., }; Referanse – [ ] Casting –( [])( ) –Integer i = ((Integer[ ])(objectArray))[0]; vs. –Integer i = (Integer)((objectArray)[0]);

10 java.lang.String 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() ”Hello world” eller ”Hello world”

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(” ”) 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-objektet retureres av o.getClass() o = new () => o instanceof && o.getClass() ==.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; Klassedefinisjon Objekt Identitet og attributter Klasse #1234 : C1 f1 = 10 f2 = ”ti”

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 #f34d:C1 f1 = 1 f2 = ”hei” C2 o2

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

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

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

18 ... konstruktor-metoder 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()); } new C1(10, ”ti”); En konstruktor kan kalle en annen, vha. this( )-konstruksjonen new C1(10); new C1(”10”); #1234 : C1 f1 = 10 f2 = ”ti” #1234 : C1 f1 = 2 f2 = ”???” #1234 : C1 f1 = 10 f2 = ”???”

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; } Klassedefinisjon og konstruktor new C2(10, ”ti”, true); Konstruktor-kall og objekt } C1-del } C2-del kall til superklassens konstruktor super-konstruktoren må kalles først, for å garantere gyldig tilstand #2468 : C2 f1 = 10 f2 = ”ti” f3 = true

21 Metoder Funksjoner / operasjoner / metoder –kode som utføre ”inni” objektet –. ( ), 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. void foo(int delta) { f1 += delta; f3 = ! f3; } foo(1); void foo(int f1) { this.f1 = f1; f3 = ! f3; } foo(11); #2468 : C2 f1 = 10 f2 = ”ti” f3 = true #2468 : C2 f1 = 11 f2 = ”ti” f3 = false

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

24 Metoder... Klasse A boolean b; bar(int i) { b = (i == 2); } foo(int f) { bar(f+1)} : B foo a = : A b = foo f = 1 bar i = 2 : A b = true Klasse B foo(A a) { a.foo(1); } new B().foo(new A()); : B : 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); this #2468 : C2 f1 = 0 foo = (int) foo delta super f1 = ?

26 Metoder og arving... 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); vs. #2468 : C2 foo = (int) bar = (int) foo = (int) bar = (int) foo : C2 i foo : C1 i 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) {... } og public int parseInt(String s) { parseInt(s, 10);} –tilsvarende for konstruktorer ( ) 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 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 = 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.*;

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 1.Klasse som mal for objekter –identitet, feltverdier og initialiseringskode –konstruktorer og metoder håndterer tilstanden 2.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; C:Class allCs = #:ArrayList #: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 og arvede 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” #:C1 n = ”hal” createC2 #:C2 getName C1 implisitt referanse til kontekst-objekt

47 Komplisert tilfelle 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” #:C1 n = ”hal” createC2 getName C1 #:C2 n = ”hal” this ”ser” C1 fra to kanter 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!”); }}) } }

51 Anonyme indre-klasser... public class MouseAdapter implements MouseListener { // dummy-metoder, gjør ingenting public void mousePressed(MouseEvent event) { } public void mouseReleased(MouseEvent event) { } public void mouseClicked(MouseEvent event) { } } public class MyPanel extends JPanel { public MyPanel() { addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { System.out.println(”Click!”); }}); } }

52 Anonyme indre-klasser... add(new JButton(new AbstractAction(”OK”) { public void actionPerformed(ActionEvent ae) { // alt som må gjøre // når OK-knappen trykkes }} )); Anonym klasse er indre-klasse inni annen klasse Kode-kroppen vil typisk kalle metoder i kontekst- objektet

53 Anonyme indre-klasser... public class MyPanel extends JPanel { public MyPanel() { add(new Button(new AbstractAction() {... })); } public doOK(ActionEvent ae) {... } } #:MyPanel doOK = (ActionEvent) actionPerformed MyPanel #: AbstractAction actionPerformed = (ActionEvent) this

54 Anonyme indre-klasser... Anonyme indre-klasser kan også referere til –kontekst-objektets felt –variable definert i metoder (!) Disse må være deklarert som final, som garanterer at de ikke endres public void addButton(final String s) { add(new Button(new AbstractAction(s) { public void actionPerformed(ActionEvent ae) { doButton(ae, s); } })); } public doButton(ActionEvent ae, String s) { System.out.println(s + ”-knappen ble trykket ned”); } }

55 Anonyme indre-klasser... Det er som om konteksten er metoden hvor den anonyme klassen er definert #:MyPanel doOK = (ActionEvent) actionPerformed ae = ActionEvent MyPanel #: extends AbstractAction actionPerformed = (ActionEvent) this addButton s = ”OK” this

56 Anonyme indre-klasser... final -deklarasjonen sikrer at variabel-verdien kan kopieres og dermed overleve addButton-kallet #:MyPanel doOK = (ActionEvent) actionPerformed ae = ActionEvent MyPanel #: extends AbstractAction actionPerformed = (ActionEvent) s = ”OK” this addButton s = ”OK” this

57 Strukturering av Java-kode Konvensjoner –navngiving –sammenhørede metoder ”Sunne” strukturer –lettere å forstå og jobbe med –fleksible i bruk –”patterns”

58 Navnekonvensjoner Feltnavn –enkelt-objekter angis med entall –arrays og lister angis med flertall Accessorer –getter: lese felt x med getX() –setter: sette felt x med setX( ) –adder: legge til felt xs med addX( ) –remover: fjerne fra xs med removeX( ) Ekkel blanding av norsk og engelsk?

59 Navnekonvensjoner... Hendelser –XEvent –fireXEvent Lyttere –XListener-klasse –xChanged(XEvent)-metode –addXListener-metode –removeXListener-metode

60 Delegering Viktigste OO-prinsipp etter arv –Moderne rammeverk bruker grensesnitt og delegering, i mindre grad arv Grunnidé: –en logisk funksjon legges til ny klasse –metoder kopieres over –felt innføres, som refererer til ny klasse –metoder ”delegerer” til objekt Fordel –logisk avgrensing av funksjon –reduserer kompleksitet i klasse –oppførsel kan endres ved kjøretid, ved å bytte instans

61 Delegering... Komponent har mange funksjoner –hierarki –hendelseshåndtering –tegning av ramme og innhold Ny Border-klasse –paintBorder og getBorderSize-metoder –border-felt og get/setBorder-metoder –internt kalles border.paintBorder Eller enda bedre –Border-grensesnitt (og evt. AbstractBorder-klasse) –Mange ulike Border-implementasjoner

62 Delegering... Grunnlag for MVC-arkitektur –metoder for datahåndtering delegeres til Model-klasse –metoder for ”rendering” delegeres til View-klasse –metoder for input delegeres til Controller-klasse Samles i åpent tilgjengelig klasse Tre grensesnitt, mange implementasjoner Grunnlag for Swing-komponenter, ikke rendyrket


Laste ned ppt "Objekt-orientering og Java Oppfriskning og videreføring av Java-kunnskaper."

Liknende presentasjoner


Annonser fra Google