Handout
Handout
1 2
5 6
Assessment (1 of 2): Tripos exam Assessment (2 of 2): Take-home test
There are two OOP questions in Paper 1
You will need to choose one of them 9am on 21st April – 9am on 23rd April 2020
Previous year’s questions for this course Pass/fail – worth 2 ticks
are a good example of what you might be I will aim for an exercise which will take about
asked this year 4 hours (but there is big variance on this)
Only material that I lecture is examinable Take-home test will be done through chime too
But no automated tests
I’ll provide a mock test for you to try
7 8
9 10
11 12
Objectives We’d like to use your code for research
To understand the workflow and tools to Research into teaching and learning is
complete a practical exercise important!
We want your consent to use your code
and share it with others
We will ‘anonymise’ it
Consent is optional and it has no impact
on your grades or teaching if you do not
We use git over SSH for version control Practical exercises are linked online
Same setup as github and Go to the course webpages to find links to
gitlab.developers.cam.ac.uk the practical exercises
Generate an SSH key Follow the link and start the task
Put the public part of the key on chime
15 16
IntelliJ can run tests and a debugger Git can be very simple
Demo: solve the task, run the tests, debug Your local repository contains all
something information
Local workflow: add files, then commit
them
There’s another copy on chime
You use this as a remote
It’s default name is ‘origin’
Full workflow: pull updates from remote,
add and commit files, push back to
remote
21 22
Git can be complicated Chime can run acceptance tests for you
You can have as many remotes as you These are designed to give you feedback on
like your solution and whether its right
You can have branches and merge These are hard to write so please help me
improve them
changes and and and…
If your solution was wrong but passed the tests then
Just remember to pull before you make let me know
any changes and push when you are done And vice-versa
and you should avoid any complexity
Demo: run tests on chime
Demo: git with IntelliJ
23 24
You should be writing your own tests
Some tasks will measure instruction
coverage
In this course we’re interested in ‘unit tests’
Test a single, small piece of functionality
25 26
27 28
29 30
Top 20 Languages 2016 (Cont Cont) Top 20 Languages 2016 (Cont Cont Cont)
31 32
35 36
Control Flow: Looping Examples Control Flow: Branching I
Branching statements interrupt the current control flow
return
int arr[] = {1,2,3,4,5}; Used to return from a function at any point
37 38
39 40
45 46
49 50
public class Vector3D { You will have noticed that the RHS looks rather like a function
Hoat x; call, and that's exactly what it is.
Hoat y;
Hoat z; It's a method that gets called when the object is constructed,
and it goes by the name of a constructor (it's not rocket
void add(Hoat vx, Hoat vy, Hoat vz) {
science). It maps to the datatype constructors you saw in ML.
x=x+vx;
y=y+vy;
z=z+vz; We use constructors to initialise the state of the class in a
} convenient way
} A constructor has the same name as the class
A constructor has no return type
51 52
Vector3D(oat xi, oat yi, oat zi) { Vector3D(oat xi, oat yi, oat zi) {
x=xi; x=xi;
y=yi; y=yi;
z=zi; You can use ‘this’ to disambiguate names z=zi;
} if needed: e.g. this.x = xi; }
Vector3D() {
// ... x=0.f;
} y=0.f;
z=0.f;
}
Vector3D v = new Vector3D(1.f,0.f,2.f); Vector3D v = new Vector3D(1.f,0.f,2.f);
// ...
53 }
Vector3D v2 = new Vector3D(); 54
Default Constructor
public class Vector3D {
Hoat x;
Hoat y;
Hoat z;
} If you don’t ini9alise a Zeld it
gets set to the ‘zero’ value for
Vector3D v = new Vector3D(); that type (don’t do this)
No constructor provided
So blank one generated with
no arguments
ya3ni lw maish
constructor he7ot 55 56
kol el data types fe
el default bta3ha
num =>0 str=>null
57 58
0.2
instances Groups related methods in a Class without requiring an object
Space efficient
17.5
0.2 17.5
instance Zeld sta9c Zeld public class Math { public class Math {
sta9c Zelds are good for public Hoat sqrt(Hoat x) {…} public sta9c Hoat sqrt(Hoat x) {…}
(one per object) (one per class) constants. otherwise use public double sin(Hoat x) {…} public sta9c Hoat sin(Hoat x) {…}
Also static methods: with care. public double cos(Hoat x) {…} public sta9c Hoat cos(Hoat x) {…}
} }
vs
public class Whatever { … …
Math mathobject = new Math(); Math.sqrt(9.0);
public sta9c void main(String[] args) {
mathobject.sqrt(9.0); ...
... ...
}
}
function to be used inside the class
59 60
What Not to Do Identifying Classes
Your ML has doubtless been one big file where We want our class to be a grouping of conceptually-
you threw together all the functions and value related state and behaviour
declarations One popular way to group is using grammar
Lots of C programs look like this :-( Noun → Object
We could emulate this in OOP by having one Verb → Method
class and throwing everything into it
61 62
Ques9on
- prompt : String State Arrow going left to right says “a Quiz has zero or more
- solu9on: String questions”
“-” means
private access + ask() : void Arrow going right to left says “a Question has exactly 1 Quiz”
+ check(answer : String) : boolean Behaviour What it means in real terms is that the Quiz class will contain
a variable that somehow links to a set of Question objects,
and a Question will have a variable that references a Quiz
“+” means object.
public access Note that we are only linking classes: we don't start drawing
arrows to primitive types.
> fun self(x)=x; Fun fact: iden9ty is the only class Vector3D<T> {
val self = fn : 'a -> 'a func9on in ML with type ‘a → ‘a
private T x;
private T y;
In Java, we can achieve something similar through Generics;
C++ through templates T getX() {return x;}
T getY() {return y;}
Classes are defined with placeholders (see later lectures)
We fill them in when we create objects using them void setX(T nx) {x=nx;}
void setY(T ny) {y=ny;}
LinkedList<Integer> = new LinkedList<Integer>() }
73 74
void setX(T nx) {x=nx;} a_er type void setX(Object nx) {x=nx;}
void setY(T ny) {y=ny;} checking void setY(Object ny) {y=ny;} Lecture 4:
this
} }
compiles Pointers, References and Memory
to
------>
Vector3D<Integer> v = Vector3D v = new Vector3D();
new Vector3D<>(); Integer x = (Integer)v.getX();
Integer x = v.getX(); v.setX((Object)4);
v.setX(4);
75 76
Objectives
>> 1 static int sum() {
2 int s = sum(3);
Know what a call-stack and a heap are 3 return s;
4 }
Understand the difference between 5
6 static int sum(int n) {
pointers and Java references 7 if (n == 0) {
8 return 0;
9 }
10 int m = sum(n - 1);
11 int r = m + n;
12 return r;
13 }
77
>> 1 static int sum() { sum() 1 static int sum() { sum()
s >> 2 s
2 int s = sum(3); int s = sum(3);
3 return s; 3 return s;
4 } 4 }
5 5
6 static int sum(int n) { 6 static int sum(int n) {
7 if (n == 0) { 7 if (n == 0) {
8 return 0; 8 return 0;
9 } 9 }
10 int m = sum(n - 1); 10 int m = sum(n - 1);
11 int r = m + n; 11 int r = m + n;
12 return r; 12 return r;
13 } 13 }
110
References in Java
Declaring unassigned
SomeClass ref = null; // explicit
Defining/assigning
// Assign
SomeClass ref = new ClassRef(); Lecture 5: Inheritance
113 114
Passing Procedure Arguments In Java Inheritance I
class Student { There is a lot of duplication here
the value here is an int
class Reference { private int age;
private String name;
Conceptually there is a hierarchy that we're
public sta9c void update(int i, int[] array) { private int grade; not really representing
i++; ... Both Lecturers and Students are people
array[0]++; the value here is a reference to an int array }
(no, really).
}
class Lecturer { We can view each as a kind of
private int age;
public sta9c void main(String[] args) {
private String name; specialisation of a general person
int test_i = 1;
int[] test_array = {1};
private int salary; They have all the properties of a person
prints 1 …
update(test_i, test_array);
} But they also have some extra stuff
System.out.println(test_i);
System.out.println(test_array[0]);
specific to them
prints 2
}
}
Demo: expression evaluator
If you mark a class ‘Znal’ then it can’t be extended and ‘Znal’ methods
can’t be overridden
117 118
int i = 7;
Hoat f = (Hoat) i; // f==7.0
double d = 3.2;
Specialise
Student Lecturer
With inheritance it is reasonable to type
exam_score
salary
cast an object to any of the types above it
in the inheritance tree...
name and age
inherited if not
private
119 120
Widening Narrowing
Person Student is-a Person Person Narrowing conversions move down
Hence we can use a Student object the tree (more specific)
anywhere we want a Person object Need to take care...
Can perform widening conversions
Student (up the tree) Student
OK because underlying object
really is a Student
Student s = new Student() public void print(Person p) {...} Person p = new Person(); public void print(Person p) {
Student s = (Student) p;
Person p = s; Student s = new Student(); Student s = (Student) p; }
print(s);
Student s = new Student();
FAILS at run9me. Not enough info
print(s);
In the real object to represent
Implicit widening 121 a Student 122
class B extends A {
class Person { Student inherits this as a public public int x; ‘this’ is a reference to the current object
public String name; variable and so can access it }
protected int age; ‘super’ is a reference to the parent object
private double height; class C extends B {
public int x; all classes extend Object (capital O)
} Student inherits this as a
protected variable and so can public void ac9on() {
if you write ‘class A {}’ you actually get
class Student extends Person { // Ways to set the x in C
access it ‘class extends Object {}’
x = 10;
public void do_something() {
this.x = 10;
name=”Bob”; Object a = new A(); // subs9tu9on principle
age=70; Student inherits this but as a // Ways to set the x in B
height=1.70; private variable and so cannot super.x = 10;
} access it directly ((B)this).x = 10; Don’t write code like this. No-one will
This line doesn’t compile understand you!
} // Ways to set the x in A
((A)this.x = 10;
}
123 } 124
127 128
Objectives
Dynamic and static polymorphism
Problems that arise from multiple code
inheritance
Java interfaces provide multiple type
inheritance
Lecture 6:
Polymorphism and Multiple Inheritance
129 130
int eval(Expression e) {
C++ can do this. Java cannot
can be Literal, Mult or Plus
} 131 132
Polymorphic Concepts II The Canonical Example I
Dynamic polymorphism A drawing program that can draw circles,
squares, ovals and stars
Run the method in the child
It would presumably keep a list of all the
Must be done at run-time since that's when we drawing objects
know the child's type Option 1
Also known as ‘dynamic dispatch’ Circle Keep a list of Circle objects, a list of
+ draw()
Square objects,...
Square Iterate over each list drawing each
+ draw() object in turn
What has to change if we want to add
Student s = new Student(); Compiler looks in memory and Znds Oval a new shape?
Person p = (Person)s; that the object is really a Student + draw()
135
Demo 136
Demo
X Conceptually wrong
Polymorphism in OOP is an extremely important concept
that you need to make sure you understand...
BlobFish
X Dependency
between two
independent
concepts
137 138
Multiple Inheritance Multiple Inheritance Problems
Fish DrawableEn9ty If we multiple inherit, we capture Fish DrawableEn9ty What happens here? Which of
the concept we want the move() methods is inherited?
+ swim() + draw()
BlobFish inherits from both and + move() + move() Have to add some grammar to
is-a Fish and is-a DrawableEntity make it explicit
C++: C++:
class Fish {…} BlobFish *bf = new BlobFish();
class DrawableEn9ty {…} bf->Fish::move();
bf->DrawableEn9ty::move();
class BlobFish : public Fish,
public DrawableEn9ty {...} Yuk.
BlobFish But... BlobFish
This is like Zeld shadowing e.g.
+ swim() ????
+ draw() class A { class B extends A {
int x; int x;
} }
139 140
Objectives
Know the procedure for object initialisation
Difference between destructors and
finalisers
RAII and TWR
High level idea of a garbage collector
Lecture 7:
Lifecycle of an Object
147 148
149 150
Constructor Chaining Chaining without Default Constructors
When you construct an object of a type with parent What if your classes have explicit constructors that take
classes, we call the constructors of all of the parents arguments? You need to explicitly chain
in sequence Use super in Java:
Person
2. Call Person() Student
public Student () {
+Student()
super(“Bob”);
}
Student 3. Call Student()
Demo: NoDefaultConstructor
151 152
void UseRawPointer()
{
MyClass *mc = new MyClass(); class FileReader { int main(int argc, char ** argv) {
// ...use mc... public:
delete mc; FileReader f;
} // Constructor
Or auto-deleted when out of scope (C++): FileReader() { // Use object here
In C++ this means f = fopen(“myZle”,”r”); ...
create a new instance C++ }
void UseSmartPointer() } // object destructor called here
{ of MyClass on the stack // Destructor
MyClass mc; using the default ~FileReader() {
// ...use mc... constructor fclose(f);
} // mc deleted here }
private :
This is called RAII = Resource Acquisi9on Is Ini9alisa9on
FILE *Zle;
153 }
154
Objectives
Understand boxing and unboxing
A general idea about Java collections: Set,
List, Queue and Map
Fail-fast iterators
Lecture 8:
Java Collections and Object Comparison
159 160
161 162
Java's Collections Framework Sets
<<interface>> Important chunk of the class library <<interface>> Set
Collecon
Iterable
A collection of elements with no duplicates that
A collection is some sort of grouping of things represents the mathematical notion of a set B
A
(objects) TreeSet: objects stored in order C
<<interface>> Usually when we have some grouping we want HashSet: objects in unpredictable order but fast
Collecon to operate on (see Algorithms course)
to go through it (“iterate over it”) Iterable
Lists Queues
<<interface>> List <<interface>> Queue
C A
An ordered collection of elements that may contain An ordered collection of elements that may contain
duplicates duplicates and supports removal of elements from the head
of the queue
LinkedLIst: linked list of elements
B B offer() to add to the back and poll() to take from the front
ArrayList: array of elements (efficient access) C
LinkedList: supports the necessary functionality
Vector: Legacy, as ArrayList but threadsafe Iterable PriorityQueue: adds a notion of priority to the queue so more A
important stuff bubbles to the top
Collec9on B
List<Double> ll = new ArrayList<>();
ll.add(1.0); List
B
ll.add(0.5); Queue<Double> ll = new LinkedList<>();
ll.add(3.7); LinkedList ArrayList Vector ll.o(er(1.0);
ll.add(0.5); ll.o(er(0.5);
ll.get(1); // get element 2 (==3.7) ll.poll(); // 1.0
ll.poll(); // 0.5
legacy
good default
choice
165 166
Maps
Resizable Hash Table +
Hash Table Array Balanced Tree Linked List Linked List
Objectives
Comparing and Comparable
Error handling approaches
How to define your own exceptions
Pros and cons of exceptions
Lecture 9:
Error Handling Revisited
173 174
Comparing Primitives Reference Equality
> Greater Than r1==r2, r1!=r2
>= Greater than or equal to These test reference equality
== Equal to i.e. do the two references point ot the same chunk of
!= Not equal to memory?
< Less than Person p1 = new Person(“Bob”);
<= Less than or equal to Person p2 = new Person(“Bob”);
False (references di(er)
(p1==p2);
Clearly compare the value of a primitive
But what does (ref1==ref2) do??
(p1!=p2); True (references di(er)
…
ArrayList<Person> plist = …;
…
Collec9ons.sort(plist); // sorts by surname
Collec9ons.sort(plist, new AgeComparator()); // sorts by age
181 182
185 186
Flow Control During Exceptions Throwing Exceptions
When an exception is thrown, any code left to run in the try An exception is an object that has Exception as an
block is skipped ancestor
So you need to create it (with new) before throwing
double z=0.0;
boolean failed=false;
try {
z = divide(5,0);
double divide(double x, double y) throws DivideByZeroExcep9on {
z = 1.0;
if (y==0.0) throw new DivideByZeroExcep9on();
}
else return x/y;
catch(DivideByZeroExcep9on d) {
}
failed=true;
}
z=3.0;
System.out.println(z+” “+failed);
187 188
189 190
No acceptance tests for take-home test Evil I: Exceptions for Flow Control
Get in the habit of writing good tests At some level, throwing an exception is like a GOTO
Tempting to exploit this
There will be no acceptance tests for the try {
take-home test – you have to get it right on for (int i=0; ; i++) {
System.out.println(myarray[i]);
your own! }
}
catch (ArrayOutOfBoundsExcep9on ae) {
// This is expected
}
195 196
197 198
Objectives
Substitutability: covariance and
contravariance
Inner classes
Lambda!
Functional interfaces
Lecture 10:
Copying Objects
199 200
} } } } o.getShape() returns
a Triangle but Triangle
is a subtype of Polygon
void process(A o) { void process(A o) { and so by subs9tutability
drawShape(o.getShape()); drawShape(o.getShape()); we can pass it to
} } drawShape
process(new B()); process(new B());
201 202
205 206
Does not compile – the compiler knows it needs class InstanceInner { Instance inner classes are a member
something that extends object but it doesn’t int g() { of the outer object and so can access
know what it is! return x + 1; outer instance variables:
}
} Outer o = new Outer();
InstanceInner i = o.new InstanceInner()
207 } 208
209 210
Lambda Need a Functional Interface to use them
211 212
Objectives
Simple use of streams
What is a design pattern
Open-closed principle
Some example patterns
Lecture 11/12:
Design patterns
213 214
list.stream().Zlter(x->x>5).collect(Collectors.toList());
Demo: Readers
217 218
Demo: ComparatorStrategy
223 224
Demo: Ac9onListener
227 228
Observer in General End of course
The observer pattern allows an object to have multiple Don’t forget to keep practising with the
dependents and propagates updates to the dependents
automatically. practical exercises
You will receive email about the take-
home test organisation closer to the time
Thanks for listening!
229 230