Læringsmål for forelesningen • OO – innkapsling vha. konstruktør og tilgangsmetoder – håndtering av konsistensregler
• Java – fra attributter til tilgangsmetoder
• Eclipse – generering av konstruktør og tilgangsmetoder 1
Forskjellige typer objekter
data
• Dataorienterte objekter – primært laget for å lagre sammenhørende dataverdier eller knytte objekter sammen
• ”Vanlige” objekter – til sammenhørende data hører operasjoner (også kalt metoder) for å manipulere dataene
• Funksjonsorienterte objekter – brukes utelukkende for evnene til å gjøre noe, f.eks. behandle data som ligger i andre objekter funksjoner 2
Illustrasjon av innkapsling fra (den forrige) boka object Client
Methods
Data
3
Innkapsling • Attributtene til et objekt representerer en kompleks tilstand – hvert attributt kan ha en rekke verdier – attributtene kan endres på ulike måter vha. metodene
• Det finnes regler for hvilke tilstander som er logisk gyldige • Ved å utelukkende å tilby metoder for å endre tilstanden, kan et objekt lettere beskytte seg mot gal bruk • Innkapsling av et objekt, ved å definere et metodegrensesnitt som sikrer riktig bruk, er et sentral poeng innen objektorientering
4
Eksempel: CD • En CD har en tittel. Tittelen kan inneholde bokstaver, tall, mellomrom, komma og bindestrek. • En CD inneholder ett eller flere spor. • Et spor har en tittel, med samme regler som for CD’er. • Et spor har en lengde og en pause. Sammen utgjør lengden og pausen sporets spillelengde. • CD’en har analogt en lengde og en spillelengde. • CD’ens lengde (altså ikke spillelengden) kan ikke overstige 72 minutter. 5
Hva slags informasjon kan en knytte til CD- og Track-klassene? • Deretter er spørsmålet: – Hvilke metoder trenger vi? Eller egentlig: hvilke metoder trenger andre klasser? – Hvilke felt trengs for å kunne implementere metodene? CD String title int maxLength int length int playLength 6
Track
tracks 1
n
String title int length int pauseLength int playLength
Konstruksjon (også kalt ”design”) • For hvert logisk stykke informasjon må en spørre seg: – (Hvordan) skal en kunne lese informasjonen? – (Hvordan) skal en kunne endre informasjonen? CD String title int maxLength int length int playLength 7
Track
tracks 1
n
String title int length int pauseLength int playLength
Konstruksjon (også kalt ”design”) • CD – title: skal kunne leses og endres, og reglene for titler og lovlige bokstaver skal respekteres – maxLength: er i praksis en konstant og skal kun kunne leses – length: skal kun kunne leses, da det beregnes fra settet med spor – playLength: som for length – tracks: skal kunne lese ut antall, spørre om et spor finnes (evt. posisjon), hent ut spor basert på posisjon, legge til (uten duplikater) og fjerne spor 8
CD String title int maxLength int length int playLength
1 tracks n Track String title int length int pauseLength int playLength
Konstruksjon forts. • Track – title: skal kunne leses og endres, og reglene for titler og lovlige bokstaver skal respekteres – length: skal kunne leses og settes – pauseLength: skal kunne leses og settes – playLength: skal kun kunne leses, da det beregnes fra lengden og pausen 9
CD String title int maxLength int length int playLength
1 tracks n Track String title int length int pauseLength int playLength
La oss begynne å tenke kode... CD-klasse Tracks-klasse
10
Effekten av private og public public Felter
Metoder
11
private
Bryter med prinsippet om innkapsling
Håndhever Innkapsling
Gir funksjonalitet til andre objekter
Interne støttefunksjoner i klassen
Fra felt til tilgangsmetoder •
Alle felt markeres som private – –
•
Relevante, offentlige tilgangsmetoder legges til –
–
• • 12
blir til private
public get() { return ; } // evt. følgende, når er boolean public boolean is() { return ; } public void set( ) { this. = ; }
Merk konvensjonen for bruk av stor bokstav etter ”get” og ”set”prefiksene Reglene er såpass enkle at Eclipse har dem innebygget, inkludert en funksjon for å generere dem
Fra felt til tilgangsmetoder •
Tabell-felt gir mer kompliserte tilgangsmetoder, siden en ikke kan tillate tilgang til tabell-verdien direkte (hvorfor ikke?) – –
•
Relevante, offentlige tilgangsmetoder legges til, f.eks.: – – – – – – – – –
• 13
[] blir til private []
public public public public public public public public public
int get<Entall>Count(); int indexOf<Entall>( <entall>); boolean contains<Entall>( <entall>); get<Entall>(int i); void set<Entall>(int i, <entall>); void add<Entall>( <entall>); void add/insert<Entall>(int i, <entall>); void remove<Entall>(int i); void remove<Entall>( <entall>);
Her finnes det ikke like klare regler som for enkle felt
CD-klasse • Felt – String title – Track[] tracks
• Metoder – – – – – – – 14
getTitle, isValidTitle, setTitle getMaxLength getLength getPlayLength getTrackCount, getTrack indexOfTrack, containsTrack addTrack, removeTrack
CD String title int maxLength int length int playLength
1 tracks n Track String title int length int pauseLength int playLength
Track-klasse • Felt – String title – int length – int pauseLength
CD String title int maxLength int length int playLength
1
• Metoder – – – – 15
getTitle, setTitle getLength, setLength getPauseLength, setPauseLength getPlayLength
tracks n Track String title int length int pauseLength int playLength
Andre felt og metoder • Konstanter – Det er vanlig å definere felt som er private static final, for å holde konstanter som max-lengden til en CD, eller settet med lovlige tegn for titler. – Dette er altså data som er uavhengig av noen instans. – I noen tilfeller kan slike konstanter gjøres public final, men generelt er det uheldig å eksponere mer enn nødvendig. Hva skjer dersom en f.eks. introduserer mini-CD’er med en annen maxlengde
• Hjelpemetoder – Det er ofte både praktisk og ryddig å definere egne metoder for validering, f.eks. isValidTitle, slik at en skiller valideringskoden fra annen logikk. – Noen ganger kan det være praktisk å la slike metoder være synlige for andre klasser, i hvert fall innen pakken. 16
Hva med lengde-begrensningen? • En (brent) CD kan ikke holde mer enn 72 minutter musikk. Betyr det at: – en skal hindre en å legge til spor, dersom den totale lengden overstiger den lovlige? – en skal hindre en å endre sporlengden (i etterkant), slik at den totale lengden overstiger den lovlige? – en skal hindre en å endre sporlengden (i etterkant) i det hele tatt? – at ingenting skal sjekkes eller hindres 17
Todelt strategi • En skal hindre at det legges til spor, slik at den totale lengden overstiger den lovlige • To varianter skal undersøkes – sporlengden settes en gang for alle, slik at lengdesjekken kun trengs å gjøres ved innlegging – sporlengden skal kunne endres, men vi må sikre at vi først sjekker om det er lov
• Hva betyr hver av variantene for implementasjonen vår? 18
Variant 1 • En skal hindre at det legges til spor, slik at den totale lengden overstiger den lovlige – addTrack-metoden må sjekke den totale lengden mot den lovlige
• Sporlengden settes en gang for alle, slik at lengdesjekken kun trengs å gjøres ved innlegging – Vi må fjerne setLength-metoden – Vi må legge til en konstruktør, slik at vi kan sette lengden ved oppretting av Track-objektet 19
track1:Track
1: setLength()
Variant 2 • En skal hindre at det legges til spor, slik at den totale lengden overstiger den lovlige – addTrack-metoden må sjekke den totale lengden mot den lovlige
• Sporlengden skal kunne endres, men vi må sikre at vi først sjekker om det er lov – For å kunne sjekke om den totale sporlengden for CD’en overstiger max-grensen, så må et spor vite hvilken CD den tilhører! Vi må legge til CD-felt og konstruktør for å sette verdien. Konstruktøren må sørge for å legge sporet inn i CD’en, slik at det ikke blir inkonsistens mellom spor- og CD-objektene – Vi må endre setLength-metoden, slik at den sjekker den nye totale lengden til CD’en mot max-grensen – Det ryddigste er å legge sjekken i en hjelpemetode i CD-klassen, siden det er denne klassen sin regel, f.eks. isLegalLength(int dt) 20
Variant 2 CD String title int maxLength int length int playLength 1
tracks n
1
cd
track1:Track
cd
cd:CD
1
Track String title int length int pauseLength int playLength 21
Poenget er å kunne få tak i CD’ens lengde, så vi kan sjekke om den nye lengden er ulovlig
1: setLength() 1.1: getLength()
evt.
1.1: isLegalLength()
Synlighetsmodifikatorer • Egenskaper (felt og metoder) som er deklarert som public, kan nåes fra kode i andre klasser, også i andre pakker • Felter og metoder uten spesifikk tilgang kan KUN nåes fra kode i samme pakke. • Egenskaper (felt og metoder) som er deklarert som private kan KUN nåes fra kode i samme klasse 22
Koden som skal til for å sikre konsistens i en objektstruktur, blir lett komplisert! Regler for beregnede data kompliserer koden, siden det som beregnes kan endres på mange måter (fra mange kanter) 23
Læringsmål for forelesningen • OO – innkapsling vha. tilgangsmetoder – håndtering av konsistensregler
• Java – fra attributter til tilgangsmetoder
• Eclipse – generering av tilgangsmetoder 24