<<

Object Oriented Programming Introduction

Object Oriented Programming

Introduction to Computer Science II Definition

Christopher M. Bourke Objected-Oriented Programming is a that uses [email protected] objects (data structures which have data fields and methods) which interact together within a computer program.

Object Oriented Programming Object Oriented Programming Key Ideas Keep in mind

When talking about OOP, keep in mind: I Modularity of design I Definitions are often blurred, authors/contexts may differ slightly I Encapsulation of data into Objects I Languages can have some, all, or none OOP features I Abstraction of an object’s behavior and representation I Programs can ignore or utilize some subset of features I Hierarchical organization of objects with subtypes inheriting behavior and state I Non-OOP languages can support some (or all!) OOP features without being “OOP” I Polymorphism ability of objects to have multiple forms in different contexts at different times I Debate still going as to “best” practices, how to do OOP, etc. I Understanding some concepts requires understanding other concepts

Object Oriented Programming MotivationI Advantages

Consider the evolution of computer languages I Facilitates modeling of real-world agents & problems I Machine Code Assembly Imperative Language I Supports modularity & decomposition → → I Clear demarcation of responsibilities and functionality I Each iteration still forces you to think in terms of a computer’s structure I Separates interface (the what) from implementation (the how) I Other paradigms force models/problems into I Promotes code reuse their paradigm I Bugs, side-effects, etc. can be localized, less and more predictable testing I Example: LISP assumes that all problems involve lists I Example: assumes all problems are procedural (algorithmic) MotivationII Contrasting with Other Paradigms

I In general, problems are forced into a language’s paradigm

I Involves some “translation” or pigeonholing I Most modern programming languages support some OOP features I Good for domain-specific problems or just number-crunching, bad for I Features back-added due to demand or advantages that OOP provides generality I OOP vs. Declarative paradigm I Opposite of what it should be: computers should be serving our needs I OOP vs. Imperative paradigm I Languages should model our world and problems

Versus Declarative Versus Imperative

Declarative Paradigm Imperative Paradigm I “Declares” behavior of a program I Specifies a specific process (algorithm) that changes a program’s state I Specifies logic of computation, not control flow I Built from one or more procedures (methods, functions) I Functional, avoids state (Lisp, Scheme, Haskell) I Procedural & Structured paradigms (state changes are local or I Logic programming parameterized), not encapsulated I Domain languages: Regular Expressions, HTML, Excel, SQL I Examples: , C I Not necessarily Turing-complete

History of OOPI History of OOPII

I First compilers simply translated C++ syntax to pure C I Paradigms have “evolved” to OOP I 1983: Brad Cox & Tom Love develop Objective-C I MIT 50s - 60s: LISP “atoms” I Inspired to add OOP features to C from Smalltalk I 1960: Sketchpad (first CAD, revolutionary GUI) by Ivan Sutherland, I 1990s: OOP came to dominate programming methodologies introduced initial concepts (especially due to GUI development) I 1967: Simula 67 by Dahl & Nygaard (bank simulation; agents: I Languages updated to include OOP features tellers, customers, accounts, transactions; physical modeling) I 1995: Java! I 1972: Smalltalk by Alan Kay I 1995 by James Gosling, Sun Microsystems I Based on Plato’s Theory of Forms I “simple, object-oriented and familiar” I Allegory of the Cave I “robust & secure” I “A form is an objective ’blueprint’ of perfection” (an archetype) I “architecture-neutral and portable” I No perfect circle, just shadows, representations of it verything has a I “high performance” quintessence, an archetype, an apotheosis I “interpreted, threaded, dynamic” I 1983: Bjarne Stoustrup develops C++

I Inspired to add OOP features to C from Simula Continued RefinementsI Continued RefinementsII

I Design Patterns - a general reusable solution to a common and reoccurring problem in software design (also called idioms)

I Anti-patterns and “smells”

I Modeling tools (UML – Unified Modeling Language)

I Design-by-contract frameworks

I Integrated Development Environments (IDEs)

I Development of libraries, frameworks

I Development of methodologies, best practices, etc. Figure : UML Diagram Example

Objects Objects Abstract Data Types

I Basis for Objects: Abstract Data Types (ADTs) Definition

I Mathematical model for classes of data structures with similar An object is a general entity characterized by the following. behavior or semantics

I Purely theoretical entities I Identity – An aspect that distinguishes it from other objects

I Generalization applicable to areas other than OOP I State – properties (attributes, elements, data, fields)

I Algebraic structures, AI, algorithms, etc. I Behavior – describes an object’s interface (methods, routines,

I Examples: stacks, queues, maps, strings, and their operations functions)

ObjectsI ObjectsII Key Concepts Key Concepts

Message sending Complex Data Types

I Objects provide services I Collection of multiple pieces of information I Client code (user) can access these services by sending messages I Mixed types I Example: a signal to execute one of its methods I Varying visibility I A signal to turn a Light object on() or off()

I Facilitated by an externally available interface ObjectsIII ObjectsIV Key Concepts Key Concepts

Construction Object Design

I General approach: decompose an entity to the point where it is I Objects are constructed rather than assigned simple enough to implement or a suitable object already exists I Construction may be specified through constructors I Keep it simple I Assignment through references I Semantics may dictate design I Contrast with primitive types I Avoid the God-Object anti-pattern

ObjectsV 4 Main Principles Key Concepts

Examples

I An animal is a general type Object Oriented Programming involves 4 main principles I Dogs, Cats, Snakes, Lizards are all animals

I How can we further develop a taxonomy? 1. Abstraction I Should the following be incorporated? 2. Encapsulation

I Pets? 3. Inheritance I Gender? 4. Polymorphism I Strict is-a relationship

I Examples: vehicle, automobile, truck, car, boat plane

AbstractionI AbstractionII

Definition Already familiar with Procedural Abstraction: the implementation of a process is codified into a reusable piece of code inside a function. Abstraction is the mechanism by which objects are given their Example: a square root function may be implemented using various representation and implementation details are hidden. algorithms.

Abstraction is apparent in many areas: I Taylor series

I Babylonian method I Application layers (database, middle-tier, front-end) I Some other interpolation method I System Layers

I Protocol layers (OSI networking model) AbstractionIII AbstractionIV

Example: A sorting function I Abstraction in OOP takes this further: methods implementations are abstracted, but so are the internal representations of the objects

I Selection sort? Quick sort? Other? I Objects are defined with a representation similar to is meaning I Temporary space? (semantics) while hiding implementation details

I How does it swap? I Defines the conceptual boundaries of an object, distinguishing between objects

In the end: who cares? I Allows the client (programmer, user) to deal with objects based on Procedural abstraction relieves us of the need to worry about their public interface without worrying about details implementation details I It just works!

Abstraction in languages Abstraction Example 1 Date/Time A date/time stamp object may be defined to represent a particular point in time (with functionality for formatting, comparing and operating with durations, intervals, other date/time instances). I Abstraction of objects is achieved through its publicly available How could such an object be represented? interface

I Interface specifies how you can use the object I A collection of individual numbers (year, month, day, etc.)

I Specifies which methods may be signaled by client code I A single numerical value (time from a particular epoch)

I May specify a contract I ISO 8601-formatted string (ex: 2012-05-04T12:20:34.000343+01:00) I In conjunction with inheritance: behavior of subtypes may change, be enhanced, etc. Abstraction relieves us of the need to worry about such details

I Representation is internal to the object I Consistency and changes are handled by the object I We only interact with its interface

Abstraction Example 2 Example 3 Strings

Most languages support strings, but may use different representations

I A null-terminated character array I A length-prefixed character array A Graph has vertices (nodes) and edges; may be represented as: I Dynamic character array I matrix I ASCII or Unicode? I adjacency list

Representing a string as an object relieves us of the need to worry about I maps these details

I Contrast with procedural language (C): memory management, consistency, expectations must be handled manually

I Instead of worrying about details: just use it! EncapsulationI EncapsulationII

Definition I A form of information hiding I In contrast to abstraction which is implementation hiding Encapsulation is a mechanism for restricting access to (some of) an object’s components and for bundling data and methods operating on that I Includes the aspect of grouping data – modularity data. I Protection of data

I Allows restriction to access and control of data Includes: I Allows internal behavior to change, evolve, be fixed without affecting 1. Grouping of data client code 2. Protection of data I Usually breakable (through reflection, exposing in subclasses) 3. Grouping of methods that act on an object’s data

EncapsulationIII Encapsulation Best Practice

I Enables mutator and accessor methods

I Changes are made to be intentional I Best practice: make everything private, control access through I Side-effects can be controlled and localized getters/setters I Allows validation I Objects should not just be data containers I Enables objects to be immutable (predictable, thread-safe) I Any method that acts on an object’s data should be a member I Key idea: abstraction allows a user to access essential information, method

encapsulation hides the data, they compliment each other I Do not break encapsulation by placing related functionality elsewhere

EncapsulationI EncapsulationII Java Example Java Example

1 public class BankAccount { § ¤ 2 private double balance; 3 private double apr; Breaking encapsulation: 4 ... 1 public class BankUtils { 5 //constructors, getters/setters § ¤ 2 6 ... 3 public static double getMonthlyEarnings( 7 public double getMonthlyEarnings() { BankAccount acct) { 8 return this.balance * (this.apr / 12.0); 4 return acct.getBalance() * (acct.getAPR() / 9 } 12.0) ; 10 } 5 } 6 } ¦ ¥© 1. Grouping of data ¦ ¥© 2. Protection of data 3. Grouping of functionality that acts on that data Side-effects Why Encapsulation

Definition Beginners question: why can’t everything just be public? A function or expression has a side-effect if it modifies some state or has Without Encapsulation: an observable interaction with calling functions or other parts of the program (either globally, to other threads, the outside world, etc.). I Internal state could be modified with impunity

I Everything essentially becomes global Examples: I Difficult to test/control

I A sort method that reorders the original list I Anti-modular

I A setter method that modifies an object’s state that can be observed I No way to enforce rules through its public interface Save on typing: utilize IDE macros (Eclipse: Source generate I A subroutine used in a logical expression that makes changes to its → getters/setters) parameters

I Any changes to global, static variables, parameters, data I/O, etc.

Inheritance Aspects of Inheritance

I Allows us to define a hierarchy of related objects Definition I Subclasses inherit behavior and/or fields from superclasses

Inheritance is the ability to extend the definition of objects; creating I Subclasses can augment, modify, or change the behavior of methods

objects from previously created or defined objects I Facilitates code reuse

I Generalized common behavior and/or interface can be defined in Most common form: classical inheritance (subclassing) superclasses

I subclass/superclass I Subclasses provide specialization (more specificity)

I derived/base classes I General properties or behavior is specialized into more concrete implementations I child/parent classes I Super/subclass defines an is-a relationship

Inheritance Java Example Java Example

1 public class Bird { 2 § public void move() { ¤ 3 System.out.println("Moving somehow..."); 4 } 5 } I Bird is a superclass 6 7 public class Robin extends Bird { 8 public void fly() { I All birds move(), but how? 9 System.out.println("Flying..."); 10 } I Ostrich and Robin may be subclasses 11 ... 12 @Override I Ostrich may specify a walk() method 13 public void move() { 14 this.fly(); 15 } I Robin may specify a fly() method 16 } 17 I move() may be overridden in the subclasses to call their respective 18 public class Ostrich extends Bird { 19 public void walk() { methods 20 System.out.println("Walking..."); 21 } I Subclasses may be referred to as their super class 22 ... 23 @Override 24 public void move() { 25 this.walk(); 26 } 27 }

¦ ¥© Collections HierarchyI Collections HierarchyII

Collection I A general collection is a data structure that holds stuff I A set is a collection that holds stuff in an unordered manner; a list is a collection that holds stuff in an ordered manner Set List I A HashSet is a set that holds stuff in an unordered manner using a hash table

I An ArrayList is a list that holds stuff in an ordered manner using an HashSet TreeSet ArrayList LinkedList array, etc.

Figure : Java Collections Library Inheritance structure

Virtual Functions How this works:

A is a function that can be overridden in a subclass. I Upon instantiation, a particular constructor is called I C++: all functions are non-virtual by default; can be made virtual by I This creates the object in memory as a virtual table (vtable) use of the keyword virtual I Object has data in memory, but also references to the code for its I Java: all non-private functions are virtual by default; can be made non-virtual by use of the keyword final methods 1 I static methods can be overridden I When a method is called, the method which the vtable refers to is I visibility of methods can be more open, but not decreased invoked I within a class, access to the superclass’s method is accessible via the I This process is a run-time mechanism (since methods can be invoked super keyword via a reference to the super class)

1but when static methods are invoked, they should be done so via the class name anyway

How this works: Dynamic Dispatch Multiple Inheritance Java Example

1 Bird b = new Bird(); § ¤ 2 b. move ();//prints"Moving somehow..." I An object can inherit from multiple parents, called multiple 3 Robin = new Robin(); inheritance 4 r. move ();//prints"Flying..." I Example: Musician (inherits from Person, Performer) 5 r. fly ();//prints"Flying..." 6 b = r;//subclass referred to as its superclass I Supported by some languages 7 b. move ();//prints"Flying..." I Problematic to implement properly: the diamond problem 8 //b.fly(); <--compile error I Example: Animal, Dog, Cat, “DogCat”? 9 b = new Ostrich(); 10 b. move ();//prints"Walking..." I Necessary to establish a mechanism to disambiguate properties

¦ ¥© Why Inheritance Liskov Substitution Principle

The Liskov Substitution Principle states: if S is a (subtype of) T , then I Motivation: Classification & Taxonomy any instance of T should be replaceable by an instance of S without altering any of the desired properties of the program. I Ubiquitous: sheer volume of data requires classification to organize it

I Hierarchical structure is most natural (though not always applicable) I A principle, not a lemma

I Fundamental to communication I I.e. should be the case

I Communication requires a common classification/description I Not guaranteed

I Certainly possible to violate (breakable)

Beware of Pitfalls Polymorphism

Definition

I Good practice: avoid the yo-yo anti-pattern (keep relations shallow) Polymorphism is the ability to create a variable, method, or an object that I When in doubt: use composition instead! has more than one form (type). I Avoid the rectangle problem (or the circle problem):

I Object types should not be mutable to sub/super types I The is-a relationship (should be) an invariant I Derived from Greek: “having multiple forms”

I Code Check: take a look at unl.cse.rectangle_problem I Inspired by biology (organisms may have different phenotypes: observable traits; genetic, behavioral, or consequence there of)

I Allows more abstract, reusable code

Subtype Polymorphism Behavioral

I The “default” type of polymorphism Behavioral subtyping is a strict type of polymorphism where: I You can refer to subclass instances as their superclass I Liskov Substitution Principle is strictly enforced I Instance’s methods are called dynamically using late-binding I Much stronger form of polymorphism I Because subtypes can provide their own method implementation (overrides), I Pre- and Post- conditions are defined & enforced (design-by-contract) I There is not enough information at compile time to determine which I Preconditions cannot be strengthened in subtypes method to call I Example: Bird may a move() method; while an Ostrich has a run() I Postconditions cannot be weakened in subtypes method, Robin has a fly() method I Invariants are guaranteed I Code Check: let’s take a look at unl.cse.oop.inheritance I Subtypes must be pure inheritance (no new methods) I Dynamic Dispatch: compiler is able to create a virtual method table I Not generally used in practice (v-table) with references to the correct method to invoke Method Overriding Ad-hoc PolymorphismI

I Subclass augments, modifies, or provides a completely different Ad-hoc Polymorphism covers a wide variety of as-needed polymorphic implementation of a method behavior. I Method has the same name and signature

I May support covariant return types I Ad-hoc: done as needed for a particular purpose

I Not the same as (operator) overloading (which is done at compile I On-the-fly polymorphism time)

Method OverloadingI Method OverloadingII

Some examples in practice: Method Overloading: several different “versions” of a method may be defined I The same name can be used for several versions of an absolute value function (rather than different names for each numeric type)

I Methods have the same identifier (name) I C: standard math library has three functions with different names I In general, have the same return type (labs, fabs, abs) for three numeric types; Java: 4 methods with the same name, different arguments I However, must differ in the type or arity (number of) parameters I Java: String class has 9 valueOf(...) methods to give the String I Resolution of which method is called is inferred at compile time based value of every type on the arguments at invocation I Java: Integer class has 3 different toString(...) methods (built-in, I May be considered static dispatch conversion, base-conversion)

Operator OverloadingI Operator OverloadingII

Should be avoided:

Operator Overloading: built-in operators’ (+, =, etc.) behavior can be I Of limited use (operator-operand combinations can only have one redefined depending on its operands meaning)

I Some overloading is already built into languages: I All combinations of operands that are used must be defined

I String + String may be concatenation I Coding requires defining a function anyway, why not just use the I Number + Number may be addition function? I Number + String may be conversion-addition or I Built-in operators have a clear and understood meaning; when applied conversion-concatenation to user defined types or completely redefined, meaning becomes I Some languages allow you to overload an operator ambiguous, unclear, open to interpretation I Could define + to mean union when used with arrays or graphs I Example: what does Array + Array mean? I Could define + to mean time-addition when used with I Concatenation? date-time/interval types I Vector addition? I Set union? Type CoercionI Type CoercionII

I When operators are overloaded, rules must be defined for how types and behaviors are resolved. Examples:

I Types are coerced into other types with specific rules so that the I Casting numbers to strings in order to concatenate operands become compatible I Integers are cast to floats in order to add/subtract/multiply I Type Coercion: one type is mapped to another compatible type I Floats may be down-casted to integers when the assignment operator I Type Promotion: mapping a type to a super-type for compatibility is used I Rules may be defined by the language or incompatible types may be disallowed entirely

I Such type casting may require an explicit instruction by the user

Type CoercionIII Type CoercionIV

Bird Covariant Contravariant General types of conversions:

I Covariant: converting from a specialized type to a generalized type (subclass to superclass, Ostrich to Bird) Robin Ostrich I Contravariant: converting from a generalized type to a specialized Invariant type (super to subclass, Bird to Ostrich) Figure : Covariance, Contravariance, Invariance I Invariant: no conversion is possible

In general, only covariance is “safe” since subtypes define an is-a relationship. More formally, if A B, then a transformation f is: ≤

Type CoercionV Parametric PolymorphismI

Parametric polymorphism allow us to define methods or classes that have strong static type-safety, but that can be applied to many different types.

I covariant if f(A) f(B) Allows us to write generic code that depends only on some aspect(s) of all ≤ I contravariant if f(B) f(A) types that are applicable to the class/method without depending on the ≤ actual type. I invariant otherwise A method or class is given a generic type, a parameter (parameterized) The specific type is specified by the client code or deduced at runtime The parameterized code itself is generic enough that it applies to all types (does not use any type-specific functionality) Parametric PolymorphismII Bounded

Examples:

I A generic “container” class (list or set) can be parameterized to hold I Some information may be needed by the implementation a specific type (defined at instantiation) I Code needs to know that such objects are numeric types or are I A generic print method that prints elements in an array or collection “comparable” in a tidy format I Bounding the parameterized type guarantees a minimum set of I A generic getMax() method can be used for all numeric types information implied by the type I A single, generic sorting method can be defined and used for any type I Bounding the types provides a minimal guarantee of the interface that is “comparable” in some manner they provide (which can then be used!) I Example: a parameterized summation method would need to bound the types to numerical types

Open Recursion Open Recursion Java keywords

I Objects are defined, but instances are constructed I this can be used inside an object to refer to itself I An instance may need to refer to its own methods or fields I super can be used to access methods/variables of a super class I No variable reference at compile time 2 I this(...) can be used to call an object’s constructors I Special keyword(s) defined (this or self ) I super(...) can be used to call an object’s superclass’s constructor I Bound to a specific object (instance) via late-binding

2Objective-C, Python, Ruby; VB uses Me!

Association, Aggregation, CompositionI Association, Aggregation, CompositionII

Aggregation: “the” relation between two classes

Association: “a” relation between two classes I One class “has” another (or usually a collection of another) class I Usually by reference I An object knows about another object I Relationship does not imply ownership I Can call its methods, interact with it I Other instances may also “have” the object I Most general object–object relationship I Destruction issues

I Example: University – Departments – Faculty Association, Aggregation, CompositionIII Association, Aggregation, CompositionIV

Composition vs Inheritance

Composition: One object owns another I Inheritance is good when hierarchy is rigid and well-established; design is mature I Upon destruction of owner, owned object(s) are also destroyed I Inheritance is fragile as changes up-stream (super classes) will affect I Should be private: no one else should depend on them everything downstream

I Composition in Java: I Composition is more extensible; does not lock you into a hierarchy I Less important in Java as garbage collection is automatic that would require refactoring I If multiple owners, owned objects won’t get destroyed I Composition is more flexible, easier to change and changes have less of an effect

I Use composition when in doubt

Other Issues Other Issues Mixins Duck Typing

A mixin is an object that provides functionality to be inherited or reused

I Object’s functionality is mixed in to another object I OOP languages without classes use dynamic typing (JavaScript, I Mixin itself is abstract and cannot be instantiated Python) I Not a form of specialization I Methods and properties define a type rather than semantics I A means to collect functionality into an object I If it walks like a duck (waddle()), talks like a duck (quack()) then its I Java: not directly supported a Duck I Interfaces provide specification, but not behavior I Abstract classes can provide functionality, but must be inherited and cannot be multiply inherited I Preferred solution: composition

Other Issues SOLIDI Copy Constructors SOLID Principles (Features, Martin):

I SRP: Single Responsibility Principle – a class should have only a

I Its often convenient to have a way to create different copies of objects single responsibility (i.e. only one potential change in the software’s specification should be able to affect the specification of the class) I Usual to implement a copy constructor: a constructor that takes an instance of its own class I OCP: Open/Closed Principle – software entities should be open for extension, but closed for modification I Pitfall: the copy should be a deep copy and not just a copy of references I LSP: Liskov Substitution Principle – objects in a program should be replaceable with instances of their subtypes without altering the I If not a deep copy, changes to the “shared” resources will be realized correctness of that program by both copies I ISP: Interface Segregation Principle – many client-specific interfaces are better than one general-purpose interface

I DIP: Dependency Inversion Principle – one should ?Depend upon Abstractions. Do not depend upon concretions Summary ExampleI Summary ExampleII Maps Maps

1 Map m = new HashMap(); could use open or closed addressing; representation details are 2 ... irrelevant and hiddent to us 3 String nuid ="12345678"; 4 Student s = new Student(...); I Inheritance: HashMap is-a Map that uses a hash table (while a TreeMap 5 m.put(nuid, s); is a map that uses a tree) 6 ... I Polymorphism: through parametric polymorphism, we can map 7 String someNuid ="87654321"; 8 Student joe = m.get(someNuid); specific types to other specific types I Java note: a Map is not Collection (see why: ¦ ¥© http://docs.oracle.com/javase/1.4.2/docs/guide/ I Maps are key-value data structures collections/designfaq.html#14 I Abstraction: get and put methods define how to use this data structure without worrying about its implementation details

Summary ExampleIII Software Engineering & Design BooksI Maps Map

AbstractMap

HashMap TreeMap

LinkedHashMap

Figure : Design Patterns: Elements of Reusable Object-Oriented Software (1994) Figure : Map data structures in Java Collections library by Gamma et al.

Software Engineering & Design BooksII Software Engineering & Design BooksIII

Figure : Code Complete (1993) by Steve McConnell Figure : The Mythical Man-Month (1975) by Frederick Brooks Jr. Software Engineering & Design BooksIV

Figure : Refactoring: Improving the Design of Existing Code (1999) by Martin Fowler