360 likes | 489 Views
203.1120. Welcome to OOP course!. Course details. Teaching team Li-Tal Mashiach and Moran Lefler Grading: 30% - Project in 3 parts 70% - Final exam Contact me: E-mail: litalma@cs.technion.ac.il (Subject: OOP) Office hours: Jacobs 409, after the lecture
E N D
203.1120 Welcome to OOP course!
Course details • Teaching team • Li-Tal Mashiach and Moran Lefler • Grading: • 30% - Project in 3 parts • 70% - Final exam • Contact me: • E-mail: litalma@cs.technion.ac.il (Subject: OOP) • Office hours: Jacobs 409, after the lecture • Lecture slides will be available on the course site http://cs.haifa.ac.il/courses/prog_tech/course_info.html
Bibliography • B. Stroustrup, The C++ Programming Language • S. Lippman and J. LaJoie, C++ Primer • S. Meyers, Effective C++ • B. Eckel, Thinking in C++
Why OOP? • “Software Crisis”: • Too many modules… • Too many functions… • Too many variables… • Better organization of the code • Smaller code • Reuse of code • Easier design, analysis and implementation • User vs. Programmer
Why C++? • Object-oriented extension of C • Any C program is also valid in C++ • Remains of non-OOP characteristics (global variables and functions, main functions…) • C++ main elements: • Encapsulation (כימוס( • Template (תבניות( • Inheritance (הורשה( • Polymorphism (רב צורתיות( • Exceptions (חריגות(
A bit of history • Time: 1962 • Place: Norwegian Computing Center, Oslo • Kristen Nygaard and Ole-Johan Dahl work on simulation of ship movement in fjords • Many kinds of ships, each with its own characteristics…
How it would have looked like? typedef struct {float sailArea;…} SailBoatData; typedef struct {float engineVolume;…} MotorBoatData; void move(Environment *env, Location *loc, int boatKind, void *boatData){ if (boatKind == SAIL_BOAT){ sailArea = ((SailBoatData*)boatData)->sailArea; … //compute movement using sail area, env, and loc }else if (boatKind == MOTOR_BOAT){ engineVolume = ((MotorBoatData*)boatData)->engineVolume; … //compute movement using engine volume, env, and loc } else … //handle other kinds of boats { void turn(Direction * dir, int boatKind, void *boatData){ if (boatKind == SAIL_BOAT){ … //handle sail boat case }else if (boatKind == MOTOR_BOAT){ … //handle the motor boat case } else … //handle other kinds of boats } //usage: int main(){ … //set up env. and boat data while(…){ move(env, loc, kind, data); } }
What are the problems? • Difficult to distribute the work within team • Team member responsible for • Kind of boats? • Must add code to every function • Particular operation? • Must be expert in all boat kinds • Difficult to share code between boat types • Difficult to add new boat types and operations • Difficult to maintain
A bit of history (cont.) • Time: 1962 • Place: Norwegian Computing Center, Oslo • Kristen Nygaard and Ole-Johan Dahl work on simulation of ship movement in fjords • Many kinds of ships, each with its own characteristics… • Solution: group the ships into classes • Each class of ships type has its own data and behavior • Simula 67
How it would have looked like (2)? class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} } class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
How it would have looked like (2)? “private” means the following elements are visible only inside the Boat class class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} }; class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } “public” means anyone can use the following elements (like in struct) //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
How it would have looked like (2)? Here we declare that every Boat can move (i.e., has a method move) class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} }; class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } And this is the C++ way to say that we are not yet going to specify how the boats move //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
How it would have looked like (2)? class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} }; class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } This means that a SailBoat is a Boat and can do whatever a Boat can do Specifically, this method describes how SailBoat moves //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
How it would have looked like (2)? class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} }; class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } We know every boat can move, so we call the move method. At runtime, either move() from SailBoat or move() from MotorBoat will be called, based on boat’s actual type //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
How it would have looked like (2)? class Boat { private: Location loc; public: void move (Environment *env) = 0; void turn (Direction *dir) = 0; Location getLocation(){return loc;} }; class SailBoat: public Boat { private: float sailArea; public: void move(Environment *env){…} void turn (Direction *dir){…} } class MotorBoat: public Boat { private: float engineVolume; public: void move(Environment *env){…} void turn (Direction *dir){…} } //usage: int main(){ Boat boat= …; Environment * env = …; while(…){ boat.move(env); } }
What did we achieve? • Described the problem in terms natural to the problem • Pre-OO, we talked in terms of ints and floats, like the computer • Now we can talk in terms of boats and maneuvers • Partitioned the problem into encapsulated sub-problems with well-defined interfaces • Adding new boat types is easy • And so is changing boat behavior
OOP – The Three Big Ideas • Encapsulation • Hide your data – then nobody can change it by mistake • private: Location loc; • Hide your algorithms – then you may change them at any time • Implementation of move(…) within each type • Inheritance • Shared behavior implemented just once • Boat::getLocation() • Polymorphism • Provide different method implementations in different types • Allows, when using objects, to keep to the right level of details • main(){… boat.move(env);…}
The OO view of the world • The world is a set of objects interacting with each other :SailBoat :Environment move() getLocation() computeWind(Location) computeCurrent(Location)
An aside: UML • Unified Modeling Language • For spec, tutorials, etc. visit http://www.uml.org/ • Generic description of classes, object interactions, etc. :SailBoat :Environment This is an interaction diagram move() getLocation() The interacting objects computeWind(Location) This time is spent executing computeWind(Location) computeCurrent(Location) Call computeCurrent(Location) Return a value from computeCurrent(Location)
Back to the OO view • The world is a set of objects interacting with each other • Each object is an instance of a class • Same behavior, different data • Classes may inherit data and functionality from other classes
Inheritance tree Boat PaddleBoat SailBoat MotorBoat AircraftCarrier
UML Class diagram Boat getLocation() move(Env) turn(Dir) Data Location … … Functionality Hollow arrow means inheritance (“is-a” relationship) SailBoat float sailArea move(Env) turn(Dir) MotorBoat float engineVolume move(Env) turn(Dir) “Has-a” relationship
Data types • Built-in data types: int, float, … • Have data • E.g., float has exponent, mantissa, sign bit • Have operations defined on them • +, !=, … • How is the float ‘+’ implemented? Don’t know • Goal: user-defined types that behave in the same way • Create, initialize, copy instances • Store state • Perform operations
Example: StringClass declaration class String{ char* chars; public: char* getString(); void setString(char* value); } String.h int main(){ String str; str.setString(“Hi everyone”); printf(“%s\n”, str.getString()); }
Example: StringClass definition class String{ char* chars; public: char* getString(); void setString(char* value); } String.h -- reminder char* String::getString(){return chars;} void String::setString(char* value){ int length = strlen(value); chars = new char[length+1]; strcpy(value, chars); } String.cpp
Encapsulation • Recall some of our objectives • Develop classes independently • Facilitate implementation changes • Example: • Replace float sailArea;with float sailAreas[]; • Have to find everyone who uses sailArea and figure out how to replace the usage --Potential for bugs! • But: if a field is not accessible outside the class, it cannot be used there • Data hiding
C++: Limiting data visibility • Visibility of class members limited in class declaration • private – accessible only within the class • protected– accessible only within the class and classes that inherit from it • public – accessible anywhere • private is the default access levelclass C{int i; //private by default private:int j1;int j2;protected:int k;public:int l;} • This is just the basics… class String{ char* chars; public: char* getString(); void setString(char* value); }
Example: String (cont.) • Let’s add string comparison! class String{ char* chars; public: char* getString(); void setString(char* value); int equals(String *other); } String.h int main(){ String str1, str2; str1.setString(“Hi everyone”); str2.setString(“Hello”); if (str1.equals(str2) ==1) printf(“equal!\n”); }
String comparison: 1st attempt class String{ char* chars; public: char* getString(); void setString(char* value); int equals(String *other); } String.h char* String::getString(){return chars;} void String::setString(char* value){…} int String::equals(String *other){ if (strcmp(chars, other->chars) == 0) return 1; return 0; } String.cpp
Optimizing comparison • Observation: • Most of the strcmps are likely false • Let’s improve performance by saving strcmps • Run strcmponly on strings of equal length • Cache string lengths
String comparison: 2nd attempt class String{ char* chars; int length; public: char* getString(); void setString(char* value); int equals(String *other); } String.h
String comparison: 2nd attempt char* String::getString(){return chars;} void String::setString(char* value){ int length = strlen(value); chars = new char[length+1]; strcpy(value, chars); } int String::equals(String *other){ if (length != other->length) return 0; if (strcmp(chars, other->chars) == 0) return 1; return 0; } String.cpp
String comparison: 2nd attempt • Changes to the main() function:
String comparison: Summary • Defined a type and operations on it • Internal data representation was concealed from the class clients • Changed implementation without touching the client code