3 Klasser och objekt 3.1 Objektorientering Java är (nästan) helt objektorienterat - det saknas stöd för någon annan form av programstrukturering (förutom de inbyggda typerna int, char, float etc. som inte är klasser) Till skillnad från Pascal/C/C++ finns det inget globalt scope där exempelvis main finns deklarerad utan enbart objekt. C++ globalt Objekt Java Objekt i flera nivåer main() main() Ett program är (vid runtime) uppdelat i ett antal objekt. 3.2 Objektets delar Ett objekt innehåller: ett antal fält, (kallas även attribut eller variabler) vilka representerar objektets lagrade data ett antal metoder, vilka representerar objektets beteende Ett fält är av en viss typ och innehåller ett värde av denna typ. En metod är en serie kodsatser som utför någon form av bearbetning på objektet.
3.3 Objektens roll Ett objekt representerar någon form av begrepp. Objekt kan vara små, t.ex. en enskild variabel som kan skrivas och läsas. Objekt kan vara stora, t.ex. en hel applikation som utformats som ett enda stort objekt. Objekt kan vara "tekniska", t.ex. representera ett fönster på bildskärmen eller en kommunikationsförbindelse. Objekt kan vara verksamhetsspecifika, t.ex. representera ett bankkonto eller en faktura. 3.4 Operationer på objekt Avläsa objektets tillstånd ( getters ) Förändra objektets tillstånd ( setters ) Generellt sett kan man dela in ett objekts operationer i fyra olika kategorier: constructors skapar nya instanser av en klass destructors tar bort/förstör instanser av en klass. transformers påverkar objektets tillstånd accessors läser av objektets tillstånd (predicates) booleska frågor om objektets tillstånd. 3.4.1 Exempel: Stack constructors Stack() // skapar ny stack med defaultstorlek Stack(int size) // skapar ny stack med size som storlek destructor sköter systemet om. Normalt sett vill man här deallkokera minne och liknande, men det tar java run-time-system om. transformers push(anelement) // lägger till ett element överst på stacken. pop() // tar bort översta elementet på stacken. accessors top() // läser av översta elementet på stacken. isempty() //svarar på frågan om stacken är tom eller inte isfull() //svarar om stacken är full eller inte 3.5 Fördelar med OO programmering Objektorienterad programstrukturering har fördelen att olika programdelar får en lösare koppling till varandra med tydliga gränssnitt (man slipper monolitiska program). Data får en tydlig koppling till den programkod som bearbetar data.
Det är viktigt att objekten väljs så att de modellerar "verkliga" begrepp och att de blir autonoma. 3.6 Klasser Beskrivningen av en viss typ av objekt kallas för klass. Klassen beskriver vilka fält och metoder som objekt av denna klass ska ha. När ett exemplar av en viss objektklass skapas (instansieras) så allokeras fysiskt minne för objektets data. Ett objekt är alltså en unik förekomst av en viss klass. En klass är en mall för hur objekt från den klassen kommer att se ut och kunna bete sig. klass objekt 3.7 Statiska metoder och data Data och metoder som är deklarerade som static delas av alla objekt och kan sägas vara egenskaper hos klassen snarare än hos klasserna. En typisk statisk metod är main som (givetvis) måste kunna anropas innan det finns några objekt eftersom den har till uppgift just att skapa (minst) ett objekt och dra igång körningen av programmet. För applets finns inte detta behov eftersom själva HTML-dokumentet tjänar samma uppgift som main gör i en applikation.
3.8 Kommunikation mellan objekt Objekten i ett program kommunicerar genom att de anropar metoder i varandra. Objekten kan också göras så att de direkt kan läsa och skriva varandras fält, men detta bör undvikas eftersom objekten då inte har kontroll över sitt data. Istället ska data läsas och skrivas via metoder där objektet kan göra nödvändiga kontroller av vad som läses och skrivs. All data ska vara privat. För att ni ska få låta er data i klasserna vara public ska ni kunna motivera det mycket väl. Det enda som får vara public i en klass normalt sett är motsvarigheten till konstanter i Pascal/C/C++, dvs variabler som är static final exempelvis static final int SIZE=200; 3.9 Klassdeklaration [public] [abstract final] class <ClassName> [extends SuperClass] [implements InterfaceList] { [Constructors] //Initialiseringsmetod(er), [Fields] //fält och [Methods] //metoder }//i godtycklig ordning ClassModifiers public abstract final public: åtkomlig utanför paketet den deklareras i abstract: innehåller metoder utan kod (abstrakta metoder) final: får ej subklassas (ärvas) Nyckelordet extends anger arv. Maximalt en klass kan ärvas, kallad basklass. Nyckelordet implements anger arv av s.k. gränssnitt, vilket är en speciell typ av klass (nämligen en en helt abstrakt klass som inte innehåller någon kod och inga variabla fält). Man kan ärva flera gränssnitt; de räknas upp i en kommaterad lista. 3.10 Fältdeklarationer och typer [FieldModifiers] Type VariableDeclarators;
FieldModifiers: <ingen accessmodifierare>: åtkomlig inom paketet public: åtkomlig utanför paketet protected private: åtkomlig inom klassen endast (rekommenderas!) final: värdet kan ej ändras; ges i deklarationen/konstr static: klassvariabel (endast en gemensam instans) transient: värdet bevaras ej vid lagring av objektet volatile: vid trådning: måste synkas med masterkopia (ordningen spelar ingen roll ) 3.10.1 Primitiva typer: boolean byte (-128 to 127, inclusive) short (-32768 to 32767, inclusive) int (-2147483648 to 2147483647, inclusive) long (-9223372036854775808 to 9223372036854775807, incl.) char ('\u0000' to '\uffff' inclusive; UNICODE-represent.) float (single-precision 32-bit format IEEE 754) double (double-precision 64-bit format IEEE 754) 3.10.2 Referenstyper ("pekare" till objekt): <ClassName> <InterfaceName> <Typ>[] // Vektor (eller array), kan vara flerdimensionell 3.11 Metoddeklarationer [MethodModifiers] ResultType MethodDeclarator [throws ExceptionClassList] MethodBody MethodModifiers: <ingen accessmodifierare>: åtkomlig inom paketet public: åtkomlig utanför paketet protected private: åtkomlig inom klassen endast abstract: endast metodens signatur; ingen exekverbar kod static: klassmetod ; kan ej anropas i ett objekt
final: metoden kan ej omdefinieras i subklasser synchronized: metoden körs alltid färdigt i en tråd native: en metod som skrivs i ett annat språk (ordningen spelar ingen roll ) ResultType: <PrimitiveType> <ReferenceType> void MethodDeclarator: metodnamn ( [FormalParameterList] ) MethodBody: { <satser> } ; // om metoden är abstract eller native 3.12 Objekt När en klass är definierad så kan man skapa objekt (instanser av klassen) var som helst i applikationen där klassen är åtkomlig, i klassens egna metoder eller i andra klassers metoder. Objekt skapas med operatorn "new": MinKlass mittobjekt = new MinKlass(); eller MinKlass mittobjekt; mittobjekt = new MinKlass(); //referensvariabel skapas //objekt skapas mittobjekt är namnet på en referensvariabel som kan referera till objekt av klassen MinKlass. Det som står efter new, dvs. MinKlass() är namnet på en speciell metod i klassen som kallas konstruktor (som beskrivs strax). 3.13 Konstruktormetoden En konstruktor är en speciell metod som används för att initialisera ett nyskapat objekt. Den anropas när ett objekt skapas med new och aldrig annars.
Man kan deklarera ingen, en eller flera konstruktorer i en klass. Om man inte deklarerar någon konstruktor så skapar kompilatorn en defaultkonstruktor som anropar superklassens konstruktor utan några parametrar. För konstruktorn gäller: den (de) har samma namn som klassen saknar returtyp (men man får ej använda modifieraren void ) deklareras som public Om det finns flera konstruktorer så måste de ha olika antal och typer på parametrarna. Vilken av konstruktorerna som används bestäms av vilka parametrar som ges vid skapandet av objektet. Detta kallas att man har överlagrat konstruktorer (överlagra=overload). Konstruktorerna kan anropa varandra med this() och kan anropa superklassens konstruktor med super(). 3.13.1 Konstruktordeklarationer [ConstructorModifiers] <ClassName> ([FormalParameterList]) [throws ExceptionClassList] ConstructorBody ConstructorModifiers: <ingen accessmodifierare>: instanser skapas inom paketet public: instanser kan skapas från andra paketet protected private: instanser kan bara skapas inifrån egna klassen ConstructorBody: { [this([args]]; [super([args])]; [<satser>] } //anropa en annan konstruktor i klassen //anropa konstruktor i superklassen
3.14 Att referera till objekt Java: ett sätt objreference attr1 method1() objreference.attr1 objreference.method1() C++: tre sätt! objpointer objreference objname attr1 method1() objname.attr1 objname.method1() (*objpointer).attr1 (*objpointer).method1() objreference->attr1 objreference->method1() 3.15 Mainmetoden Main-metoden är den speciella metod som anropas när man startar ett java-program. Main ska se ut på följande sätt: public static void main(string[] args) { <satser> } Main-metoden har alltid följande modifierare: public för att vara åtkomlig för alla static för att kunna anropas även om inga objekt finns void för att inte returnera något värde Inparametern är en sträng-vektor som innehåller alla argument som man vill skicka med när man startar programmet. Vad satserna i main-metoden typiskt gör är att skapa de initiala objekt som behövs för att programmet ska komma igång. När main-metoden har exekverat färdigt avslutas programmet.
3.16 Static: klassmedlemmar Medlemmar (fält och metoder) som deklareras static kommer bara att finnas i ett exemplar för hela klassen och alla objekt av klassen delar på dessa. Statiska fält brukar kallas klassvariabler och statiska metoder klassmetoder fält metoder static: klassnivå K1 kvar1 K1 kvar2 main() kmetx() K2 K1 K2 kvarr kvary() K2 ej static: instansnivå 3 instanser av K1 K1 ivar1 ivar2 ivar3 K2 ivars ivart ivaru imet1() K1 imet2() K1 imetm() K2 3.17 Sju olika sorts variabler i Java En variabel motsvaras i runtime av ett minnesutrymme i datorn där det kan lagras ett värde som överensstämmer med den typ som variabeln är deklarerad med, dvs. ett värde av primitiv typ eller referenstyp. Man kan identifiera sju olika sorts variabler beroende på i vilket sammanhang de deklareras. I runtime existerar variablerna bara under en viss tid. Variabelsort Deklarerad existerar Klassvariabel i en klass med static när klassen är laddad Instansvariabel i en klass, ej med static när objektet existerar Arraykomponent i en arraydeklaration när array-objektet existerar Metodparameter i metodens signatur när metoden exekverar Konstruktor parameter i konstruktorns signatur när konstruktorn exekverar Exception Lokal variabel i ett block eller for-sats hanterar paramter i en catch-sats när catch-blocket exekverar när blocket/for- satsen exeverar
3.18 Minneshantering i Java: Garbage Collection I Java är det systemet som ansvarar för att hantera minnet. Det finns en skräpsamlare som avallokerar objekt när de inte längre används. Exekveringsmiljön håller alltså reda på alla referenser till alla objekt. När alla referenser är borta så avallokeras objektet vid lämplig tidpunkt. Avallokeringen av oanvända objekt sker typiskt när det uppstår minnesbrist eller när programmet termineras. En destruktor liknande den som finns i C++ går alltså inte att skapa själv. Om man vill kan man lägga in en speciell metod med namnet finalize i sina klasser. Denna metod anropas av systemet när objektet avallokeras, vare sig det sker under programmets gång eller vid terminering. I finalize-metoden kan man lägga diverse avinitaliseringar. Finalize-metoden behövs inte ur systemsynpunkt. Använd inte i första taget 3.19 Klass-filer Följande regler skall följas i varje källkodsfil där en klass deklareras: Filnamn: KlassNamn.java Endast en klass i varje fil Klassen kan ej delas upp på flera filer Filen ska inledas med kommentarer som säger vad klassen gör Paketdeklaration som säger i vilket paket klassen ska ingå (endast om paketuppdelning tillämpas) Importdeklarationer som talar om vilka paket som används i klassens implementation Deklaration av klassen med samtliga dess fält och metoder. Implementationen av metoderna görs direkt i samband med deklarationen.