1 Egna klasser Vi har bekantat oss med klasser genom att se hur vi kan använda olika klasser. I synnerhet klassen Scanner och klassen Math. För scannerklassen skapade vi en instans för att sedan utnyttja instansmetoder (metoder som hör till objektet) för att exempelvis läsa ett heltal från tangenbordet. I Math-klassen använder vi oss av klassmetoder för att exempelvis beräkna sinus och cosinus av vinklar. Vi kan sammanfatta klassers och objekts beståndsdelar som Klass Konstruerare Klassmetod / statisk metod, exempelvis Math.sin( v ) Klassattribut Math.PI Objekt new Scanner(System.in) Instansmetod. Man säger som regel bara metod om instansmetoder. Det är underförstått att en metod hör till ett objekt. Ex. tgb.nextint() Attribut. Exempelvis System.in lagras som attribut i Scannerobjektet Det absolut vanligaste är att arbeta med object såsom i Scannerfallet. Mathklassen är väldigt speciell, då den bara har klassmedlemmar. 1.1 En punkt-klass Vi börjar med att definiera vad en punkt består utav. 3 2 1, 2 1 3, 1 0-1 0 1 2 3 4-1 Om vi vill representera punkter som i grafen ser vi att en punkt består av två heltal, kallade x och y. x och y är alltså en punkts attribut. Tumregel: Dölj alla attribut för den som använder objektet Tumregeln som i nuläget är bökig att motivera, men en central princip inom objektorienterad programmering. Den innebär att efter att punkten skapas, ska man använda metoder för att läsa av och förändra punktens x- och y-värde. Metoder av detta slag kallas access-metoder. Punktklassen
:Point x:int y:int Point() Point(int x, int y) Detta är ett sätt att illustrera en klass egenskaper och operationer. Diagramformen kallas UML-diagram. Utifrån diagrammet kan vi läsa oss till hur vi använder en Punktklass, åtminstone syntaktiskt. Filen "PointTest.java" class PointTest public static void main(string [] arg) Point punktett = new Point(3, 8); Point punkttvå = new Point(); punkttvå.setx( 3 ); punkttvå.sety( 1 ); System.out.println("Punkt ett befinner sig på koordinaterna ["+ punktett.getx()+", "+punktett.gety()+"]"); System.out.println("Punkt två befinner sig på koordinaterna ["+ punkttvå.getx()+", "+punkttvå.gety()+"]"); Men det är inte därför vi är här. Vi ska även se hur vi kan definiera punktklassen själva. En klass bör, som vi tidigare nämnt, definieras i en fil med samma namn som klassen. Vi definierar alltså vår punktklass i filen "Point.java", kompilatorn skapar då en Point.class 1. "Point.java" class Point private int x; private int y; public Point() x = 0; y = 0; public Point(int x_arg, int y_arg) public int getx() return x; public int gety() return y; 1.class filen döps till Point.class eftersom klassens namn är Point
public void setx(int x_arg) public void sety(int y_arg) Det som är definierat i denna java-fil är Pointklassens medlemmar. Två attribut, två konstruerare och fyra metoder. 1.2 Centrala delar i klassen point Konstruktion: I huvudprogrammet såg vi punktett = new Point(3,8); Operatorn new innebär att ett objekt av typen Point konstrueras. Det som sker är 1. Skapa klassens attribut. För Pointklassen skapas heltalen x och y. Heltalen x och y är nu en del av objektet. 2. Utför konstruerarens satser. Konstrueraren beskriver vad som ska hända efter att attributen skapats. Huvudprogrammets new-sats innebär alltså ett hopp till konstrueraren som tar två int argument. public Point(int x_arg, int y_arg) Argumenten från huvudprogrammet, kallade aktuella argument, 3 och 8, förs över till de lokala variablerna, x_arg respektive y_arg. Tänk som om vi hade variabler initierade till int x_arg = 3; int y_arg = 8; Därefter utförs satserna Attribut: x och y är inte deklarerade i konstrueraren, det hade varit ett misstag. Det är steg 1. ovan som skapar variablerna x och y. class Point private int x; private int y; Vi kan illustrera vår "punktett" ur huvudprogrammet med ett UML-diagram som
punktett:point x = 3 y = 8 Det UML-diagram vi såg tidigare var ett klassdiagram, detta är ett objektdiagram, eftersom det innehåller namn på instansen och värden på attributen. Point punkttvå = new Point(); Hoppar till konstrueraren public Point() x = 0; y = 0; Som nollställer x och y. Denna konstruerare som kallas defaultkonstruerare, eftersom den inte tar några argument (värden inom parenteserna), ska sätta instansen i någon form av naturligt startläge. Att ge den kordinaten 0,0 är då lämpligt. punkttvå:point x = 0 y = 0 Det man måste tänka på då man definierar metoder och konstruerare är att objektets attribut alltid är tillgängliga. Metoder: Nästa sats i huvudprogrammet är punkttvå.setx( 3 ); Vilken anropar Point-klassens metod public void setx(int x_arg) På samma sätt som för konstruraren förs det aktuella argumentet, heltalet 3, över till det formella argumentet x_arg. Motivet till att döpa argumentet x_arg är att det inte ska "krocka" med instansens x. Om vi istället döpt argumentet x, hade vi varit tvingade att använda nyckelordet this, som innebär instansen själv för att inte få en sats som x = x; public void setx(int x) this.x = x; Om metoden definierats på detta vis stället hade den fungerat på samma sätt, men vi läser då tilldelningen som: instansens x variabel tilldelas den lokala x-variabelns värde.
Anropet till sety fungerar på samma sätt. Efter de båda anropen har objektet punkttvå ändrat tillstånd till punkttvå:point x = 3 y = 1 De resterande satserna i huvudprogrammet System.out.println("Punkt ett befinner sig på koordinaterna ["+ punktett.getx()+", "+punktett.gety()+"]"); System.out.println("Punkt två befinner sig på koordinaterna ["+ punkttvå.getx()+", "+punkttvå.gety()+"]"); Ger utskriften Punkt ett befinner sig på koordinaterna [3,8] Punkt två befinner sig på koordinaterna [3,1] Se hur texterna läggs ihop med metodanropen "Text" + punktett.getx() + "Text" getx() är definierad som public int getx() return x; int på första raden kallas returtyp och anger till vilken datatyp som metodanropet utvärderas till. Tänk på operatordiskussionen i teorimoment 3, alla uttryck utvärderas till ett värde med en datatyp. Här utvärderas punktett.getx() till en int. Satsen är alltså jämförbar med int x1 = punktett.getx(); int y1 = punktett.gety(); System.out.println("Punkt... koordinaterna ["+x1+", "+y1+"]"); Satsen return x; Finns sist i alla metoder som inte har void som returtyp. void innebär ju ingenting/inget returvärde. public/private: nyckelorden public och private anger synlighet. Nyckelordet public anger att alla ser medlemmen som public-deklarerats. Private innebär att bara medlemmar som hör till samma klass ser medlemmen. Det innebär för oss att eftersom attributen private-deklarerats kan vi inte se dem från huvudprogrammet. Alltså int x1 = punktett.x; // x osynlig, private-deklarerad int y1 = punktett.y; // y osynlig, private-deklarerad Däremot kan klassens medlemmar alltid se x och y attributen som i
public void setx(int x_arg) En bra omformulering av tumregeln vi öppnade med Dölj alla attribut för den som använder objektet Är med hjälp av public/ private Attribut deklareras private, metoder deklareras public Det finns flera undantag till denna regel men det är en mycket bra utgångspunkt. Exempel Filen "Square.java" public class Square private double side; public Square(double side) this.side = side; public double getside() return side; public void setside(double newside) side = newside; public double getarea() return side*side; public void printarea() System.out.println("Arean är:" + side*side ); Filen "Main.java" public class Main public static void main(string[] args) Square sq = new Square(3.0); System.out.println("Kvadratens area är" + sq.getarea() ); // eller sq.printarea(); Metoden getarea() är inte en accessmetod eftersom den inte har en direkt relation med attributet side Övning Skriv en klass som representerar en person, låt ett huvudprogram ange personens namn och adress, och därefter skriva ut personens namn och adress.
:Person name:string address:string Person() Person(String name, String address) getname():string getaddress():string setname(string newname) setaddress(string newaddress) printperson()