Overview of OOP

Dr. Zhang COSC 1436 Summer, 2018 7/17/2018 Review Data Structures (list, dictionary, tuples, sets, strings) • Lists are enclosed in square brackets: l = [1, 2, "a"] (access by index, is mutable sequence) • Tuples are enclosed in parentheses: t = (1, 2, "a") (access by index, is immutable sequence) • Dictionaries are built with curly brackets: = {"a":1, "b":2} (access by key, dictionary is mutable) • Sets can be made using the set() built in function set1={1,2,3,4} ( All elements in a set must be unique, set is mutable) Review Data Structures (list, dictionary, tuples, sets, strings) • PYTHON OBJECTS: MUTABLE VS. IMMUTABLE o The following are immutable objects: (can be dictionary key) o Numeric types: int, float, complex o string o tuple o frozen set o Bytes o The following objects are mutable (can not be dictionary key) o list o dictionary o set o byte array About Pickle

• The Concept • In chapter 6, we learn how to store data in a text file. Sometimes you need to store the contents of a complex object, such as a dictionary or a set, to a file. The easiest way to save an object to a file is to serialized , it is converted to a stream of bytes that can be easily stored in a file for later retrieval. • In python, the processing of serializing an object is referred to as pickling About Pickle import pickle def main(): out_file = open('person.dat','wb') ## Open a file for binary writing #Create a dictionary person={'Hong Sun':'[email protected]','Luke Smith':'[email protected]'} #call pickle dump method to pickle the object and write it to the file pickle.dump(person,out_file) #clase the file out_file.close() ## Open a file for binary reading in_file = open('person.dat','rb') ## call pick load method and assign to a dictionary person_new=pickle.load(in_file) print(person_new) #print the dictionary in_file.close() #close the file main() Difference between Procedure Oriented and Object Oriented Programming

• Procedural programming creates a step by step program that guides the application through a sequence of instructions. Each instruction is executed in order. • Procedural programming also focuses on the idea that all algorithms are executed with functions and data that the programmer has access to and is able to change. • Object-Oriented programming is much more similar to the way the real world works; it is analogous to the human brain. Each program is made up of many entities called objects. • Instead, a message must be sent requesting the data, just like people must ask one another for information; we cannot see inside each other’s heads. Features of OOP

• Ability to simulate real-world event much more effectively • Code is reusable thus less code may have to be written • Data becomes active • Better able to create GUI (graphical user interface) applications • Programmers are able to produce faster, more accurate and better- written applications Fundamental concepts of OOP in Python

The four major principles of object orientation are: • Encapsulation • Data Abstraction • Inheritance • Polymorphism Fundamental concepts of OOP in Python Encapsulation • Encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition. Typically, only the object’s own methods can directly inspect or manipulate its fields. • Encapsulation is the hiding of data implementation by restricting access to accessors and mutators. • An accessor is a method that is used to ask an object about itself. In OOP, these are usually in the form of properties, which have a get method, which is an accessor method. However, accessor methods are not restricted to properties and can be any public method that gives information about the state of the object. • A Mutator is public method that is used to modify the state of an object, while hiding the implementation of exactly how the data gets modified. It’s the set method that lets the caller modify the member data behind the scenes. • Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state. This type of data protection and implementation protection is called Encapsulation. • A benefit of encapsulation is that it can reduce system complexity. Accessor or Mutator method example

• • class MyClass(): • def __init__(self): • self.__my_attr = 3 • def set_my_attr(self,val): • self.__my_attr = val • def get_my_attr(self): • return self.__my_attr • obj1 = MyClass() • print (obj1.get_my_attr()) • obj1.set_my_attr(7) • print (obj1.get_my_attr()) • n the example above,

• The methods obj1.get_my_attr() is Accessor methods since it doesn’t alter the object a in any sense, but only pulls the relevant information. But obj1.set_my_attr(7) is a mutator method, since it effectively changes the object to a new one. Fundamental concepts of OOP in Python Data Abstraction • Data abstraction and encapsulation are closely tied together, because a simple definition of data abstraction is the development of classes, objects, types in terms of their interfaces and functionality, instead of their implementation details. Abstraction denotes a model, a view, or some other focused representation for an actual item. • In short, data abstraction is nothing more than the implementation of an object that contains the same essential properties and actions we can find in the original object we are representing. Fundamental concepts of OOP in Python Inheritance • Inheritance is a way to reuse code of existing objects, or to establish a subtype from an existing object, or both, depending upon programming language support. In classical inheritance where objects are defined by classes, classes can inherit attributes and behavior from pre-existing classes called base classes, superclasses, parent classes or ancestor classes. The resulting classes are known as derived classes, subclasses or child classes. The relationships of classes through inheritance gives rise to a hierarchy. Fundamental concepts of OOP in Python Polymorphism • Polymorphism in Latin word which made up of ‘ploy’ means many and ‘morphs’ means forms • From the Greek , Polymorphism means many(poly) shapes (morph) • This is something similar to a word having several different meanings depending on the context • Generally speaking, polymorphism means that a method or function is able to cope with different types of input. Fundamental concepts of OOP in Python

Polymorphism Overview of OOP

What is a Class? • A class is a special data type which defines how to build a certain kind of object. • The class also stores some data items that are shared by all the instances of this class • Instances are objects that are created which follow the definition given inside of the class • Python doesn’t use separate class interface definitions as in some languages You just define the class and then use it Overview of OOP

What is an Object..? • Objects are the basic run-time entities in an object- oriented system. • They may represent a person, a place, a bank account, a table of data or any item that the program must handle. • When a program is executed the objects interact by sending messages to one another. • Objects have two components: - Data (i.e., attributes) - Behaviors (i.e., methods) • Object is an instance of a class Overview of OOP Terminology Overview of OOP

• Defining a Class in Python • Like function definitions begin with the keyword def, in Python, we define a class using the keyword class. • class Employee: ## 'Common base class for all employees' empCount = 0 def __init__(self, name, salary): self.name = name self.salary = salary Employee.empCount += 1 def displayCount(self): print (“Total Employees: “, Employee.empCount) def displayEmployee(self): print ("Name : ", self.name, ", Salary: ", self.salary) Overview of OOP

Methods in Classes • Define a method in a class by including function definitions within the scope of the class block • There must be a special first argument self in all of method definitions which gets bound to the calling instance • There is usually a special method called __init__ in most classes • __str__ is a special method, like __init__ , that is supposed to return a string representation of an object Overview of OOP

Instantiating Objects with ‘__init__’ • _init__ serves as initialization method that Python calls when you create a new instance of this class. Usually does some initialization work • An __init__ method can take any number of arguments • However, the first argument self in the definition of __init__ is special Overview of OOP

Self • the first argument of every method is a reference to the current instance of the class • By convention, we name this argument self • In __init__, self refers to the object currently being created; so, in other class methods, it refers to the instance whose method was called • Similar to the keyword this in Java or C++ But Python uses self more often than Java uses this • You do not give a value for this parameter(self) when you call the method, Python will provide it. Continue… Overview of OOP

Self Continue… • Although you must specify self explicitly when defining the method, you don’t include it when calling the method. • Python passes it for you automatically Defining a method: Calling a method: (this code inside a class definition.) • def get_age(self, num): self.age = num example :bankaccount.py Overview of OOP

Deleting instances: • No Need to “free” • When you are done with an object, you don’t have to delete or free it explicitly. • Python has automatic garbage collection. • Python will automatically detect when all of the references to a piece of memory have gone out of scope. Automatically frees that memory. • Generally works well, few memory leaks • There’s also no “destructor” method for classes Overview of OOP Overview of OOP • Important advantage of OOP consists in the encapsulation of data. We can say that object-oriented programming relies heavily on encapsulation. • The terms encapsulation and abstraction (also data hiding) are often used as synonyms. They are nearly synonymous, i.e. abstraction is achieved though encapsulation. • Data hiding and encapsulation are the same concept, so it's correct to use them as synonyms • Generally speaking encapsulation is the mechanism for restricting the access to some of an objects' components, this means, that the internal representation of an object can't be seen from outside of the objects definition. Overview of OOP • Access to this data is typically only achieved through special methods: Getters and Setters • By using solely get() and set() methods, we can make sure that the internal data cannot be accidentally set into an inconsistent or invalid state. • C++, Java, and C# rely on the public, private, and protected keywords in order to implement variable scoping and encapsulation • It's nearly always possible to circumvent this protection mechanism Overview of OOP

Public, Protected and Private Data • If an identifier doesn't start with an underscore character "_" it can be accessed from outside, i.e. the value can be read and changed • Data can be protected by making members private or protected. Instance variable names starting with two underscore characters cannot be accessed from outside of the class. Overview of OOP

Public, Protected and Private Data • If an identifier is only preceded by one underscore character, it is a protected member. • Protected members can be accessed like public members from outside of class Overview of OOP

Public, Protected and Private Data Overview of OOP

Public, Protected and Private Data Fundamental concepts of OOP in Python Polymorphism • The polymorphism is the process of using an operator or function in different ways for different data input. In practical terms, polymorphism means that if class B inherits from class A, it doesn’t have to inherit everything about class A; it can do some of the things that class A does differently.

• Similarly, the "add" operation is defined in many mathematical entities, but in particular cases you "add" according to specific rules: 1+1 = 2, but (1+2i)+(2-9i)=(3-7i).

• Polymorphic behavior allows you to specify common methods in an "abstract" level, and implement them in particular instances. Overview of OOP Polymorphism • The polymorphism is the process of using an operator or function in different ways for different data input. In practical terms, polymorphism means that if class B inherits from class A, it doesn’t have to inherit everything about class A; it can do some of the things that class A does differently. • There are two kinds of Polymorphism • Overloading : Two or more methods with different signatures (stay in same class) • Overriding: Replacing an inherited method with another having the same signature (in different class) Overview of OOP Polymorphism • Python operators work for built-in classes. • But same operator behaves differently with different types. For example, the + operator will, perform arithmetic addition on two numbers, merge two lists and concatenate two strings. This feature in Python, that allows same operator to have different meaning according to the context is called Overview of OOP • What is the difference between Overriding and Overloading? • Although, method overriding and method overloading are used to provide a method with different implementations, there are key differences between these two concepts/techniques. • First of all, subjects of method overriding always stay within different classes, while subjects of method overloading stay within the same class. That means overriding is only possible in object oriented programming languages that allows inheritance, while overloading can be available in a non object-oriented language as well. In other words, you override a method in the super class but you overload a method within your own class. Overview of OOP • What is the difference between Overriding and Overloading? • Another difference is that overridden methods have the same method name, method signature and the return type, but overloaded methods must differ in either the signature or the return type (the name should be the same). In order to differentiate between two overridden methods, the exact type of object that is used to invoke the methods id used, whereas to differentiate between two overloaded methods the types of the parameters are used. Another key difference is that overloading is resolved at compile time, while overriding is resolved at runtime. Overview of OOP

Polymorphism Overview of OOP

Inheritance • While designing a inheritance concept, following key pointes keep it in mind • A sub type never implements less functionality than the super type • Inheritance should never be more than two levels deep • We use inheritance when we want to avoid redundant code. Overview of OOP

Inheritance • Two built-in functions isinstance() and issubclass() are used to check inheritances. • Function isinstance() returns True if the object is an instance of the class or other classes derived from it. • Each and every class in Python inherits from the base class object. Overview of OOP

Inheritance • Inheritance is a powerful feature in object oriented programming • It refers to defining a new class with little or no modification to an existing class. • The new class is called derived (or child) class and the one from which it inherits is called the base (or parent) class. • Derived class inherits features from the base class, adding new features to it.  This results into re-usability of code