Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture...

96
COMP 213 Advanced Object-oriented Programming Lecture 25 Class Invariants

Transcript of Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture...

Page 1: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

COMP 213

Advanced Object-oriented Programming

Lecture 25

Class Invariants

Page 2: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Class Invariants

A class invariant isdefinition of Class Invariant

some property that is always true of all instancesof the class in question.

i.e., some statement, probably talking about the fields of theclass, that might be true or false.

We’re getting a bit formal now, so we have to allow forpathological cases like ‘2 + 2 = 4’, which is a statement that willalways be true for any class.

Page 3: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Class Invariants

A class invariant isdefinition of Class Invariant

some property that is always true of all instancesof the class in question.

i.e., some statement, probably talking about the fields of theclass, that might be true or false.

We’re getting a bit formal now, so we have to allow forpathological cases like ‘2 + 2 = 4’, which is a statement that willalways be true for any class.

Page 4: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Class Invariants

A class invariant isdefinition of Class Invariant

some property that is always true of all instancesof the class in question.

i.e., some statement, probably talking about the fields of theclass, that might be true or false.

We’re getting a bit formal now, so we have to allow forpathological cases like ‘2 + 2 = 4’, which is a statement that willalways be true for any class.

Page 5: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Example of a Statement

Recall the Point class:

class Point {

private int xCoord;private int yCoord;

public Point(int x, int y) {xCoord = x;yCoord = y;

}

public void move(int dx, int dy) {xCoord += dx;yCoord += dy;

}}

Page 6: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Example of a Statement

(the class also has two accessor methods getX() and getY())

One possible statement we might make about Point instancesis:

0 ≤ xCoord and 0 ≤ yCoord

If we have an instance p of type Point, this statement will betrue for p if

0 ≤ p.xCoord and 0 ≤ p.yCoord

Note that our notion of truth is relative to instances

Page 7: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Example of a Statement

(the class also has two accessor methods getX() and getY())

One possible statement we might make about Point instancesis:

0 ≤ xCoord and 0 ≤ yCoord

If we have an instance p of type Point, this statement will betrue for p if

0 ≤ p.xCoord and 0 ≤ p.yCoord

Note that our notion of truth is relative to instances

Page 8: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Example of a Statement

(the class also has two accessor methods getX() and getY())

One possible statement we might make about Point instancesis:

0 ≤ xCoord and 0 ≤ yCoord

If we have an instance p of type Point, this statement will betrue for p if

0 ≤ p.xCoord and 0 ≤ p.yCoord

Note that our notion of truth is relative to instances

Page 9: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Example of a Statement

(the class also has two accessor methods getX() and getY())

One possible statement we might make about Point instancesis:

0 ≤ xCoord and 0 ≤ yCoord

If we have an instance p of type Point, this statement will betrue for p if

0 ≤ p.xCoord and 0 ≤ p.yCoord

Note that our notion of truth is relative to instances

Page 10: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 11: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 12: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 13: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 14: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 15: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 16: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointPoint p;

p = new Point(12, 348);

p = new Point(1,-5);

p = new Point(2, 56)

p.move(-3, 22);

p.move(1, 0);

the statement is true for pthe statement is false for pClearly, this statement is not true for all instances of class Point,and so is not a class invariant.

Page 17: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Different Class

Consider another class:

class NonNegPoint {

private int xCoord;private int yCoord;

public NonNegPoint() {xCoord = 0;yCoord = 0;

}

public void move(int dx, int dy) {xCoord += Math.max(dx, -dx);yCoord += Math.max(dy, -dy);

}}

Page 18: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Class Invariant

For this class (NonNegPointP)

0 ≤ xCoord and 0 ≤ yCoord

is a class invariant.

The property is true when a NonNegPoint instance is created,and it remains true after any method is called (there is only onemethod in this example).

Page 19: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointNonNegPoint p;

p = new NonNegPoint();

p.move(-1, -1);

p.move(2, -22);

p.xCoord = 0; p.yCoord = 0p.xCoord = 1; p.yCoord = 1p.xCoord = 3; p.yCoord = 23Clearly, there is nothing we can do to get a negative value forxCoord or yCoord.

Page 20: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointNonNegPoint p;

p = new NonNegPoint();

p.move(-1, -1);

p.move(2, -22);

p.xCoord = 0; p.yCoord = 0p.xCoord = 1; p.yCoord = 1p.xCoord = 3; p.yCoord = 23Clearly, there is nothing we can do to get a negative value forxCoord or yCoord.

Page 21: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointNonNegPoint p;

p = new NonNegPoint();

p.move(-1, -1);

p.move(2, -22);

p.xCoord = 0; p.yCoord = 0p.xCoord = 1; p.yCoord = 1p.xCoord = 3; p.yCoord = 23Clearly, there is nothing we can do to get a negative value forxCoord or yCoord.

Page 22: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointNonNegPoint p;

p = new NonNegPoint();

p.move(-1, -1);

p.move(2, -22);

p.xCoord = 0; p.yCoord = 0p.xCoord = 1; p.yCoord = 1p.xCoord = 3; p.yCoord = 23Clearly, there is nothing we can do to get a negative value forxCoord or yCoord.

Page 23: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

For Example

some instances of PointNonNegPoint p;

p = new NonNegPoint();

p.move(-1, -1);

p.move(2, -22);

p.xCoord = 0; p.yCoord = 0p.xCoord = 1; p.yCoord = 1p.xCoord = 3; p.yCoord = 23Clearly, there is nothing we can do to get a negative value forxCoord or yCoord.

Page 24: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

We can check that a property is a class invariant by checking:

1 each constructor makes the property true; and2 each public method ‘preserves’ the property

i.e., if it is true when the method is called,then it is true when the method has finished.

Page 25: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

We can check that a property is a class invariant by checking:

1 each constructor makes the property true; and2 each public method ‘preserves’ the property

i.e., if it is true when the method is called,then it is true when the method has finished.

Page 26: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

The constructor makes the property true:

NonNegPoint constructor

public NonNegPoint() {xCoord = 0;yCoord = 0;// 0 <= xCoord and 0 <= yCoord

}

Page 27: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

The constructor makes the property true:

NonNegPoint constructor

public NonNegPoint() {xCoord = 0;yCoord = 0;// 0 <= xCoord and 0 <= yCoord

}

Page 28: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and is preserved by the one public method:

in Class NonNegPoint

public void move(int dx, int dy) {

// if 0 <= xCoord and 0 <= yCoord here

xCoord += Math.max(dx, -dx);yCoord += Math.max(dy, -dy);

// then 0 <= xCoord and 0 <= yCoord here}

Page 29: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and is preserved by the one public method:

in Class NonNegPoint

public void move(int dx, int dy) {

// if 0 <= xCoord and 0 <= yCoord here

xCoord += Math.max(dx, -dx);yCoord += Math.max(dy, -dy);

// then 0 <= xCoord and 0 <= yCoord here}

Page 30: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and is preserved by the one public method:

in Class NonNegPoint

public void move(int dx, int dy) {

// if 0 <= xCoord and 0 <= yCoord here

xCoord += Math.max(dx, -dx);yCoord += Math.max(dy, -dy);

// then 0 <= xCoord and 0 <= yCoord here}

Page 31: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Invariance for Doubly-linked Lists

A class invariant for LList (doubly-linked lists) is that the list ofBiNodes is well-formed:

i.e., going along a tail pointer, then along a prev pointer takesyou back to where you started (and vice-versa).

Page 32: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Well-formed Lists

In more detail,

null is well-formeda non-null BiNode b is well-formed if

b.prev is null, orb.prev is not null, andb.prev is well-formed andb.prev.tail is b, and

b.tail is null, orb.tail is not null, andb.tail is well-formed andb.tail.prev is b

Page 33: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

A Non-well-formed List

Page 34: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

More Invariance

Another invariant for LList is that listStart points to the start ofthe list, and listEnd points to the end of the list.

In more detail, either:

listStart = listEnd = null, orboth listStart and listEnd are not null and

listStart.prev = null andlistEnd.tail = null

Page 35: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

LList Class Invariant

In its full glory:

class invariant for LListlistStart is well-formed and

listStart = listEnd = null, orboth listStart and listEnd are not null and

listStart.prev = null andlistEnd.tail = null

Page 36: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList has only the ‘default’ constructor:

LList constructor

public LList() {

}

Both listStart and listEnd are null — and null is well-formed.

So the constructor makes the class invariant true

Page 37: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList has only the ‘default’ constructor:

LList constructor

public LList() {

}

Both listStart and listEnd are null — and null is well-formed.

So the constructor makes the class invariant true

Page 38: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

Let’s look at the public method add(int):

LList#add(int)public void add(int b) {// assuming listStart is well-formed// and ... here

listStart = new BiNode(b, listStart);

if (listEnd == null) {

listEnd = listStart;}

// we need to know listStart is well-formed// and ... here}

Page 39: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

First Line

Let’s start at the beginning:

listStart = new BiNode(b, listStart);

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}// prev = null

}

By assumption, listStart was well-formed, so the tail of the newBiNode is well-formed; so is the prev BiNode . . .

Page 40: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

First Line

Let’s start at the beginning:

listStart = new BiNode(b, listStart);

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}// prev = null

}

By assumption, listStart was well-formed, so the tail of the newBiNode is well-formed; so is the prev BiNode . . .

Page 41: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

First Line

Let’s start at the beginning:

listStart = new BiNode(b, listStart);

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}// prev = null

}

By assumption, listStart was well-formed, so the tail of the newBiNode is well-formed; so is the prev BiNode . . .

Page 42: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

First Line

Let’s start at the beginning:

listStart = new BiNode(b, listStart);

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}// prev = null

}

By assumption, listStart was well-formed, so the tail of the newBiNode is well-formed; so is the prev BiNode . . .

Page 43: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and the if-statement:

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}}

makes sure that the new BiNode is well-formed.

Page 44: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and the if-statement:

BiNode constructorBiNode(int b, BiNode t) {

value = b;tail = t;if (tail != null) {tail.prev = this;

}}

makes sure that the new BiNode is well-formed.

Page 45: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {// if listStart is well-formed herelistStart = new BiNode(b, listStart);

// then listStart is well-formed here

if (listEnd == null) {

listEnd = listStart;}

// so listStart is well-formed here}

because the if-statement doesn’t change listStart

Page 46: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {// if listStart is well-formed herelistStart = new BiNode(b, listStart);

// then listStart is well-formed here

if (listEnd == null) {

listEnd = listStart;}

// so listStart is well-formed here}

because the if-statement doesn’t change listStart

Page 47: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {// if listStart is well-formed herelistStart = new BiNode(b, listStart);

// then listStart is well-formed here

if (listEnd == null) {

listEnd = listStart;}

// so listStart is well-formed here}

because the if-statement doesn’t change listStart

Page 48: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {...

if (listEnd == null) {

// then listStart was nulllistEnd = listStart;// listEnd.tail = null

}

}

because listStart’s previous value is the value of the newBiNode’s tail.Moreover, the new BiNode’s prev is null.

So the invariant is preserved!

Page 49: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {...

if (listEnd == null) {

// then listStart was nulllistEnd = listStart;// listEnd.tail = null

}

}

because listStart’s previous value is the value of the newBiNode’s tail.Moreover, the new BiNode’s prev is null.

So the invariant is preserved!

Page 50: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {...

if (listEnd == null) {

// then listStart was nulllistEnd = listStart;// listEnd.tail = null

}

}

because listStart’s previous value is the value of the newBiNode’s tail.Moreover, the new BiNode’s prev is null.

So the invariant is preserved!

Page 51: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {...

if (listEnd == null) {

// then listStart was nulllistEnd = listStart;// listEnd.tail = null

}

}

because listStart’s previous value is the value of the newBiNode’s tail.Moreover, the new BiNode’s prev is null.

So the invariant is preserved!

Page 52: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

LList#add(int)public void add(int b) {...

if (listEnd == null) {

// then listStart was nulllistEnd = listStart;// listEnd.tail = null

}

}

because listStart’s previous value is the value of the newBiNode’s tail.Moreover, the new BiNode’s prev is null.

So the invariant is preserved!

Page 53: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and so we continue through all the other public methods . . .

So far, the notion of class invariant just seems like hard work:

formulating the invariant, thenchecking it.

But can class invariants help the programmer?

Page 54: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and so we continue through all the other public methods . . .

So far, the notion of class invariant just seems like hard work:

formulating the invariant, thenchecking it.

But can class invariants help the programmer?

Page 55: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and so we continue through all the other public methods . . .

So far, the notion of class invariant just seems like hard work:

formulating the invariant, thenchecking it.

But can class invariants help the programmer?

Page 56: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and so we continue through all the other public methods . . .

So far, the notion of class invariant just seems like hard work:

formulating the invariant, thenchecking it.

But can class invariants help the programmer?

Page 57: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Checking Invariance

. . . and so we continue through all the other public methods . . .

So far, the notion of class invariant just seems like hard work:

formulating the invariant, thenchecking it.

But can class invariants help the programmer?

Page 58: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

Let’s write a method that will remove the i-th BiNode from a list.

in class LList/*** Remove the i-th element from the list

* (counting from 0). If i is greater than

* the length of the list, no element is

* removed.

* @param i

* the index of the element to remove

*/public void remove(int i) {}

Page 59: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

Let’s write a method that will remove the i-th BiNode from a list.

in class LList/*** Remove the i-th element from the list

* (counting from 0). If i is greater than

* the length of the list, no element is

* removed.

* @param i

* the index of the element to remove

*/public void remove(int i) {}

Page 60: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

in class LListpublic void remove(int i) {// find the i-th elementBiNode n = listStart;int count = 0;while (n != null) {if (count == i) {// remove the current node...return;

}count++;n = n.tail();

}}

Page 61: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

in class LListpublic void remove(int i) {// find the i-th elementBiNode n = listStart;int count = 0;while (n != null) {if (count == i) {// remove the current node...return;

}count++;n = n.tail();

}}

Page 62: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

in class LListpublic void remove(int i) {// find the i-th elementBiNode n = listStart;int count = 0;while (n != null) {if (count == i) {// remove the current node...return;

}count++;n = n.tail();

}}

Page 63: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

in class LListpublic void remove(int i) {// find the i-th elementBiNode n = listStart;int count = 0;while (n != null) {if (count == i) {// remove the current node...return;

}count++;n = n.tail();

}}

Page 64: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

We can ‘remove’ the middle BiNode:

. . . by rearranging the pointers:

Page 65: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

We can ‘remove’ the middle BiNode:

. . . by rearranging the pointers:

Page 66: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

The Class Invariant

The class invariant tells us we need to ensure:

from the definition of well-formedb.prev is null, or

b.prev is not null, andb.prev.tail is b, and

b.tail is null, orb.tail is not null, andb.tail.prev is b

for each node b

So we should check whether the nodes on either side of n arenull.If they’re both not null, we’ll rearrange the pointers as required(b.tail.prev is b, etc.)

Page 67: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

The Class Invariant

The class invariant tells us we need to ensure:

from the definition of well-formedb.prev is null, or

b.prev is not null, andb.prev.tail is b, and

b.tail is null, orb.tail is not null, andb.tail.prev is b

for each node b

So we should check whether the nodes on either side of n arenull.If they’re both not null, we’ll rearrange the pointers as required(b.tail.prev is b, etc.)

Page 68: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

The Class Invariant

The class invariant tells us we need to ensure:

from the definition of well-formedb.prev is null, or

b.prev is not null, andb.prev.tail is b, and

b.tail is null, orb.tail is not null, andb.tail.prev is b

for each node b

So we should check whether the nodes on either side of n arenull.If they’re both not null, we’ll rearrange the pointers as required(b.tail.prev is b, etc.)

Page 69: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Considering Cases

Suppose the node to the left is null.Then n is the first node in the list.

Well-formedness isn’t an issue (remember we assume westarted in a state where the list was well-formed, so we’reassuming that all the list to the right — which is the list that willremain after we remove n — is well-formed).

But the other part of the class invariant tells us:

class invariant for LListlistStart = listEnd = null, orboth listStart and listEnd are not null and

listStart.prev = null andlistEnd.tail = null

Page 70: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Considering Cases

Suppose the node to the left is null.Then n is the first node in the list.

Well-formedness isn’t an issue (remember we assume westarted in a state where the list was well-formed, so we’reassuming that all the list to the right — which is the list that willremain after we remove n — is well-formed).

But the other part of the class invariant tells us:

class invariant for LListlistStart = listEnd = null, orboth listStart and listEnd are not null and

listStart.prev = null andlistEnd.tail = null

Page 71: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Considering Cases

Suppose the node to the left is null.Then n is the first node in the list.

Well-formedness isn’t an issue (remember we assume westarted in a state where the list was well-formed, so we’reassuming that all the list to the right — which is the list that willremain after we remove n — is well-formed).

But the other part of the class invariant tells us:

class invariant for LListlistStart = listEnd = null, orboth listStart and listEnd are not null and

listStart.prev = null andlistEnd.tail = null

Page 72: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

At the Start of the List

If n is also the end of the list (i.e., there is just the one node inthe list), this part of the invariant tells us we need to set bothlistStart and listEnd to null.

Otherwise, we need to ensure

listStart.prev = null

Note that, in the ‘otherwise’ case (there are nodes to the right),

listEnd.tail = null

holds by assumption.

Page 73: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

At the Start of the List

If n is also the end of the list (i.e., there is just the one node inthe list), this part of the invariant tells us we need to set bothlistStart and listEnd to null.

Otherwise, we need to ensure

listStart.prev = null

Note that, in the ‘otherwise’ case (there are nodes to the right),

listEnd.tail = null

holds by assumption.

Page 74: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

At the Start of the List

If n is also the end of the list (i.e., there is just the one node inthe list), this part of the invariant tells us we need to set bothlistStart and listEnd to null.

Otherwise, we need to ensure

listStart.prev = null

Note that, in the ‘otherwise’ case (there are nodes to the right),

listEnd.tail = null

holds by assumption.

Page 75: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

deep in remove(int)// remove the current nodeif (n.prev() == null) { // start of listlistStart = n.tail();if (n.tail() == null) {listEnd = null;

} else {listStart.prev = null;

}}

By assumption, n.tail() is well-formed, so listStart is.Also at the start of the list; listStart and listEnd are both null.To ensure listStart.prev is null

Page 76: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

deep in remove(int)// remove the current nodeif (n.prev() == null) { // start of listlistStart = n.tail();if (n.tail() == null) {listEnd = null;

} else {listStart.prev = null;

}}

By assumption, n.tail() is well-formed, so listStart is.Also at the start of the list; listStart and listEnd are both null.To ensure listStart.prev is null

Page 77: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

deep in remove(int)// remove the current nodeif (n.prev() == null) { // start of listlistStart = n.tail();if (n.tail() == null) {listEnd = null;

} else {listStart.prev = null;

}}

By assumption, n.tail() is well-formed, so listStart is.Also at the start of the list; listStart and listEnd are both null.To ensure listStart.prev is null

Page 78: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

deep in remove(int)// remove the current nodeif (n.prev() == null) { // start of listlistStart = n.tail();if (n.tail() == null) {listEnd = null;

} else {listStart.prev = null;

}}

By assumption, n.tail() is well-formed, so listStart is.Also at the start of the list; listStart and listEnd are both null.To ensure listStart.prev is null

Page 79: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Removing a BiNode

deep in remove(int)// remove the current nodeif (n.prev() == null) { // start of listlistStart = n.tail();if (n.tail() == null) {listEnd = null;

} else {listStart.prev = null;

}}

By assumption, n.tail() is well-formed, so listStart is.Also at the start of the list; listStart and listEnd are both null.To ensure listStart.prev is null

Page 80: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Case: End of List

Similarly, if we’re at the end of the list(but not the start: this is an ‘else’ case),then by assumption of the class invariant

n.prev is well-formedlistStart.prev (off to the right) is null

we only need to ensure that listEnd.tail is null.

Page 81: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Case: End of List

Similarly, if we’re at the end of the list(but not the start: this is an ‘else’ case),then by assumption of the class invariant

n.prev is well-formedlistStart.prev (off to the right) is null

we only need to ensure that listEnd.tail is null.

Page 82: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Case: End of List

Similarly, if we’re at the end of the list(but not the start: this is an ‘else’ case),then by assumption of the class invariant

n.prev is well-formedlistStart.prev (off to the right) is null

we only need to ensure that listEnd.tail is null.

Page 83: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Case: End of List

Similarly, if we’re at the end of the list(but not the start: this is an ‘else’ case),then by assumption of the class invariant

n.prev is well-formedlistStart.prev (off to the right) is null

we only need to ensure that listEnd.tail is null.

Page 84: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

‘Else’ Case: End of the List

remove, contd.else if (n.tail == null) {// end of list; nodes to leftlistEnd = n.prev();listEnd.tail = null;

}

We know this isn’t null. . .

. . . so listEnd.tail won’t throw a NullPointerException.

Page 85: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

‘Else’ Case: End of the List

remove, contd.else if (n.tail == null) {// end of list; nodes to leftlistEnd = n.prev();listEnd.tail = null;

}

We know this isn’t null. . .

. . . so listEnd.tail won’t throw a NullPointerException.

Page 86: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

‘Else’ Case: End of the List

remove, contd.else if (n.tail == null) {// end of list; nodes to leftlistEnd = n.prev();listEnd.tail = null;

}

We know this isn’t null. . .

. . . so listEnd.tail won’t throw a NullPointerException.

Page 87: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Final Case: in media resOtherwise: there are nodes to left and right.

By assumption:

off to the left:n.prev is well-formed; andlistStart.prev is null

off to the right:n.tail is well-formed; andlistEnd.tail is null

We therefore need only concern ourselves withwell-formedness. The requirement is:

from the definition of well-formedb.prev.tail is b, andb.tail.prev is b

for each node b on either side of n.

Page 88: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Final Case: in media resOtherwise: there are nodes to left and right.

By assumption:

off to the left:n.prev is well-formed; andlistStart.prev is null

off to the right:n.tail is well-formed; andlistEnd.tail is null

We therefore need only concern ourselves withwell-formedness. The requirement is:

from the definition of well-formedb.prev.tail is b, andb.tail.prev is b

for each node b on either side of n.

Page 89: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Final Case: in media resOtherwise: there are nodes to left and right.

By assumption:

off to the left:n.prev is well-formed; andlistStart.prev is null

off to the right:n.tail is well-formed; andlistEnd.tail is null

We therefore need only concern ourselves withwell-formedness. The requirement is:

from the definition of well-formedb.prev.tail is b, andb.tail.prev is b

for each node b on either side of n.

Page 90: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Final Case: in media resOtherwise: there are nodes to left and right.

By assumption:

off to the left:n.prev is well-formed; andlistStart.prev is null

off to the right:n.tail is well-formed; andlistEnd.tail is null

We therefore need only concern ourselves withwell-formedness. The requirement is:

from the definition of well-formedb.prev.tail is b, andb.tail.prev is b

for each node b on either side of n.

Page 91: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Last Case

remove, contd.else {// nodes to left and right

// cut out n from the leftn.prev().tail = n.tail();

// cut out n from the rightn.tail().prev = n.prev();

}

// done!

Page 92: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Last Case

remove, contd.else {// nodes to left and right

// cut out n from the leftn.prev().tail = n.tail();

// cut out n from the rightn.tail().prev = n.prev();

}

// done!

Page 93: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Last Case

remove, contd.else {// nodes to left and right

// cut out n from the leftn.prev().tail = n.tail();

// cut out n from the rightn.tail().prev = n.prev();

}

// done!

Page 94: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Last Case

remove, contd.else {// nodes to left and right

// cut out n from the leftn.prev().tail = n.tail();

// cut out n from the rightn.tail().prev = n.prev();

}

// done!

Page 95: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Done!

Page 96: Advanced Object-oriented Programmingcgi.csc.liv.ac.uk/~akridel/COMP213-Fall2016/Lecture Slides/Lecture25.pdfAdvanced Object-oriented Programming Lecture 25 Class Invariants. Class

Summary

Class Invariants . . .. . . crystallise design

Next:

More Invariants