Download Python OOP: Classes, Encapsulation, Inheritance, Polymorphism & Special Methods - Prof. De and more Lab Reports Computer Systems Networking and Telecommunications in PDF only on Docsity!
CSCI 553: Networking III
Unix Network Programming
Spring 2007
Object Oriented Programming
Today's Agenda
A Word about the Test
Books, Notes & Account
Assigned Seats
Study Questions
Objects & Testing
Set up .bashrc for JUnit usage
Lab 05
Finish 5.1 before leaving
Objects to the Rescue
Object-oriented programming (OOP) solves both problems
Each object knows how to update itself
Don't have to change old code when adding new types of things
No chance of calling the wrong function
Seems like a small change, but it allows programmers to think and design at a
higher level
Also allows them to make more powerful mistakes…
Ideas apply to all modern languages
But there's more variation in form than there is with loops, conditionals, and
functions
for time in simulation_period: for thing in world: thing.update(time)
Abstract Data Types
Modern languages encourage programmers to
define abstract data types (ADTs)
“Abstract” because they hide the details of their
implementation
Programmers interact with them through a limited
set of operations, rather than by manipulating data
directly
Fewer things can go wrong
Easier to read resulting code
Makes code easier to maintain, since internals can be
changed without changing calling code
Classes and Instances
Figure 1: Memory Model for Classes and Objects
Defining a Class
Define a class in Python using the class keyword
Name of the new class is usually followed by object in parentheses
We'll see other options later
Then ":" and an indented block containing the class's contents
class Empty(object):
pass
pass means “do nothing”, i.e., create an empty class
Not particularly useful, but you have to start somewhere
Methods
Give the class methods by defining functions inside it
The object itself is always passed to the method as its first argument
Universally called self
Unlike this in C++ and Java, the name is just a convention
But everyone uses it, and you should too
object.method(argument) is equivalent to:
Find the class C that object is an instance of
Call C.method(object, argument)
class Greeting(object): def say(self, name): print 'Hello, %s!' % name
if name == 'main': greet = Greeting() greet.say('object')
Hello, object!
Creating Members
Every object is a new scope for variable
names
Just like a module, or a function call
The values in an object's scope are its
members
Create members use dotted notation: self.x = 3
Gives the current object a new member x with the
value 3
Or overwrites the existing member x with the value 3
Creating Members
Figure 2: Creating a Simple Point
Encapsulation
Encapsulation is one of the three defining principles of OOP
(^) Programs are much easier to write, read, and maintain if object members are only ever accessed by methods
But unlike C++, Java, and C#, Python doesn't allow programmers to hide methods
or data members
p = Point() p.x = 3. p.y = 4. print 'point is', p.get_values() point is (3.5, 4.25)
Any function or method can see and modify any object's internals
(^) Resist the temptation to program this way! (^) If you manipulate an object's internals directly, you have to change your program when you change the object's implementation
Constructors
class Point(object): def init(self, x=0, y=0): self.reset(x, y) def reset(self, x, y): assert (type(x) is int) and (x >= 0), 'x is not non-negative integer' assert (type(y) is int) and (y >= 0), 'y is not non-negative integer' self.x = x self.y = y def get(self): return (self.x, self.y) def norm(self): return math.sqrt(self.x ** 2 + self.y ** 2)
if name == 'main': p = Point(1, 1) print 'point is initially', p.get() p.reset(2, 2) print 'p moved to', p.get() point is initially (1, 1) p moved to (2, 2)
Constructor Style
A class can only have one constructor
Some languages allow classes to have several, distinguished by
argument types
But since Python doesn't use type declarations, this wouldn't work
It's good style to create all of the object's members in the
constructor
So that people only have to look in one place to find what members
exist
Note how the class checks values before changing the
object's state
Remember: fail early, fail often
New Classes from Old
Suppose we have a class Organism that represents living things
Common name, scientific name, …
Want to create a class Mammal
Body temperature, gestation period, …
Wrong: copy Organism's definition and add more members and
methods
“Anything repeated in two or more places will eventually be wrong in at
least one.”
Right: use inheritance
The second defining principle of OOP
Derive a child class from a parent
The child has all the members and methods of its parents, plus whatever
else we give it
Inheritance Example
class Organism(object): def init(self, common_name, sci_name): self.common_name = common_name self.sci_name = sci_name def get_common_name(self): return self.common_name def get_sci_name(self): return self.sci_name def str(self): return '%s (%s)' % (self.common_name, self.sci_name)
class Mammal(Organism): def init(self, common_name, sci_name, body_temp, gest_period): Organism.init(self, common_name, sci_name) self.body_temp = body_temp self.gest_period = gest_period def get_body_temp(self): return self.body_temp def get_gest_period(self): return self.gest_period def str(self): extra = ' %4.2f degrees / %d days' % (self.body_temp, self.gest_period) return Organism.str(self) + extra
if name == 'main': creature = Mammal('wolf', 'canis lupus', 38.7, 63) print creature
wolf (canis lupus) 38.70 degrees / 63 days