INF1010 våren 2012 Torsdag 9. februar Arv og subklasser del 1 (pluss litt I/O og unntaksbehandling) Stein Gjessing Institutt for informatikk Universitetet i Oslo 1
Når du har lært om subklasser kan du programmere med: Første uke: Spesialisering (og generalisering) Gjenbruk av klasser og begreper Ved sammensetning (komposisjon) Ved arv Klasse-hierarkier - arv Referanser (pekere) sterk typing Andre uke: Virtuelle metoder Nøkkelordet super Konvertering av referanser Klassen Object Metoden equals() Nøkkelordet instanceof Konstruktører 2
Hva er en subklasse? En klasse, K, beskriver objekter med visse felles egenskaper En subklasse av K, S, beskriver objekter som har de samme egenskapene (som beskrevet av K), men i tillegg er objektene noe mer, de har flere egenskaper... class K {... class S extends K {... Nytt Java nøkkelord: extends" Navn på klasser og subklasser (K og S her) bør best mulig beskrive hva klassene representerer 3
Eksempel: Universitetsregister I et mini-system for Universitetet i Oslo skal alle studenter registreres med navn og telefonnummer (åtte siffer), samt hvilket studieprogram de er tatt opp til. Det skal være mulig for studenter å bytte program. Systemet skal også inneholde informasjon om de ansatte ved universitetet, nemlig navn, telefonnummer, lønnstrinn og antall arbeidstimer per uke. Tekniskadministrativt ansatte har en arbeidsuke på 37,5 timer, mens vitenskapelig ansatte har 40-timers arbeidsuke. Alle personer skal behandles som......... 4
Eksempel: Universitetsregister I et mini-system for Universitetet i Oslo skal alle studenter registreres med navn og telefonnummer (åtte siffer), samt hvilket studieprogram de er tatt opp til. Det skal være mulig for studenter å bytte program. Systemet skal også inneholde informasjon om de ansatte ved universitetet, nemlig navn, telefonnummer, lønnstrinn og antall arbeidstimer per uke. Tekniskadministrativt ansatte har en arbeidsuke på 37,5 timer, mens vitenskapelig ansatte har 40-timers arbeidsuke. Alle personer skal behandles som......... Substantivmetoden" 5
Klassen Student class Student { String navn; int tlfnr; String program; void skrivdata() { System.out.println("Navn: " + navn); System.out.println("Telefon: " + tlfnr); System.out.println("Studieprogram: " + program); boolean gyldigtlfnr() { return tlfnr >= 10000000 && tlfnr <= 99999999; void byttprogram(string nytt) { program = nytt; 6
Klassen Ansatt class Ansatt { String navn; int tlfnr; int lønnstrinn; int antalltimer; void skrivdata() { System.out.println("Navn: " + navn); System.out.println("Telefon: " + tlfnr); System.out.println("Lønnstrinn: " + lønnstrinn); System.out.println("Timer: " + antalltimer); boolean gyldigtlfnr() { return tlfnr >= 10000000 && tlfnr <= 99999999; void lønnstillegg(int tillegg) { lønnstrinn += tillegg; 7
Student vs Ansatt Felles variable: navn, tlfnr Egne variable: Student: program Ansatt: lønnstrinn, antalltimer Felles metoder: gyldigtlfnr() Lignende metoder: skrivdata() Egne metoder: Student: nyttprogram(string nytt) Ansatt: lønnstillegg(int tillegg) 8
Klassen Person Kan samle det som er felles i en egen, mer generell, klasse: class Person { String navn; int tlfnr; boolean gyldigtlfnr() { return tlfnr >= 10000000 && tlfnr <= 99999999; Klassen Person beskriver alt som er felles for studenter og ansatte" 9
Student og Ansatt som subklasser Kan nå gjøre Student og Ansatt til subklasser av Person: class Student extends Person { String program; void byttprogram(string nytt) { program = nytt; class Ansatt extends Person { int lønnstrinn; int antalltimer; Angir at klassene Student og Ansatt er subklasser (= utvidelser) av klassen Person. void lønnstillegg(int tillegg) { lønnstrinn += tillegg; Hva med skrivdata()? - Kommer tilbake til denne Nytt Java nøkkelord: extends" 10
class Student { String navn; int tlfnr; String program; class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... boolean gyldigtlfnr() {... void byttprogram(string nytt) {... class Student extends Person { String program; void byttprogram(string nytt) {... Eksempler på objekter av klassene navn tlfnr gyldigtlfnr() navn tlfnr program gyldigtlfnr() byttprogram() navn tlfnr gyldigtlfnr() program byttprogram() 11
Bruk av en subklasse Vi kan bruke variable og metoder i en subklasse på samme måte som om vi hadde definert alt i én klasse: Uten bruk av subklasser (før): eller Med bruk av subklasser (nå): class Student { String navn; int tlfnr; String program; boolean gyldigtlfnr() {... void byttprogram(string nytt) {... Navn: stud class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... class Student extends Person { String program; void byttprogram(string nytt) {... Navn: stud navn tlfnr program gyldigtlfnr() byttprogram() Type: Student Type: Student Student stud = new Student(); boolean ok = stud.gyldigtlfnr(); String prog = stud.program; navn tlfnr gyldigtlfnr() program byttprogram() 12
UML-notasjon for subklassehierarki class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... Person class Student extends Person { String program; void byttprogram(string nytt) {... class Ansatt extends Person { int lønnstrinn; void lønnstillegg (int tillegg){ lønnstrinn += tillegg; Student Ansatt I INF1010 er riktig UML-notasjon ikke viktig (men subklassehierarkier er viktig) 13
Igjen: Hva er en subklasse? En subklasse er en klasse som bygger på en allerede spesifisert klasse, og som dermed arver dennes egenskaper i tillegg til å utvide med egne egenskaper (metoder/variable/konstanter). En subklasse er altså en mer spesialisert utgave av klassen den bygger på. Klassen vi bygger på kalles en superklasse. Dette fant Ole-Johan Dahl og Kristen Nygaard på i 1967, og laget programmeringsspråket Simula# 14
Spesialisering - Generalisering Mengden av alle Personer navn tlfnr Person Student Mengden av alle Studenter navn tlfnr lønnstrinn antalltimer Ansatt Mengden av alle Ansatte navn tlfnr program Sub-klasse ~ Sub-mengde (del-mengde) 15
Klasse-hierarkier Det er mulig å definere subklasser av en subklasse (etc.): class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... Person Student class Student extends Person { String program; void byttprogram(string nytt){... MasterStudent class MasterStudent extends Student { String veileder; Obs: Her er MasterStudent en subklasse av både Student og Person, og arver egenskaper fra begge disse. navn tlfnr gyldigtlfnr() program byttprogram() veileder MasterStudent-objekt 16
Generalisering spesialisering Mengden av alle Personer navn tlfnr gyldigtlfnr() Person Student Mengden av alle Studenter navn tlfnr gyldigtlfnr() program byttprogram() MasterStudent Mengden av alle MasterStudenter navn tlfnr gyldigtlfnr() program byttprogram() veileder 17
Klassehierarki: Klasser - Subklasser Bil class Bil {... Lastebil Personbil Drosje class Personbil extends Bil {... class Lastebil extends Bil {... class Drosje extends Personbil {... 18
Klassehierarki: Personbil Bil Klasser - Subklasser" class Bil { <lys beige egenskaper> class Personbil extends Bil { <røde egenskaper> class Lastebil extends Bil { <grønne egenskaper> class Drosje extends Personbil { <gule egenskaper> Alle lastebiler Lastebil Drosje Alle biler Alle drosjer Alle personbiler 19
Hvorfor bruker vi subklasser? 1 Klasser og subklasser avspeiler virkeligheten Bra når vi skal modellere virkeligheten i et datasystem 2 Klasser og subklasser avspeiler arkitekturen til datasystemet / dataprogrammet Bra når vi skal lage et oversiktlig stort program 3 Klasser og subklasser kan brukes til å forenkle og gjøre programmer mer forstålig, og spare arbeid: Gjenbruk av programdeler Bottom up programmering Lage verktøy Top down programmering Postulere verktøy 1 og 2 er klart" viktigst" 20
Gjenbruk av deler av programmer Viktig å ikke måtte skrive ny kode hver gang man skal programmere noe nytt Gjenbruk mest mulig av kode du har skrevet før Lag kode med henblikk på et den skal brukes (til noe liknende) senere Lag biblioteker Bruk andres bibliotek Javas eget bibliotek Strukturering av kode ( gjenbruk i samme program) Inf1000: Gjenbruk av metoder og klasser 21
Gjenbruk ved hjelp av klasser / subklasser Ved sammensetning (komposisjon) (i inf1000): Deklarer pekere til objekter av klasser du har skrevet før Lag objekter av disse klassen Kall på metoder i disse klassene Ved arv (nytt i inf1010): Lag en ny klasse som utvider den eksisterende klassen (spesielt viktig ved litt større klasser) Føy til ekstra variable og metoder 22
Gjenbruk ved sammensetning har dere allerede sett mange eksempler på i INF1000. Eksempel: Gjenbruk ved sammensetning / komposisjon class PersonRegister { HashMap<String,Person> venner = new HashMap<String,Person>(); Person p = new Person(); String navn = Ole-Morten"; venner, p og navn er /* + Diverse metoder */ deklarert som pekere til objekter av andre klasser som allerede eksisterer. p venner navn Ole-Morten 23
Gjenbruk ved arv Objekter av klassene class Bok { String tittel, forfatter; class Fagbok extends Bok { double dewey; class Skjønnlitterærbok extends Bok { String sjanger; class Bibliotek { Bok b1 = new Fagbok(); Bok b2 = new Skjønnlitterærbok(); Arv Komposisjon Gjenbrukes Gjenbrukes 24
Når skal vi bruke arv? Generelt: Ved er-en relasjon mellom objektene. En Student er en Person En Ansatt er en Person Hva med relasjonene roman bok? En roman er en bok (arv). kapittel bok? Et kapittel er ikke en bok, men et kapittel er en del av en bok, og en bok har/består av kapitler (sammensetning) Relasjoner som har-en og består-av skal ikke modelleres som subklasser, men ved hjelp av sammensetning (som datafelt (konstanter/variable)). 25
Oppgave Hvor er det naturlig å bruke komposisjon og hvor er det naturlig med arv i disse tilfellene? Relasjon mellom Komposisjon Arv vare - varelager nyhetskanal - kanal person - personregister cd - spor (sanger) PC - datamaskin gaupe - rovdyr fly - transportmiddel motor - bil 26
Ulike referansetyper Person pers; Student stud; class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... pers stud gyldigtlfnr() navn tlfnr class Student extends Person { String program; void byttprogram(string nytt){... byttprogram() program Objekt av klassen Student Vi kan ha pekere både av typen Student og av typen Person 27
Ulike måter å se et objekt på Navn: stud Type: Student navn tlfnr gyldigtlfnr() program byttprogram() Navn: pers Typen (klassen) til hele dette objektet er Student Type: Person Student stud; Person pers; stud = new Student(); pers = stud; Typen (klassen) til et objekt er uforanderlig. Et objekt kan likevel fremtre for oss på ulike måter. Et objekt av klassen class Student extends Person {... kan vi se på som et objekt av typen (klassen) Person: da er egenskapene som er spesielle for Student ikke synlige (men de er der fortsatt!). Student: da er både Person- og Studentegenskapene synlige for oss. Det er referansens type som avgjør hvordan objektet fremtrer. (med untak av virtuelle metoder, som vi snart skal lære hva er) (Det er lov å skrive: pers = new Student(); 28
Eksempler class Person { String navn; int tlfnr; boolean gyldigtlfnr() {... class Student extends Person { String program; void byttprogram(string nytt) {... Student s navn tlfnr gyldigtlfnr() program byttprogram() Person p navn tlfnr gyldigtlfnr() program byttprogram() Anta: Student s = new Student(); Person p = new Student(); Hvilke av følgende uttrykk er nå lovlige? s.navn = Ole-Morten"; s.gyldigtlfnr(); s.program = "Matte"; s.byttprogram("data"); p.navn = Ole-Ivar"; p.gyldigtlfnr(); p.program = "Matte"; p.byttprogram("data"); 29
IO feil En metode som kan komme til å gjøre en IO-feil må enten behandle denne selv, eller kaste feilen videre (også i main): public void mittprogmedio( ) throws IOException { < kode som gjør fil-behandling> I Java-biblioteket: class IOException extends Exception {... Vi skal lære mye mer om unntak og feilbehandling etter hvert throws er et Java nøkkelord 30
Inn fra tastatur i Java main les Hilsen klassedatastruktur import java.io.*; import java.util.*; class Hilsen { public static void main (String [] args) throws IOException { Scanner les= new Scanner (System.in); System.out.println( Hva heter du?"); String navn = les.nextline ( ); System.out.println( God dag " + navn ); snidil:>javac Hilsen.java snidil:>java Hilsen Hva heter du? Stein Gjessing God dag Stein Gjessing snidil:> Kaster IOunntak til runtimesystemet navn 11 konstruktører 47 metoder pluss plass til å lagre en streng (en tekst) Stein Gjessing String nextline() Objekt av klassen Scanner Et objekt av klassen String 31
main les Hilsen klassedatastruktur Inn fra tastatur - tekster fnavn import java.io.*; import java.util.*; class Hilsen { public static void main (String [] args) throws IOException { Scanner les= new Scanner (System.in); System.out.println( Hva heter du?"); String fnavn = les.next( ); String enavn = les.next( ); System.out.println( Etternavn: " + enavn ); System.out.println( Fornavn: " + fnavn ); >javac Hilsen.java >java Hilsen Hva heter du? Stein Gjessing Etternavn: Gjessing Fornavn: Stein > Et objekt av klassen String enavn 11 konstruktører 47 metoder pluss plass til å lagre en streng (en tekst) Gjessing String next() Objekt av klassen Scanner 11 konstruktører 47 metoder pluss plass til å lagre en streng (en tekst) Stein Et objekt av klassen String 32
Om å lese tall (Utdrag av et program) main tastaturparser import java.io.*; import java.util.*;.... Scanner tastaturparser= new Scanner (System.in); double tall; int antall; System.out.println( Tast inne et kommatall: ); tall = tastaturparser.nextdouble(); System.out.println( Tast inne et heltall: ); double nextdouble() int nextint() Objekt av klassen Scanner som henter data fra System.in (tastaur) antall = tastaturparser.nextint(); System.out.println ( Du skrev + tall + og + antall );
Innlesing av heltall fra fil utskrift på skjerm import java.io.*; import java.util.*; main filinn boolean hasnext() class LesFraFil { Objekt av klassen Scanner int nextint() public static void main (String [ ] args) throws IOException { Scanner filinn = new Scanner (new File ("minfil.txt )); int tall; while(filinn.hasnext()) { tall = filinn.nextint(); System.out.println(tall); // slutt main // slutt class LesFraFil DETTE GÅR BRA HVIS FILEN BARE INNE- HOLDER HELTALL!! 34
Slik gjør du, utskrift til fil: main filut import java.io.*; try { PrintWriter filut = new PrintWriter ( minutfil.txt ); catch (FileNotFoundException f) {... // Utskrift skjer som til skjerm: Dette objektet skriver på filen minutfil.txt void println() minutfil.txt filut.println( utskrift + 17 ): // For at innholdet på den nye filen skal // bevares må vi til slutt si: filut.close( ); 35
Til slutt i dag litt mer om unntak / feil - behandling i Java Mye kode kan feile og feilaktige situasjoner (unntak) kan oppstå. Kode som kan feile kan - og som oftest må - vi legge følgende rundt: Feiler koden blir denne blokken utført med feilobjektet som e peker på som parameter try { <... Kode som kan feile > catch (Exception e) { <... Gjør noe med feilen, prøv å rett opp...> 36
Fem reserverte Java ord try - Står foran en blokk som er usikker dvs. der det kan oppstå et unntak catch - Står foran en blokk som behandler et unntak. Har en peker til et unntaksobjekt som parameter finally - blir alltid utført (mer senere) throw - Starter å kaste et unntak throw <en peker til et unntaksobjekt> f.eks throw new Unntak(); throws - Kaster et unntak videre Brukes i overskriften på en metode som ikke selv vil behandle et unntak Bruk: try { <usikker kode> catch (Unntaksklasse u) { <behandle unntaket, u peker på et objekt som beskriver unntaket> 37
Unntak oppstår i egen kode try { <USIKKER KODE> <Når det skjer noe galt f.eks. at en peker er null:> throw new Unntaksklasse( );.... catch (Unntaksklasse unt) { < Unntaksbehandling. Dette hoppes over når intet unormalt/galt har hendt > < her fortsetter programmet både etter normal utføring og etter behandling av eventuelle unntak > Enkleste form for unntaksbehandling. På forhånd har vi deklarert: class Unntaksklasse extends Exception {... 38
a Når unntak oppstår i en annen metode (og ikke behandles der) try {.... x = b ( );.... catch (Unntaksklassen unt) { < Unntaksbehandling. Dette hoppes over når intet unormalt har hendt > < her fortsetter programmet både etter normal utføring og etter behandling av eventuelle unntak> a kaller b int b( ) throws Unntaksklassen { b oppdager en feil: throw new Unntaksklassen ( ) ; Normal retur fra b til a: return 17; Metoden b feiler kanskje fordi kontrakten for kall på metoden ikke ble oppfylt. Unntaksklassen er en klasse som på forhånd er deklarert (egendefinert eller definert i Java-biblioteket) som en subklasse av klassen Exception. 39
Java-bibliotekets klassehierarki for unntak Throwable Vanskelig å gjøre noe med Error RuntimeException Exception IOException VirtualMachineError IOError Må fanges NullPointerException ArithmeticException Unntak i dette subtreet bør fanges 40