Objects
=======
History - Simula 67
Kristen Nygaard
Ole-Johan Dahl
Simulation programming languages
Key ideas
Class - group of objects that behave the same way
(not all OO languages have classes, though)
Inheritance - related objects share behavior
(very important, but not quite universal)
Dispatch - each object knows how to do operations itself
This one is most important/distinguishing
Encapsulation (later) - hide internals of an object, especially its representation
"private" members only accessible from within the same class
"protected" members only accessible from the class and subclasses
Similar to module systems
Subtyping - treat one object as if it were another
inheritance usually implies subtyping (it's bad style to not) but you can have subtyping without inheritance
It turns out that simulating the world is useful not just in simulation software, but in a lot of application software as well - "objects" represent things we want to model in the world
Inheritance provides a lot of reuse.
Let's look at an example (have them write it)
public class ArrayList {
public void add(A elem) { ... }
public void addAll(List elems) {
for (A e : elems) {
add(e);
}
}
public boolean isMember(A elem) { ... }
}
public class Set extends ArrayList {
public void add(A elem) {
if (!isMember(elem))
super.add(elem);
}
// have students implement addAll here!
// do we need to override both add and addAll?
// depends on if addAll calls add
// "fragile base class problem" - changes to class can break subclasses
// an example of how inheritance causes tight coupling along with reuse
// also note: a Set is not really a List! add behaves differently
// notion of "behavioral subtyping" - subtype should obey the specification of supertype, in this case that adding an element increases the size of the list (broken by Set)
}
// better design uses composition
public class Set {
private ArrayList elements = new ArrayList();
public void add(A elem) {
if (!isMember(elem))
elements.add(elem);
}
public void union(Set other) {
elements.addAll(other.elements);
}
}
Dispatch provides interoperability
List interface
Implementations: ArrayList, LinkedList
List.addAll(List other) - can be implemented in a way that is agnostic of the other list's implementation, allowing different kinds of lists to work together
This is useful even for data structures like lists
Where it is essential is frameworks
OOP became popular becase of GUIs
Different widgets need to interoperate on a screen
Today: different apps need to interoperate on your phone
mostly these are implemented with OO
but even those that are not use OO-style interfaces
OO interfaces are even used to implement file systems on Linux!
Smalltalk (1972)
Designed for "children of all ages"
One of the most elegant language designs in existance, right up there with Scheme
Self
prototype based - make a sample object, other objects delegate to it
JavaScript is prototype-based
Smalltalk and Self developed key optimization schemes used in Java/JS JITs
Implementation of JavaScript Dispatch
Representation see https://chromium.googlesource.com/external/github.com/v8/v8.wiki/+/60dc23b22b18adc6a8902bd9693e386a3748040a/Design-Elements.md
Inline caching
Wikipedia: https://en.wikipedia.org/wiki/Inline_caching
Original paper: http://web.cs.ucla.edu/~palsberg/course/cs232/papers/DeutschSchiffman-popl84.pdf
v0 :=
call lookup_method
lookup_method looks up the method_symbol in the class of this
discovering class C and method m
and rewrites code inline to:
v0 := v_this.virt_class
call m
implementation of m:
if v0 != C then goto lookup
// continue with actual method implementation
Implementation of C++ Dispatch
see textbook