![Page 1: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/1.jpg)
1
Lecture 14
Data AbstractionObjects, inheritance, prototypes
Ras Bodik Shaon Barman
Thibaud Hottelier
Hack Your Language!CS164: Introduction to Programming Languages and Compilers, Spring 2012UC Berkeley
![Page 2: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/2.jpg)
AnnouncementRas will hold a review tomorrow 11-12 in the Woz
topics: parsing and coroutines; bring your questions
Project Proposals due Sunday
I will post remaining slides tonight
2
![Page 3: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/3.jpg)
Where are we?Our new constructs concerned control abstraction:→ hiding complex (changes) to program control flow under suitable programming constructs
- lazy iterators, built on coroutines- backtracking in regexes, built with coroutines- search for a proof tree, hidden in the Prolog
interpreter
There must also be data abstraction. A few examples: 3
![Page 4: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/4.jpg)
Objects (review from CS61B)
Why objects?abstraction: hide implementation under encapsulation
Why inheritance?reuse: specialization of an object’s behavior reuses its code
4
![Page 5: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/5.jpg)
Our Design RationaleWe want to support objects
What is the minimum base language to support objects?
Our language already supports closureswhich are similar in that they carry state and code
Can we build objects from this existing mechanism?
rather than adding support for objects into base language?
5
![Page 6: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/6.jpg)
Single-Method Approach
6
![Page 7: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/7.jpg)
We have seen closure-based objects alreadyWhere did we use closures as objects?
Iterators are single-method objectson each call, iterators return the next element and “advance” their iterator state
7
![Page 8: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/8.jpg)
Use of single-method object
d = newObject(0) print d("get") --> 0 d("set", 10) print d("get") --> 10
8
![Page 9: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/9.jpg)
Multi-method object represented as a closurefunction newObject (value) function (action, v) { if (action == "get“) { value } else if (action == "set“) { value = v } else { error("invalid action")} } } 9
![Page 10: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/10.jpg)
Objects as tables
10
![Page 11: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/11.jpg)
Recall tablesCreate a table
{}{ key1 = value1, key2 = value2 }
Add a key-value pair to table (or overwrite a k/w pair)
t = {}t[key] = value
Read a value given a keyx = t[key]
11
![Page 12: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/12.jpg)
Object as a table of attributesAccount = {balance = 0}
Account[“withdraw”] = function(v) { Account[“balance”] = Account[“balance”] - v}
Account[“withdraw”](100.00)
What syntactic sugar we add to clean this up?
12
![Page 13: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/13.jpg)
Sugar design
13
![Page 14: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/14.jpg)
Syntactic sugarp.f → p[“f”] → get(p, “f”)
Careful: we need to distinguish between reading p.f
translated to getand writing into p.f
translated to put
14
![Page 15: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/15.jpg)
Object as a table of attributes, revisitedAccount = {balance = 0}
function Account.withdraw (v) { Account.balance = Account.balance - v}Account.withdraw(100.00)
a = Account Account = nil
a.withdraw(100.00) -- ERROR!
15
![Page 16: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/16.jpg)
Introduce selfAccount = {balance = 0}function Account.withdraw (self, v) { self.balance = self.balance - v}
a1 = AccountAccount = nila1.withdraw(a1, 100.00) -- OK
a2 = {balance=0, withdraw = Account.withdraw}a2.withdraw(a2, 260.00)
16
![Page 17: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/17.jpg)
The colon notationfunction Account:withdraw (v) { self.balance = self.balance - v} a:withdraw(100.00)
How to desugar?
17
![Page 18: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/18.jpg)
Rewriting E:ID()
18
![Page 19: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/19.jpg)
DiscussionWhat is the inefficiency of our current objects?
too much space wasted by each object carrying its objects and fields that are constant across many objects
19
![Page 20: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/20.jpg)
Meta-Methods
20
![Page 21: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/21.jpg)
The __index metamethodWhen a lookup of a field fails, interpreter consults the __index field:
setmetatable(a, {__index = b})
21
![Page 22: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/22.jpg)
Prototypespoor man’s classes
22
![Page 23: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/23.jpg)
What runtime setup do we want?A prototype is an object that behaves like a class
23
![Page 24: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/24.jpg)
Create an objectfunction Account:new (o) { -- create object if user does not provide one o = o or {} setmetatable(o,self) self.__index = self o}
a = Account:new({balance = 0})a:deposit(100.00)
24
![Page 25: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/25.jpg)
Note about cs164 projectsWe may decide not to use metatables, just the __index field. The code
function Account:new (o) { o = o or {} setmetatable(o,self) self.__index = self o}
Would become function Account:new (o) { o = o or {} o.__index = self o } 25
![Page 26: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/26.jpg)
Inheritance
26
![Page 27: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/27.jpg)
Inheritance allows reuse of code …… by specializing existing class (prototype)
How to accomplish this with a little “code wiring”?
Let’s draw the desired run-time organization:Assume class A, subclass B, and b an instance of B
27
![Page 28: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/28.jpg)
Must set this up in the constructorTasks that we need to perform
28
![Page 29: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/29.jpg)
Define a classAccount = {balance = 0} function Account:new (o) { o = o or {} setmetatable(o, sel) self.__index = self o}function Account:deposit (v) { self.balance = self.balance + v } function Account:withdraw (v) { if (v > self.balance) { error"insufficient funds" } self.balance = self.balance - v} 29
![Page 30: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/30.jpg)
Create subclass of AccountSpecialAccount = Account:new()s = SpecialAccount:new({limit=1000.00})s:deposit(100.00)
function SpecialAccount:withdraw (v) if (v - self.balance >= self:getLimit()) { error"insufficient funds" } self.balance = self.balance - v}
function SpecialAccount:getLimit () { self.limit or 0}
30
![Page 31: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/31.jpg)
Discussion of prototype-based inheritance Notice the sharing:
constant-value object attributes (fields) remain stored in the prototype until they are assigned.After assignment, the object stores the attribute rather than finding it in the prototype
31
![Page 32: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/32.jpg)
Multiple Inheritance
32
![Page 33: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/33.jpg)
“Privacy”protecting the implementation
33
![Page 34: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/34.jpg)
Our goalSupport large programmer teams.Bad scenario:
– programmer A implements an object O– programmer B uses O relying on internal details
of O– programmer A changes how O is implemented– the program now crashes on customer’s
machineHow do OO languages address this problem?
- private fields
34
![Page 35: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/35.jpg)
Language Design ExcerciseYour task: design an analogue of private fields
Lua/164 supports meta-programmingit should allow building your own private fields
35
![Page 36: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/36.jpg)
Object is a table of methods function newAccount (initialBalance) def self = {balance = initialBalance} def withdraw (v) { self.balance = self.balance – v } def deposit (v) { self.balance = self.balance + v } def getBalance () { self.balance } { withdraw = withdraw, deposit = deposit, getBalance = getBalance} } 36
![Page 37: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/37.jpg)
Use of this object
acc1 = newAccount(100.00)acc1.withdraw(40.00)print acc1.getBalance() --> 60
37
![Page 38: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/38.jpg)
Discussion of Table of methods approachThis approach supports private data
Users of the object cannot access the balance except via objects methods.
Why is this useful?implementation is hidden in functions and can be swappedbecause the client of this object is not reading its fields
How can we extend the object with private methods?
38
![Page 39: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/39.jpg)
We can safely change the implementationfunction newAccount (initialBalance) def self = { balance = initialBalance, LIM = 1000, } def extra() { if (self.balance > self.LIM) { self.balance * 0.1 } else { 0 } } def getBalance () { self.balance + extra() } // as before { /* methods */ }}
39
![Page 40: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/40.jpg)
More discussionCan the table-of-methods objects be extendedto support inheritance?
40
![Page 41: Lecture 14 Data Abstraction O bjects, inheritance, prototypes](https://reader036.vdocuments.net/reader036/viewer/2022062520/56816301550346895dd376c1/html5/thumbnails/41.jpg)
ReadingRequired:
Chapter 16 in PiL
41