Top Banner
1 Nedarvning
53

Nedarvning

Jan 03, 2016

Download

Documents

kiersten-nels

Nedarvning. Plan. Overlæsning af metoder og konstruktører Nedarvning fra klasser Grænseflader Design af klasser. Overlæsning. Java tillader mulighed for at metoder og konstruktører kan deles om det samme navn. Navnet siges da at være overlæsset med flere implementationer. - PowerPoint PPT Presentation
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Nedarvning

1

Nedarvning

Page 2: Nedarvning

2

Plan

• Overlæsning af metoder og konstruktører

• Nedarvning fra klasser

• Grænseflader

• Design af klasser

Page 3: Nedarvning

3

Overlæsning

Java tillader mulighed for at metoder og konstruktører kan deles om det samme navn. Navnet siges da at være overlæsset med flere implementationer.

Lovligheden af en overlæsning afgøres af metodernes og konstruktørernes signatur, d.v.s. sekvensen af parametrenes typer.

Bemærk at returtypen ikke indgår i signaturen.

Page 4: Nedarvning

4

Signaturer

Metode SignaturString toString() ()void move(int dx, int dy) (int, int)void paint(Graphics g) (Graphics)

Hvis to metoder eller konstruktører har forskellige signaturer, må de gerne dele det samme navn.

Page 5: Nedarvning

5

Eksempel på overlæsning (kontruktører)

public class Point { private double x, y;

public Point() { x = 0.0; y = 0.0; }

public Point(double x, double y) { this.x = x; this.y = y; }

...}

Page 6: Nedarvning

6

public class Point { private double x, y; // ...

public double distance(Point other) { double dx = this.x - other.x, dy = this.y - other.y; return Math.sqrt(dx*dx + dy*dy); }

public double distance(double x, double y) { double dx = this.x - x, dy = this.y - y; return Math.sqrt(dx*dx + dy*dy); }}

Eksempel på overlæsning (metoder)

Page 7: Nedarvning

7

public class Point { private double x, y; // ...

public double distance(Point other) { return distance(other.x, other.y); }

public double distance(double x, double y) { double dx = this.x - x, dy = this.y - y; return Math.sqrt(dx*dx + dy*dy); }}

Alternativ implementering

Page 8: Nedarvning

8

Overlæsning bør kun bruges, når der findes en generel beskrivelse af funktionaliteten, der passer på alle overlæssede metoder.

Brug af overlæsning

class StringBuffer { StringBuffer append(String str) { ... } StringBuffer append(boolean b) { ... } StringBuffer append(char c) { ... } StringBuffer append(int i) { ... } StringBuffer append(long l) { ... } StringBuffer append(float d) { ... } StringBuffer append(double d) { ... } // ...}

Page 9: Nedarvning

9

public class String { public String substring(int i, j) { // base method: return substring [i..j-1] }

public String substring(int i) { return substring(i, length()); } //...}

Brug af overlæsning

Page 10: Nedarvning

10

Klasseerklæringer

[ClassModifiers] class ClassName [extends SuperClass] [implements Interface1, Interface2 ...] { ClassMemberDeclarations }

Page 11: Nedarvning

11

Når klassen C2 nedarver fra (eller udvider) klassen C1, siges C2 at være en underklasse af C1, og C1 siges at være overklasse for C2.

Nedarvning fra klasser

class C2 extends C1 { //...}

C1

C2

Alle medlemmer i C1, der er public eller protected, er tilgængelige i C2.

Page 12: Nedarvning

12

class ColoredPoint extends Point { Color color; // ...}

Point

ColoredPoint

Eksempel på nedarvning

double xdouble y...

Color color...

Page 13: Nedarvning

13

Tolkning af nedarvning

En underklasse udgør en specialisering af sin overklasse.

En overklasse udgør en generalisering af sine underklasser.

En overklasses felter og metoder deles af dens underklasser (metoderne kan genbruges af underklasserne).

Page 14: Nedarvning

14

En klasse, som arver fra en anden klasse, kan enten være en specialisering (typisk), en udvidelse, eller både en specialisering og en udvidelse af denne klasse.

Brug af arv

class ChessFrame extends JFrame { // ...}

Specialisering:

Udvidelse: class ColoredPoint extends Point { // ...}

Page 15: Nedarvning

15

Multipel nedarvning

En klasse kan i princippet nedarve direkte fra mange overklasser. Dette kaldes for multipel nedarvning.

Java understøtter ikke nedarvning i sin fulde generalitet. I Java kan en klasse højst nedarve direkte fra én anden klasse.

En begrænset form for multipel nedarvning er dog mulig, idet en klasse gerne må implementere mere end én grænseflade.

Page 16: Nedarvning

16

I Java må enhver klasse højst have én overklasse.

Singulær nedarvning

C1a

C2

C1bC1

C2a C2b

C3

Page 17: Nedarvning

17

I Java er alle klasser organiseret i et hierarki, der har klassen Object som rod.

Enhver klasse, undtagen Object, har en unik overklasse.

Hvis der for en klasse ikke eksplicit defineres nogen overklasse, er Object dens overklasse.

Klassen Object

Page 18: Nedarvning

18

public class Object { public Object();

public String toString(); public boolean equals(Object obj); public int hashCode(); public Object clone();

public final void notify(); public final void notifyAll(); public final wait() throws InterruptedException; public final wait(long millis) throws InterruptedException; public final wait(long millis, int nanos) throws InterruptedException; public final Class getClass(); public void finalize();}

Klassen Object

Page 19: Nedarvning

19

Et dynamisk array af objekter

public class SimpleArrayList { public int size() { ... } public Object get(int idx) { ... } public void add(Object x) { ... }

private static final int INIT_CAPACITY = 10; private int theSize; private Object[] theItems = new Object[INIT_CAPACITY]; }

Generisk, kan genbruges uden kodemodifikation

Page 20: Nedarvning

20

public Object get(int idx) { if (idx < 0 || idx >= size()) throw new ArrayIndexOutOfBoundsException( "Index " + idx + "; size " + size()); return theItems[idx]; }

public int size() { return theSize; }

public void add(Object x) { if (theItems.length == size()) { Object[] old = theItems; theItems = new Object[theItems.length * 2 + 1]; for (int i = 0; i < size(); i++) theItems[i] = old[i]; } theItems[theSize++] = x; }

Page 21: Nedarvning

21

Svøbeklasser (wrapper classes)

Eftersom værdier af primitive typer ikke er objekter, tilbyder Java en række klasser til repræsentation af sådanne værdier.

Primitiv type Svøbeklasseboolean Booleanbyte Bytechar Characterdouble Doublefloat Floatint Integerlong Longshort Short

Et svøbeklasseobjekt tildeles en værdi ved sin konstruktion. Herefter kan værdien ikke ændres!

Page 22: Nedarvning

22

Svøbeklassen Integer

public final class Integer extends Number implements Comparable { public Integer(int value); public Integer(String s)

throws NumberFormatException; public int intValue();

public static Integer valueOf(String s) throws NumberFormatException; public static int parseInt(String s) throws NumberFormatException; public final static int MIN_VALUE = -2147483648; public final static int MAX_VALUE = 2147483647; // ... private int value;}

Page 23: Nedarvning

23

import java.awt.Color;

public class ColoredPoint extends Point { public Color color;

public ColoredPoint(double x, double y, Color color) { super(x, y); // must be the first statement this.color = color; }

public ColoredPoint(double x, double y) { this(x, y, Color.black); // must be the first statement

}

public ColoredPoint() { color = Color.black; // invokes super() implicitly }

}

Konstruktører for underklasser

Page 24: Nedarvning

24

Initialisering af nedarvede klasser

public class Base { int x = ...; public Base() { ...; }}

public class Derived extends Base { int y = ...;

public Derived() { ...; }}

// executed first

// executed second

// executed third

// executed fourth

Page 25: Nedarvning

25

Referencer

En variabel af referencetype indeholder en henvisning til et objekt.

Base b = new Derived();

En reference kan henvise til objekter fra forskellige klasser, blot reglen om undertyper er overholdt.

Page 26: Nedarvning

26

Definition: En type er en samling af værdier.

Reglen om undertyper

Regel: En værdi af en undertype kan optræde overalt, hvor en værdi af dens overtype forventes.

T1

T2

Definition: Typen T1 er en undertype af typen T2, hvis enhver værdi i T1 også er en værdi i T2.

Page 27: Nedarvning

27

Designregel for underklasser

Designregel: Et objekt af en underklasse bør kunne optræde overalt, hvor et objekt af dens overklasse forventes.

Shape

Line Rectangle

Shapes

Lines Rectangles

Er-relation imellem klasser (is-a)

Page 28: Nedarvning

28

Polymorf tildeling

Tildelingsreglen: Typen af et udtryk på højresiden af en tildeling skal være en undertype af typen på venstresiden.

Shape aShape; Line aLine = new Line(...);Rectangle aRectangle = new Rectangle(...);

aLine = aShape;

aLine = aRectangle;

aShape = aShape;

aShape = aLine; // ok

// ok

// compilation error

// compilation error

Page 29: Nedarvning

29

Tildelingsreglen checkes på oversættelsestidspunktet.

aLine = aShape; // compilation error

Lovligheden heraf checkes på kørselstidspunktet.

Reglen kan tilfredsstilles ved at indsnævre typen på højresiden (narrowing, down casting):

aLine = (Line) aShape; // ok

Typekonvertering(casting, kvalificering)

En ulovlig indsnævring bevirker, at der kastes en ClassCastException.

Page 30: Nedarvning

30

Bestemmelse af klassetilhørsforhold

Operatoren instanceof kan benyttes til at afgøre, hvorvidt et objekt tilhører en given klasse (eller grænseflade).

if (aShape instanceof Line) aLine = (Line) aShape:

Page 31: Nedarvning

31

Arraytyper

I Java er arrays objekter.

Object

int[] double[] B B[]

D D[]

Alle arrays er undertyper af Object.

Page 32: Nedarvning

32

Overskrivning af metoder

Overskrivning foretages, når der i en underklasse defineres en metode med samme navn, signatur og returværdi som en metode i overklassen. Ellers foretages overskrivning ikke.

class Shape { public String toString() { return "Shape"; }}

class Line extends Shape { Point p1, p2;

public String toString() { return "Line from " + p1 + " to " + p2; }}

Page 33: Nedarvning

33

Præcision ved overskrivning

class B { public void m(int i) { ... }}

class D extends B { public void m(char c) { ... }}

resulterer ikke i overskrivning, men derimod i overlæsning.

Page 34: Nedarvning

34

Polymorfe metodekald

Hvilken implementation af en overskrevet metode, der udføres, afhænger af objekttypen og afgøres på kørselstids-punktet (dynamisk binding).

Shape[] shapes = new Shape[CAPACITY];shapes[0] = new Line(...);shapes[1] = new Rectangle(...);...

Kun instansmetoder kan kaldes polymorft.

for (int i = 0; i < CAPACITY; i++) System.out.println(shapes[i].toString());

Page 35: Nedarvning

35

Kald af overskrevne metoder

class Point { // ... public boolean equals(Object other) { if (other instanceof Point) { Point p = (Point) other; return x == p.x && y == p.y; } return false; }}

class ColoredPoint extends Point {//...public boolean equals(Object other) {

if (other instanceof ColoredPoint) { ColoredPoint p = (ColoredPoint) other; return super.equals(p) && color.equals(p.color); }

return false;}

}

Page 36: Nedarvning

36

Grænseflader (interfaces)

En grænseflade kan opfattes som en klasse uden implementation.

Implementeringen udsættes til de klasser, der implementerer grænsefladen.

Page 37: Nedarvning

37

[ClassModifiers] interface InterfaceName[ extends Interface1, Interface2, ... ] {

InterfaceMemberDeclarations}

Syntaks for grænseflader

Et medlem kan være enten en abstrakt metode (en metode uden implementation) eller en konstant.

De abstrakte metoder erklæres således:

ReturnType MethodName([ParameterList]);

Alle medlemmer er offentlige.

Page 38: Nedarvning

38

Eksempler på grænseflader

interface Iterator { boolean hasNext(); Object next(); void remove();}

interface Comparable { int compareTo(Object o);}

interface Comparator { int compare(Object o1, Object o2);}

Page 39: Nedarvning

39

Implementering af grænseflader

Klasser kan implementere en grænseflade ved at “overskrive” grænsefladens metoder.

interface Drawable { void draw(Graphics g);}

public class Line implements Drawable { Point p1, p2;

public void draw(Graphics g) { g.drawLine(p1.x, p1.y, p2.x, p2.y); }}

Page 40: Nedarvning

40

Præcision ved overskrivning

public interface Comparable { int compareTo(Object obj);}

class Number implements Comparable { public int compareTo(Number number) { return value < number.value ? -1 : value > number.value ? 1 : 0; }

private int value;}

giver fejl på oversættelsestidspunktet:

Number must be declared abstract. It does not define int compareTo(java.lang.Object)

from interface Comparable.

Page 41: Nedarvning

41

class Number implements Comparable { public int compareTo(Object obj) { return value < (Number) obj.value ? -1 : value > (Number) obj.value ? 1 : 0; }

private int value;}

Løsning

Page 42: Nedarvning

42

Et interface erklærer metoder uden implementation. Klasser der implementer en grænseflade, skal angive implementationer for alle grænsefladens metoder (hvis klassen da ikke skal være abstrakt).

En klasse kan implementere flere grænseflader.

En grænseflade kan nedarve fra en eller flere andre grænseflader, men ikke fra en klasse.

Nedarvning fra og implementering af grænseflader

Page 43: Nedarvning

43

Implementation af flere grænseflader

interface Drawable { void draw(Graphics g);

}

interface Movable {void move(double dx, double dy);

}

class Rectangle extends Shape implements Drawable, Movable { public void draw(Graphics g) {

// draw the rectangle}

public void move(double dx, double dy) { // move the rectangle}

}

Page 44: Nedarvning

44

Abstrakte klasser

Klasser kan erklære abstrakte metoder ved hjælp af nøgleordet abstract.abstract [MethodModifiers] ReturnType MethodName([ParameterList]);

En abstrakt klasse er en klasse, der indeholder eller nedarver mindst en abstrakt metode. En sådan klasse skal erklæres med modifikatoren abstract.

Hverken en grænseflade eller en abstrakt klasse må have instanser.

Page 45: Nedarvning

45

Anonyme klasser

class StringComparator implements Comparator { int compare(Object o1, Object o2) { return ((String) o1).compareTo((String) o2)); } }

StringComparator strComp = new StringComparator();

kan erstattes med

StringComparator strComp = new Comparator() { int compare(Object o1, Object o2) { return ((String) o1).compareTo((String) o2)); } };

Page 46: Nedarvning

46

Retningslinjer ved design af klasser

(1) Undgå offentlige felter

Et felt må kun være offentligt, hvis klassen er final, og en ændring af feltets værdi frit kan foretages.

public class Point { protected double x, y;

public double getX() { return x; } public double getY() { return y; }

public void setX(double x) { this.x = x; } public void setY(double y) { this.y = y; }}

Page 47: Nedarvning

47

(2) Adskil grænseflade fra implementation

Når funktionaliteten af en klasse kan opnås på forskellig vis, bør grænsefladen adskilles fra implementationen.

public interface List { Object elementAt(int pos); int getCount(); boolean isEmpty(); void insertElementAt(Object obj, int pos); void removeElementAt(int pos);}

public class LinkedList implements List { // body of LinkedList}

public class DynamicArray implements List { // body of DynamicArray}

Page 48: Nedarvning

48

(3) Placer en klasses hjælpeklasser i samme fil som klassen

Definer eventuelt en hjælpeklasse som en indre klasse.

public class LinkedList implements List { static protected class Node { Node prev, next; Object element; } //...}

Node

Object

Page 49: Nedarvning

49

(4) Afprøv hver klasse for sig (unit testing)

Afprøvningen af en klasse kan passende foretages i en main-metode i klassen.

Page 50: Nedarvning

50

(5) Dokumenter kildekoden med javadoc

Andre specielle mærker (tags):@author@version

@exception eller @throws@since

Eksempel på en javadoc kommentar:

/*** Retrieves the element from the LinkedList

* at the position pos *

* @param pos The position* @return The retrieved element

* @see #insertElementAt(Object element, int pos)*/public Object elementAt(int pos) {

Page 51: Nedarvning

51

fortsættes

Page 52: Nedarvning

52

Page 53: Nedarvning

53

• Læs kapitel 5

• Løs følgende opgaver fra lærebogen

Opgave 6: 4.21 (1 point)

Opgave 7: 4.22 (2 point)

Opgave 8: 4.27 (2 point, ikke-obligatorisk)

Afleveringsfrist: tirsdag den 9. oktober

Ugeseddel 225. september - 2. oktober