CS61A Lecture 15 Object-Oriented Programming, Mutable Data
Total Page:16
File Type:pdf, Size:1020Kb
7/16/2012 COMPUTER SCIENCE IN THE NEWS CS61A Lecture 15 Object‐Oriented Programming, Mutable Data Structures Jom Magrotker UC Berkeley EECS July 12, 2012 http://www.iospress.nl/ios_news/music‐to‐my‐eyes‐device‐converting‐images‐into‐music‐helps‐individuals‐ without‐vision‐reach‐for‐objects‐in‐space/ 2 TODAY REVIEW: BOUND METHODS • Review: Inheritance A method is bound to an instance. Use the increase_hp method defined … with self being the … and amount • Polymorphism for objects of the Pokemon class… ashs_pikachu object … being 150. • Mutable Lists Pokemon.increase_hp(ashs_pikachu, 150) is equivalent to ashs_pikachu.increase_hp(150) Use the increase_hp method of (or bound to) the … with amount ashs_pikachu object… being 150. 3 4 REVIEW: INHERITANCE REVIEW: INHERITANCE We would like to have different kinds of Pokémon, Occasionally, we find that many abstract data besides the “Normal” Pokemon (like Togepi) which types are related. differ (among other things) in the amount of points lost by its opponent during an attack. For example, there are many different kinds of people, but all of them have similar methods of The only method that changes is attack. All the eating and sleeping. other methods remain the same. Can we avoid duplicating code for each of the different kinds? 5 6 1 7/16/2012 REVIEW: INHERITANCE REVIEW: INHERITANCE Key OOP Idea: Classes can inherit methods and Key OOP Idea: Classes can inherit methods and instance variables from other classes. instance variables from other classes. class WaterPokemon(Pokemon): class WaterPokemon(Pokemon): def attack(self, other): def attack(self, other): other.decrease_hp(75) other.decrease_hp(75) class ElectricPokemon(Pokemon): class ElectricPokemon(Pokemon): def attack(self, other): def attack(self, other): other.decrease_hp(60) other.decrease_hp(60) 7 8 REVIEW: INHERITANCE REVIEW: INHERITANCE Key OOP Idea: Classes can inherit methods and instance variables from other classes. >>> ashs_squirtle = WaterPokemon(‘Squirtle’, ‘Ash’, 314) class WaterPokemon(Pokemon): >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) def attack(self, other): >>> mistys_togepi.attack(ashs_squirtle) other.decrease_hp(75) >>> ashs_squirtle.get_hit_pts() 264 class ElectricPokemon(Pokemon): >>> ashs_squirtle.attack(mistys_togepi) def attack(self, other): >>> mistys_togepi.get_hit_pts() other.decrease_hp(60) 170 9 10 REVIEW: INHERITANCE REVIEW: INHERITANCE >>> ashs_squirtle = WaterPokemon(‘Squirtle’, >>> ashs_squirtle = WaterPokemon(‘Squirtle’, ‘Ash’, 314) ‘Ash’, 314) >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) >>> mistys_togepi.attack(ashs_squirtle) >>> mistys_togepi.attack(ashs_squirtle) >>> ashs_squirtle.get_hit_pts() mistys_togepi >>> ashs_squirtle.get_hit_pts() uses the attack 264 method from the 264 >>> ashs_squirtle.attack(mistys_togepi) Pokemon class. >>> ashs_squirtle.attack(mistys_togepi) >>> mistys_togepi.get_hit_pts() >>> mistys_togepi.get_hit_pts() ashs_squirtle 170 170 uses the attack method from the WaterPokemon class. 11 12 2 7/16/2012 REVIEW: INHERITANCE REVIEW: INHERITANCE >>> ashs_squirtle = WaterPokemon(‘Squirtle’, If the class of an object has the method or attribute of ‘Ash’, 314) interest, that particular method or attribute is used. >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) >>> mistys_togepi.attack(ashs_squirtle) Otherwise, the method or attribute of its parent is used. >>> ashs_squirtle.get_hit_pts() 264 >>> ashs_squirtle.attack(mistys_togepi) Inheritance can be many levels deep. >>> mistys_togepi.get_hit_pts() If the parent class does not have the method or attribute, 170 we check the parent of the parent class, and so on. 13 14 REVIEW: INHERITANCE REVIEW: INHERITANCE We can also both override a parent’s method or attribute and use the original parent’s method. class ElectricPokemon(Pokemon): ... Say that we want to modify the attacks of Electric Pokémon: when they attack another def attack(self, other): Pokémon, the other Pokémon loses the original Pokemon.attack(self, other) 50 HP, but the Electric Pokémon gets an increase self.increase_hp(10) of 10 HP. 15 16 PROPERTIES PROPERTIES One way is to define a new method. Python allows us to create attributes that are computed from other attributes, but need not class Pokemon: necessarily be instance variables. ... def complete_name(self): Say we want each Pokemon object to say its return self.owner + “’s ” + self.name complete name, constructed from its owner’s name and its own name. >>> ashs_pikachu.complete_name() ‘Ash’s Pikachu’ 17 18 3 7/16/2012 PROPERTIES ANNOUNCEMENTS Another way is to use the property decorator. • Project 2 is due Friday, July 13. • Homework 7 is due Saturday, July 14. class Pokemon: ... • Project 3 will be released this weekend, due @property Tuesday, July 24. def complete_name(self): • Your TA will distribute your graded midterms return self.owner + “’s ” + self.name in exchange for a completed survey. >>> ashs_pikachu.complete_name ‘Ash’s Pikachu’ 19 20 WHAT IS YOUR TYPE? POLYMORPHISM Write the method attack_all for the Pokemon class that takes a tuple of OOP enables us to easily make new abstract data Pokemon objects as its argument. When called on a Pokemon object, that types for different types of data. Pokémon will attack each of the Pokémon in the provided tuple. (Ignore the output printed by the attack method.) >>> type(ashs_pikachu) >>> ashs_pikachu = ElectricPokemon(‘Pikachu’, ‘Ash’, 300) <class ‘ElectricPokemon’> >>> ashs_squirtle = WaterPokemon(‘Squirtle’, ‘Ash’, 314) >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) >>> type(ashs_squirtle) >>> mistys_togepi.attack_all((ashs_pikachu, ashs_squirtle)) <class ‘WaterPokemon’> >>> ashs_pikachu.get_hit_pts() 250 >>> type(mistys_togepi) is Pokemon >>> ashs_squirtle.get_hit_pts() True 264 21 22 POLYMORPHISM POLYMORPHISM for other in others: self.attack(other) class Pokemon: ... other can be an object of many different data def attack_all(self, others): types: ElectricPokemon, WaterPokemon, for other in others: and Pokemon, for example. self.attack(other) 23 24 4 7/16/2012 POLYMORPHISM POLYMORPHISM for other in others: Write the method attacked_by for the Pokemon class that takes a tuple of self.attack(other) Pokemon objects as its argument. When called on a Pokemon object, that Pokémon will be attacked by each of the Pokémon in the provided tuple. attack can work on objects of many >>> ashs_pikachu = ElectricPokemon(‘Pikachu’, ‘Ash’, 300) different data types, without having to >>> ashs_squirtle = WaterPokemon(‘Squirtle’, ‘Ash’, 314) consider each data type separately. >>> mistys_togepi = Pokemon(‘Togepi’, ‘Misty’, 245) >>> ashs_squirtle.attacked_by((ashs_pikachu, mistys_togepi)) >>> ashs_squirtle.get_hit_pts() attack is polymorphic. 204 25 26 POLYMORPHISM POLYMORPHISM for other in others: other.attack(self) class Pokemon: ... other can be an object of many different data def attacked_by(self, others): types: ElectricPokemon, WaterPokemon, and Pokemon, for example. for other in others: other.attack(self) It can also be an object of any other class that has an attack method. 27 28 POLYMORPHISM POLYMORPHISM: HOW DOES + WORK? Key OOP idea: The same method can work on We try the type function on other expressions: data of different types. >>> type(9001) <class ‘int’> We have seen a polymorphic function before: >>> type(‘hello world’) >>> 3 + 4 <class ‘str’> 7 >>> type(3.0) >>> ‘hello’ + ‘ world’ <class ‘float’> ‘hello world’ 29 http://diaryofamadgayman.files.wordpress.com/2012/01/wait‐what.jpg 30 5 7/16/2012 POLYMORPHISM: HOW DOES + WORK? EVERYTHING IS AN OBJECT The dir function shows the attributes of a class: Everything (even numbers and strings) >>> dir(WaterPokemon) in Python is an object. ['__class__', '__delattr__', '__dict__', ..., 'attack', 'decrease_hp', 'get_hit_pts', 'get_name', 'get_owner', 'increase_hp', 'total_pokemon'] In particular, every class (int, str, The green attributes were defined inside (and inherited from) the Pokemon class and the blue attribute was defined directly Pokemon, ...) is a subclass of a built‐in inside the WaterPokemon class. object class. Where did the red attributes come from? 31 32 EVERYTHING IS AN OBJECT EVERYTHING IS AN OBJECT The object class provides extra attributes that Since everything is an object, this means we enable polymorphic operators like + to work on should be able to call methods on everything, many different forms of data. including numbers: >>> dir(object) ['__class__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', >>> 3 + 4 '__getattribute__', '__gt__', '__hash__', 7 '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', >>> (3).__add__(4) '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__'] 7 33 34 EVERYTHING IS AN OBJECT EVERYTHING IS AN OBJECT Python converts the expression Python converts the expression 3 + 4 ‘hello’ + ‘ world’ to to (3).__add__(4) (‘hello’).__add__(‘ world’) 3 is an int object. The int class has an ‘hello’ is a str The str class also has a __add__ method. object. different __add__ method. 35 36 6 7/16/2012 EVERYTHING IS AN OBJECT EVERYTHING IS AN OBJECT If a class has an __add__ method, we can use the + Implement the method __gt__ for the Pokemon operator on two objects of the class. class that will allow us to check if one Pokémon is “greater” than another, which means that it has Similarly, for example, (strictly) more HP than the other. 4 > 3 is converted to (4).__gt__(3) >>> ashs_pikachu = ElectricPokemon(‘Pikachu’, 4 <= 3 is converted