COS 333: Chapter 12, Part 1

Willem van Heerden
15 Nov 202162:16

Summary

TLDRThis lecture delves into object-oriented programming (OOP), exploring its support in high-level languages and its foundational concepts. It discusses the necessity of abstract data types, inheritance, and polymorphism in OOP languages. The talk highlights design issues like object exclusivity, subtype considerations, and inheritance models, contrasting single and multiple inheritance. It also examines dynamic binding, type checking, and the initialization of objects. The lecture provides insights into programming languages like Smalltalk, which pioneered OOP, and languages like Java and C++ that primarily support OOP but retain imperative structures.

Takeaways

  • 📚 The lecture introduces Chapter 12, focusing on support for Object-Oriented Programming (OOP) in high-level languages, with a second part to follow in the last lecture of the course.
  • 🔑 OOP is supported in various languages to different extents, with some being purely OOP like Smalltalk, while others like Ada and C++ offer OOP as an additional feature on top of procedural programming.
  • 💡 The core concepts of OOP include abstract data types, inheritance, and polymorphism, which are essential for any language claiming to support OOP.
  • 👶 Inheritance allows for the creation of new classes based on existing ones, promoting code reuse and establishing a hierarchy among classes.
  • 📈 The advantages of inheritance include increased productivity through code reuse and the ability to logically structure classes in a hierarchical order.
  • 🔍 Design issues in OOP languages involve considerations of object exclusivity, subtypes, type checking, single vs. multiple inheritance, object allocation, binding types, nested classes, and object initialization.
  • 🔄 Dynamic binding in OOP is facilitated by polymorphic references and occurs at runtime, allowing for method calls to be bound to the correct method dynamically.
  • 🚫 Abstract methods and classes are part of OOP, with abstract methods defining a protocol without an implementation and abstract classes being unable to be instantiated.
  • 🔍 The script discusses three approaches to object exclusivity: treating everything as an object (as in Smalltalk), adding objects to a complete typing system (as in C++), and using an imperative typing system for primitives while making everything else an object (as in Java).
  • 🤔 The disadvantages of OOP include increased complexity due to interdependencies among classes, which can complicate maintenance and upgrades.
  • 📝 Smalltalk is highlighted as the first purely OOP language, with all computation handled through message passing and all objects allocated on the heap, but suffers from performance issues due to its uniform object handling and reliance on a garbage collector.

Q & A

  • What is the main focus of the lecture?

    -The lecture primarily focuses on the support for object-oriented programming in high-level programming languages, covering the foundational concepts, design issues, and examples of programming languages that support these principles.

  • What are the key concepts that must be supported in an object-oriented programming language?

    -An object-oriented programming language must support abstract data types, inheritance, and polymorphism.

  • What is the significance of inheritance in object-oriented programming?

    -Inheritance allows new classes to be defined in terms of existing classes, promoting code reuse and enabling a hierarchical organization of classes.

  • Can you explain the difference between a class and an object in object-oriented programming?

    -A class is a blueprint for creating objects, defining the properties and methods that objects of that class will have. An object is an instance of a class, representing a specific entity with its own state and behavior.

  • What is the meaning of polymorphism in the context of object-oriented programming?

    -Polymorphism in object-oriented programming refers to the ability of different objects to respond to the same message (method call) in different ways, typically achieved through method overriding.

  • How does the Smalltalk programming language exemplify object-oriented programming?

    -Smalltalk is considered a pure object-oriented programming language because it treats everything as an object, including primitive types like integers and floats, and it was the first language to be developed with these principles.

  • What are the different extents to which programming languages can support object-oriented programming?

    -Programming languages can range from having very basic support for object-oriented programming as an optional feature, to being primarily object-oriented with some imperative structures, to being pure object-oriented languages that rely entirely on an object model for functionality.

  • What are some of the design issues that need to be considered when supporting object-oriented programming in a high-level programming language?

    -Design issues include the exclusivity of objects, the consideration of subclasses as subtypes, type checking with reference to polymorphism, support for single or multiple inheritance, object allocation and de-allocation, dynamic and static binding, nested classes, and object initialization.

  • Why might a programming language choose to implement single inheritance over multiple inheritance?

    -Single inheritance can be chosen to simplify the language and avoid complexities such as naming collisions and additional runtime overhead associated with multiple inheritance.

  • What is the role of abstract methods and abstract classes in object-oriented programming languages?

    -Abstract methods define a protocol for a method without an implementation, ensuring that derived classes must provide their own implementation. Abstract classes cannot be instantiated and include at least one abstract method, enforcing that certain functionality is implemented by derived classes.

  • How does Smalltalk handle object allocation and memory management?

    -In Smalltalk, all objects are allocated on the heap, and memory management is handled implicitly by a garbage collector, which frees up memory occupied by objects that are no longer in use.

  • What is the impact of dynamic binding on the performance of an object-oriented program?

    -Dynamic binding can impact performance because the determination of which method to call is made at runtime, consuming runtime resources. However, it allows for greater flexibility and extensibility in software development.

Outlines

00:00

📘 Introduction to Object-Oriented Programming Support

This paragraph introduces the lecture's focus on the support for object-oriented programming (OOP) in high-level languages, outlining the topics to be covered, including an introduction to OOP, its concepts, and design issues. It highlights the range of OOP support in various languages, from purely procedural to purely object-oriented, with examples like Smalltalk as the first OOP language and others like Java and C# that blend OOP with imperative features.

05:02

🔑 Key Concepts of Object-Oriented Programming

The paragraph delves into the foundational concepts of OOP, emphasizing the necessity of support for abstract data types, inheritance, and polymorphism in an OOP language. Inheritance is discussed as a means to increase productivity through code reuse and to create logical hierarchies of classes. The paragraph also introduces terminology such as classes, objects, derived classes, parent classes, methods, and message passing, illustrating how these concepts contribute to the structure and behavior of OOP.

10:04

📚 Inheritance and Method Overriding in OOP

This section explores the intricacies of inheritance, including access controls and method overriding. It explains how subclasses can specialize parent classes by adding functionality and how access to class members can be restricted. The paragraph also discusses the ability of a subclass to override inherited methods, adapting their behavior to the subclass's needs, and the implications of this on the overall design of OOP languages.

15:05

🔍 Dynamic Binding and Polymorphism

The concept of dynamic binding is introduced, explaining how it allows for the determination of the correct method to call at runtime through polymorphic references. The paragraph discusses the advantages of dynamic binding for software system extension and maintenance, and touches on abstract methods and classes, which enforce that derived classes implement certain functionalities. It also covers the implications of dynamic binding on type checking and the potential for runtime errors due to type mismatches.

20:07

🏭 Design Issues in Object-Oriented Programming Languages

The paragraph addresses several design considerations for OOP languages, such as the reliance on objects, subtype relationships, type checking with polymorphism, support for single or multiple inheritance, object allocation and de-allocation, binding dynamics, nested classes, and object initialization. It sets the stage for a deeper discussion on how different programming languages approach these design issues and the trade-offs involved in their implementation.

25:07

🌐 Object Exclusivity and Subtype Considerations

This section examines the design issue of object exclusivity, discussing the approaches where everything is an object, versus adding objects to an existing type system, and using an imperative type system for primitives while treating everything else as an object. It also explores the implications of considering subclasses as subtypes, focusing on the 'is-a' relationship and its impact on the behavior compatibility between parent and derived classes.

30:07

🎛️ Polymorphism and Inheritance Challenges

The paragraph delves into the challenges associated with polymorphism and inheritance, particularly the complexities introduced by multiple inheritance and the concept of diamond inheritance. It discusses the potential for naming collisions and the increased cost of dynamic binding when multiple inheritance is involved, while also highlighting the flexibility and power that multiple inheritance offers in expressing complex inheritance structures.

35:09

📦 Object Allocation, De-allocation, and Binding

This section discusses the allocation and de-allocation of objects, the distinction between stack and heap allocation, and the implications of subtypes on object assignment. It also addresses the decision between dynamic and static binding for messages within an OOP language, considering the trade-offs between efficiency and flexibility, and the programmer's ability to specify binding types in languages like C++.

40:12

🛠️ Nested Classes and Object Initialization

The paragraph considers the support for nested classes, their visibility to the nesting class and vice versa, and the initialization of objects, including the use of constructors and default initialization. It explores the design decisions related to the visibility of class members and the handling of parent class member initialization in subclasses.

45:13

🔑 Smalltalk: The Pure Object-Oriented Programming Language

This final paragraph provides an overview of Smalltalk as the first purely object-oriented programming language. It discusses the language's characteristics, such as the treatment of all elements as objects, heap allocation, message passing for computation, dynamic type checking, and its simple inheritance model. The paragraph also touches on the limitations of Smalltalk, including its performance due to the uniform use of message passing and garbage collection.

Mindmap

Keywords

💡Object-Oriented Programming (OOP)

Object-Oriented Programming is a programming paradigm that uses 'objects' to design applications and programs. It is centered around the concept of 'objects', which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods). In the video, OOP is the main theme, with the script discussing how it is supported in various programming languages and the foundational concepts that must be present in a language for it to be considered object-oriented.

💡Inheritance

Inheritance is a core concept in OOP that allows a new class, known as a 'subclass' or 'derived class', to inherit attributes and methods from an existing class, known as the 'parent class' or 'superclass'. The script explains how inheritance facilitates code reuse and the creation of hierarchical class structures, using examples such as a 'Person' class from which 'Student', 'Lecturer', and 'Pensioner' classes could inherit.

💡Polymorphism

Polymorphism is the ability of different classes to be treated as instances of the same superclass. It is closely related to inheritance and allows for dynamic method binding, where the exact method that gets called is determined at runtime based on the actual object's type. The script discusses polymorphism in the context of method calls and how it enables flexibility in object interactions.

💡Abstract Data Types (ADTs)

Abstract Data Types are high-level descriptions of data types that abstract out the implementation details and expose only the necessary operations to the users of the type. The script mentions ADTs as a precursor to OOP, highlighting their limitations in terms of code reuse and the lack of a natural hierarchy, which are addressed by OOP concepts like inheritance.

💡Encapsulation

Encapsulation is the bundling of data with the methods that operate on that data, or the restriction of direct access to some of an object's components. The script touches on encapsulation as part of the definition of an ADT, where information and behavior related to an object are encapsulated within the object itself.

💡Design Issues

Design issues in the context of the video refer to the various considerations and decisions that need to be made when designing a programming language to support OOP. These include how to handle inheritance, polymorphism, object allocation, and other OOP features. The script delves into several design issues, such as exclusivity of objects, subtypes, type checking, and more.

💡Smalltalk

Smalltalk is an object-oriented, dynamically typed, reflective programming language. It was developed in the 1970s and is known for being one of the first OOP languages. The script uses Smalltalk as an example of a 'pure' OOP language, where everything, including basic types like integers, is treated as an object.

💡Dynamic Binding

Dynamic Binding is the process of determining the method to be called at runtime rather than at compile time. It is a feature of polymorphism and is crucial for allowing objects to behave dynamically based on their actual type. The script explains how dynamic binding works in OOP languages and its role in enabling method overriding and runtime method selection.

💡Abstract Classes

An abstract class is a class that cannot be instantiated on its own and serves as a blueprint for other classes, typically through abstract methods that must be implemented by any non-abstract subclass. The script mentions abstract classes in the context of enforcing certain methods to be implemented by derived classes.

💡Message Passing

Message passing is a concept in OOP where objects communicate by sending messages to each other. A message in this context is a request to perform an operation, which is implemented as a method in the receiving object. The script uses the term 'message passing' to describe the interaction between objects in an OOP language.

💡Garbage Collection

Garbage Collection is an automatic memory management technique used by programming languages to reclaim memory used by objects that are no longer in use. The script discusses garbage collection in the context of Smalltalk, where it is used to manage the memory of heap-allocated objects, and notes it as a factor contributing to the language's performance characteristics.

Highlights

Introduction to support for object-oriented programming in higher-level languages and the topics to be covered in the lecture.

Discussion on the varying degrees of object-oriented programming support across different programming languages, from full support to basic features.

Explanation of the three core concepts of object-oriented programming: abstract data types, inheritance, and polymorphism.

The benefits of inheritance in object-oriented programming for code reuse and the creation of class hierarchies.

Introduction to object-oriented terminology such as classes, objects, derived classes, parent classes, methods, and message passing.

The role of access controls in object-oriented programming for encapsulation and the concept of protected access.

The importance of dynamic binding in object-oriented programming for method calls and its advantages for software system extension and maintenance.

The concept of abstract methods and classes in object-oriented programming and their necessity for ensuring derived class implementations.

Design issues in object-oriented programming languages, including the exclusivity of objects, subtype considerations, and type checking with polymorphism.

Different approaches to object allocation and de-allocation in object-oriented programming and their implications.

The impact of single versus multiple inheritance on object-oriented programming languages and associated complexities.

Discussion on object initialization in object-oriented programming, including constructor usage and inheritance of parent class members.

Overview of object-oriented programming support in Smalltalk, the first object-oriented programming language.

Smalltalk's unique approach to treating everything as an object, including basic types, and its implications for performance.

The use of message passing for computation in Smalltalk and its role in making the language uniform but potentially slower.

Smalltalk's handling of object allocation and garbage collection, and the potential disadvantages of relying on a garbage collector.

Dynamic type checking and its runtime implications for Smalltalk's performance and error detection.

Inheritance in Smalltalk, including the rules for method overriding and accessing overridden methods in parent classes.

Transcripts

play00:01

welcome to today's lecture which deals

play00:04

with the first part of chapter 12

play00:08

covering support for object oriented

play00:11

programming there will be a second part

play00:14

which will be covered in the last

play00:16

lecture for the course

play00:19

these are the topics that we will be

play00:21

discussing in today's lecture

play00:24

we'll begin with a quick introduction

play00:27

into how object-oriented programming is

play00:29

supported in higher level programming

play00:32

languages

play00:33

we'll then move on to

play00:36

the introductory concepts related to

play00:39

object-oriented programming itself

play00:41

and we'll look at all of the various

play00:44

concepts that must be supported in an

play00:46

object-oriented programming language

play00:49

we'll then move on to a number of design

play00:52

issues that need to be considered if one

play00:55

is to support object-oriented

play00:57

programming in a high-level programming

play00:59

language and these design issues will be

play01:02

used for the remainder of the discussion

play01:05

on this chapter where we'll look at a

play01:08

couple of different examples of

play01:10

programming languages and how they

play01:13

support object-oriented programming

play01:15

principles

play01:16

we'll finish this lecture off by looking

play01:19

at the first of these programming

play01:20

language examples

play01:22

namely the small talk programming

play01:24

language and small talk was the very

play01:27

first object-oriented programming

play01:29

language to be developed

play01:34

now there are a wide variety of

play01:36

different programming languages that

play01:38

support object-oriented programming and

play01:41

what we see in practice is a kind of a

play01:43

continuum

play01:45

so different programming languages

play01:47

support object-oriented programming to

play01:50

different extents

play01:51

some programming languages have a very

play01:54

full pure representation of

play01:57

object-oriented programming and are

play01:59

primarily object oriented whereas other

play02:02

programming languages only have very

play02:05

basic support for object oriented

play02:08

programming

play02:09

so what we see in practice is quite a

play02:12

number of programming languages are

play02:15

primarily procedural and data oriented

play02:19

so in these programming languages we

play02:22

generally speaking have support for

play02:25

imperative programming structures

play02:28

so things like

play02:30

structs

play02:32

enumerations unions and those sorts of

play02:34

things but then in addition they have an

play02:37

object-oriented programming model that

play02:39

is kind of added on top of everything

play02:42

else that the programming language

play02:43

supports so for these languages

play02:46

object-oriented programming is more of

play02:48

an optional feature that can be used by

play02:50

the programmer and languages that fall

play02:53

into this category are for example ada

play02:56

95 and c plus

play03:00

then there are some object-oriented

play03:02

programming languages that also support

play03:04

functional programming

play03:06

a good example of this would be class

play03:09

which is the common lisp object system

play03:13

and this adds object-oriented

play03:15

programming support to a lisp like

play03:19

dialect

play03:20

newer programming languages

play03:22

that are

play03:24

supporting object oriented programming

play03:27

may not support other paradigms at all

play03:30

so they may be fairly pure

play03:32

object-oriented programming languages

play03:34

however they may retain some basic

play03:37

imperative structures

play03:39

so good examples of languages that fall

play03:42

in this category are java and c-sharp

play03:45

both of these languages are primarily

play03:47

object oriented but they do provide

play03:50

support for certain

play03:52

non-object-oriented concepts for example

play03:55

imperative type systems

play03:59

and then a small number of programming

play04:01

languages are considered to be pure

play04:04

object-oriented programming languages

play04:06

they rely entirely on an object model to

play04:10

achieve their functionality and they

play04:13

have nothing from the imperative model

play04:15

included at all so in these languages

play04:18

even primitive types like integers and

play04:21

floats would be represented as objects

play04:24

small talk being the very first

play04:27

object-oriented programming language

play04:29

is very much in this category and also

play04:33

more recently

play04:35

ruby can be considered to be a pure

play04:38

object-oriented programming language

play04:42

so now let's move on to what is required

play04:46

for an object-oriented programming

play04:48

language to be considered object

play04:50

oriented in nature

play04:53

so every object-oriented programming

play04:55

language must support three things

play04:58

firstly it must provide support for

play05:01

abstract data types which we discussed

play05:04

in the previous chapter

play05:06

abstract data types provide a means for

play05:09

encapsulating information related to an

play05:12

object as well as behavior related to

play05:16

that object

play05:18

then an object-oriented programming

play05:19

language also needs to support

play05:21

inheritance which is the central theme

play05:24

in object-oriented programming

play05:27

and then related to inheritance

play05:30

we also need support for polymorphism in

play05:33

an object-oriented programming language

play05:36

and polymorphism refers to the dynamic

play05:39

binding of method calls to methods now

play05:43

we'll look at all of these concepts as

play05:46

we continue with our discussion in this

play05:49

lecture

play05:52

so let's begin by looking at the first

play05:56

important edition

play05:58

that object-oriented programming

play06:00

languages bring into the mix which is

play06:03

inheritance

play06:04

so we know that productivity can be

play06:06

increased if we can reuse parts of an

play06:10

existing implementation

play06:12

this is because we don't need to

play06:14

re-implement these existing parts we

play06:17

simply use them as they exist

play06:20

now there are two problems associated

play06:23

with the basic abstract data types that

play06:26

we discussed in the previous chapter

play06:30

firstly they are very difficult to reuse

play06:33

without performing some relatively

play06:36

drastic changes

play06:38

in effect what you would have to do is

play06:40

copy the entire adt out and then make a

play06:43

series of whatever required changes are

play06:47

needed

play06:48

to this copied abstract data type so

play06:51

this of course then doesn't allow for a

play06:53

lot of reuse of existing program code

play06:57

secondly all of these abstract data

play07:01

types are essentially independent from

play07:03

one another they are self-contained

play07:05

units and they all exist at exactly the

play07:08

same level

play07:10

so inheritance then if it is supported

play07:14

in an object-oriented programming

play07:15

language allows new classes to be fi

play07:18

defined in terms of existing classes so

play07:22

in other words these new classes can

play07:25

then inherit common parts from existing

play07:28

classes so for example we might have a

play07:31

person class and we might define for

play07:34

this person class a name and an age for

play07:37

example so in other words every person

play07:40

then has their own name and age now we

play07:43

may then have inherited classes from

play07:46

person for example we may have a student

play07:48

class and a lecturer class and maybe a

play07:51

pensioner class and these would then

play07:54

inherit from the person class

play07:57

what this then means is that the student

play08:01

lecturer and pensioner classes don't

play08:04

need to implement any functionality

play08:07

related to the name and age that is

play08:10

defined for the person class

play08:12

because they are derived classes or

play08:15

children of the person class they then

play08:18

already have that functionality included

play08:22

so inheritance then addresses both of

play08:24

the problems associated

play08:26

with regular abstract data types

play08:29

firstly they allow a lot of reuse

play08:33

of adts after only a few minor changes

play08:36

so for example if we look at a student

play08:38

class it can inherit all of the

play08:41

functionality from the person class

play08:43

which it doesn't need to re-implement

play08:45

and then all it needs to do is implement

play08:48

functionality related to what is

play08:50

specific for a student for example the

play08:53

student's student number

play08:55

and for example the

play08:58

final results for all of the subjects

play09:01

that the student has taken

play09:03

secondly they also then allow for

play09:06

classes to be defined in a hierarchy so

play09:10

this means we can then logically

play09:13

construct a series of classes that

play09:15

relate to one another in a very natural

play09:19

hierarchical fashion for example a

play09:22

student is a kind of person and

play09:25

therefore it logically makes sense for

play09:28

students to inherit from the person adt

play09:34

so now let's look at some terminology

play09:37

related to object oriented programming

play09:41

firstly the adts that we implement are

play09:45

usually referred to as classes in an

play09:49

object-oriented programming language

play09:52

now instances of these classes are

play09:54

usually called objects so an instance is

play09:57

an actual instantiation of a class which

play10:01

we can then work with and we can create

play10:03

as many instances as we want of a class

play10:08

now a class that inherits is referred to

play10:11

as a derived class or a subclass

play10:14

so in my example the student lecturer

play10:19

and pensioner classes are all derived

play10:23

classes or sub classes

play10:26

the class from which another class

play10:28

inherits is referred to as a parent

play10:30

class or a super class so in my example

play10:34

the parent class or super class would be

play10:38

the person class

play10:40

we then also have sub programs that

play10:43

define operations on objects in other

play10:46

words the behavior of a particular

play10:49

object

play10:50

and these are usually referred to as

play10:53

methods in some programming languages

play10:56

the term member function will be used as

play10:59

well but in a purely object-oriented

play11:02

sense we usually call these methods

play11:07

calls to methods in an object-oriented

play11:10

programming language are called messages

play11:13

so when we have a number of objects that

play11:16

are sending messages back and forth we

play11:18

refer to this as message passing

play11:21

now of course an object may have a

play11:24

number of methods associated with it and

play11:26

these methods all together define the

play11:29

behavior that is valid for the object in

play11:33

question

play11:34

so the entire collection of all of the

play11:36

objects methods is referred to as the

play11:39

message protocol or the message

play11:42

interface or sometimes just the

play11:44

interface of the object

play11:47

now messages have two parts firstly we

play11:50

have the method name and secondly we

play11:52

have the destination object so if we go

play11:55

back to my previous example if we have a

play11:58

student class and we create an object of

play12:01

the student class which is called s

play12:04

then the student class may have a method

play12:07

associated with it called print

play12:10

so we would call this print method then

play12:13

on an object that we have created and

play12:15

this object is an instance

play12:17

so we would have s dot print

play12:21

so in this example s would then be the

play12:24

destination object that's the object

play12:26

that we are sending the print message to

play12:29

and print would be the method name so

play12:33

this is then actually the message that

play12:35

we are sending to the object

play12:38

now in the simplest case a class will

play12:42

inherit all of the entities from its

play12:44

parent and then it can add more entities

play12:48

in other words essentially the child

play12:52

class or the derived class

play12:54

specializes the parent clause by adding

play12:57

additional appropriate functionality

play13:01

inheritance can be complicated by what

play13:04

are referred to as access controls that

play13:07

are applied to encapsulated entities so

play13:11

when we are talking about encapsulated

play13:13

entities we are talking either about

play13:16

member variables

play13:18

or methods that exist within a class

play13:23

so we can then apply access controls to

play13:26

these entities

play13:28

so a class could hide entities from its

play13:32

subclasses a class could also hide

play13:35

entities from its clients or it could do

play13:39

both hiding entities from both

play13:41

sub-classes and clients

play13:44

it may also be possible for a class to

play13:47

hide entities from its clients

play13:50

while allowing its sub-classes to see

play13:52

them and we would refer to this as

play13:56

protected access

play13:58

now strictly speaking protected access

play14:00

is not necessary

play14:02

however it is convenient

play14:05

but strictly speaking an object-oriented

play14:08

programming language only really needs

play14:10

to differentiate between hiding data

play14:13

from its subclasses and clients or

play14:17

making it accessible to both of them

play14:21

now besides inheriting methods as they

play14:24

are a class can also modify an inherited

play14:28

method so if we go back to my previous

play14:30

example

play14:31

our person class may provide a print

play14:34

method and then we may re-implement this

play14:38

print method in a different way in our

play14:41

student class

play14:42

so in this case what we would say then

play14:44

is that the student class overrides the

play14:48

inherited print method from its parent

play14:52

class

play14:53

and the method in the parent class in

play14:56

other words the print method in the

play14:58

person class is said to be overridden

play15:05

now we mentioned in the last chapter

play15:07

that adts have data associated with them

play15:12

which are represented by means of member

play15:15

variables that belong to the adts and

play15:18

they also have some kind of behavior

play15:21

associated with them which would be

play15:23

implemented by means of a method or a

play15:27

member function

play15:28

so the same of course then is true for

play15:31

classes and then also obviously objects

play15:35

which are instances of classes in an

play15:38

object-oriented programming language

play15:41

so there are two kinds of variables that

play15:43

can be associated with a class we can

play15:46

firstly have a class variable

play15:48

and a class variable has one instance of

play15:52

that variable that exists

play15:54

for the entire class so in other words

play15:57

all of the objects of that class share

play16:00

the class variables

play16:03

and then we also have instance variables

play16:06

and an instance variable has one

play16:09

instance per object that is created of

play16:12

that particular class

play16:14

so a good example of this would be a

play16:17

class that represents a savings account

play16:21

savings accounts

play16:23

and share an interest rate which is

play16:26

common to all of these accounts so the

play16:28

interest rate would be represented by

play16:31

means of a class variable

play16:34

however each individual

play16:36

savings account has its own balance

play16:39

which is separate and independent from

play16:42

all other savings account objects

play16:45

so the balance of a savings account

play16:48

would be represented by means of an

play16:50

instance variable there being one per

play16:54

object of the savings account class

play16:58

now to correspond with these two kinds

play17:01

of variables there are also two kinds of

play17:03

methods that can be associated with the

play17:06

class

play17:07

firstly we have class methods and these

play17:09

accept messages that go to the class as

play17:13

a whole

play17:14

in some object oriented programming

play17:16

languages it's also possible to call

play17:19

class methods on objects of the class

play17:22

but the point is that the message goes

play17:26

to the class not to an individual object

play17:29

and then we have instance methods and

play17:32

these accept messages for individual

play17:35

objects in other words instances of a

play17:38

class

play17:39

so for example in if we have our savings

play17:42

accounts class from our previous example

play17:45

that i've just used

play17:46

then a get interest rate and set

play17:50

interest rate method would be class

play17:52

methods because they work with data

play17:55

related to the class as a whole so those

play17:58

would then be messages that would be

play18:00

sent to the savings account class

play18:04

an instance method in this example would

play18:07

be a

play18:09

get balance or set balance method these

play18:12

must be sent to objects because they

play18:15

work with data related to each

play18:18

individual object namely the balance of

play18:21

the account

play18:24

now we've previously mentioned that

play18:26

inheritance is also very important in

play18:28

object-oriented programming languages

play18:31

and there is also differentiation

play18:33

between single inheritance where we have

play18:37

each class only having a single parent

play18:40

and multiple inheritance where a class

play18:43

may have multiple parents we'll go into

play18:46

detail on the difference between single

play18:48

inheritance and multiple inheritance

play18:51

later on

play18:52

in this lecture

play18:55

now object oriented programming is

play18:57

obviously a very useful feature to add

play19:00

to a high-level programming language but

play19:01

it doesn't come without disadvantages

play19:05

so

play19:06

one big disadvantage associated with

play19:09

inheritance

play19:11

and the class system in object-oriented

play19:14

programming languages is that

play19:16

interdependencies are created amongst

play19:19

classes and this is of course because we

play19:22

have classes that inherit from parent

play19:25

classes and therefore they rely on some

play19:28

of the functionality in the parent class

play19:31

so this may then complicate maintenance

play19:34

because if we change a parent class then

play19:37

it may require changes in all of the

play19:40

derived classes that inherit from it

play19:46

so now we've looked at the first two

play19:48

requirements that an object-oriented

play19:51

programming language must fulfill

play19:53

firstly the presence of adts

play19:56

and secondly a mechanism for inheritance

play20:00

we can now move on to the third

play20:02

important requirement for

play20:04

object-oriented programming which is

play20:07

dynamic binding

play20:09

so dynamic binding happens through

play20:11

what's called a polymorphic reference or

play20:14

pointer

play20:15

and a polymorphic reference or pointer

play20:17

can refer to objects of either a class

play20:20

or a descendant of that class in other

play20:24

words a class that inherits from the

play20:26

class in question

play20:28

so here we have an example of this

play20:31

we have a pointer over here called p

play20:34

and this is a pointer to a person

play20:38

object

play20:39

so this pointer can now be used as a

play20:43

polymorphic pointer and we do that by

play20:46

assigning to this pointer a new student

play20:50

object that has been created

play20:53

so this student object is an instance of

play20:56

the student class but because we assume

play20:58

that the student class inherits from the

play21:01

person class

play21:02

we can now use this pointer p which is a

play21:05

person pointer to refer to a student we

play21:09

could also do the same thing if we had a

play21:12

lecturer class that inherits from person

play21:15

in which case we would then set p to be

play21:18

a new lecturer and in fact we could do

play21:21

this with any class that inherits from

play21:24

the person class

play21:26

now it's important to understand

play21:28

that we must use a reference or a

play21:32

pointer in order to create this

play21:35

polymorphic structure

play21:37

that we've just demonstrated it

play21:41

becomes more complex when we are working

play21:44

with actual objects so in other words a

play21:46

person object or a student object but

play21:49

we'll get to more detail on this a

play21:51

little bit later on in this lecture

play21:54

now when

play21:56

overwritten methods are called through a

play21:58

polymorphic variable then the binding to

play22:01

the correct method will be dynamic in

play22:04

nature in other words it will occur at

play22:06

runtime

play22:07

so let's say for example that our person

play22:10

class includes a print method and our

play22:13

student class overrides this print

play22:16

method so it provides its own version of

play22:18

the print method what will then happen

play22:21

is if we call print on this pointer p

play22:26

then we will polymorphically call the

play22:29

correct version of the print method so

play22:32

in other words instead of calling the

play22:34

person classes print method we will call

play22:37

the student classes print method but

play22:40

this must occur dynamically at run time

play22:43

and this is because we can only

play22:45

determine what the actual type is that

play22:48

is being referred to

play22:50

through the p pointer at a runtime this

play22:53

can't be determined at compile time

play22:57

so this dynamic binding then allows for

play23:00

the easy extension

play23:03

of software systems during development

play23:05

as well as maintenance

play23:10

now related to dynamic bindings some

play23:13

programming languages provide support

play23:15

for abstract methods and abstract

play23:18

classes in c class abstract methods are

play23:22

referred to as pure virtual methods

play23:26

so an abstract method then does not

play23:29

include a definition instead it only

play23:32

defines a protocol for that method so

play23:36

there's no actual implementation of the

play23:39

body for an abstract method

play23:41

an abstract class then includes at least

play23:45

one abstract method possibly more

play23:48

and but very importantly an abstract

play23:50

class cannot be instantiated so we can't

play23:53

create objects of an abstract class

play23:56

now abstract methods are used to ensure

play24:00

that certain functionality must be

play24:03

implemented by derived classes so if we

play24:06

go back to our previous example of the

play24:08

person and student class

play24:11

and the lecturer and pensioner classes

play24:16

all three of which inherit from the

play24:18

person class then we might decide that

play24:21

we want to ensure that every person

play24:25

object can be printed however it might

play24:28

not make sense for us to implement the

play24:30

print method in the person class

play24:33

so what we can do is we can provide an

play24:36

abstract method for the print method

play24:40

and that would be in the person class it

play24:42

wouldn't include any implementation at

play24:45

all but what this thing does is it

play24:47

ensures that all of the derived classes

play24:50

must implement this print method

play24:53

unless they will also be abstract if we

play24:56

want to create instances of the student

play24:59

class the lecturer class and pensioner

play25:01

class then they must all implement the

play25:05

print method

play25:07

that will then mean that these classes

play25:09

will be concrete and we can therefore

play25:11

create

play25:12

instances of the student the lecturer

play25:16

and the pensioner classes

play25:19

we can of course create pointers

play25:23

or references

play25:25

to the person class and this will allow

play25:28

us to still polymorphically

play25:30

use that point then to

play25:33

allow assigning to it of any of the

play25:36

derived classes however we can't

play25:38

directly create an instance of the

play25:41

person class itself because it is now

play25:44

abstract

play25:47

so now we've discussed the basics of

play25:49

object oriented programming and we can

play25:51

move on to the design issues which we

play25:54

will use in order to discuss the example

play25:58

object-oriented programming languages

play26:00

which we'll discuss towards the end of

play26:02

this lecture and over the course of the

play26:05

next lecture

play26:07

so there are a number of design issues

play26:09

related to object-oriented programming

play26:11

firstly we have the exclusivity of

play26:14

objects so this relates to how heavily

play26:17

the programming language relies on

play26:20

objects and their classes

play26:23

do they rely very heavily on

play26:26

objects

play26:27

are objects simply added on as an

play26:30

additional feature where the rest of the

play26:33

programming language is imperative in

play26:35

nature and what sort of balance between

play26:38

those can we achieve within the

play26:40

programming language

play26:42

then we have a very important question

play26:44

of where the subclasses are considered

play26:47

to be subtypes we'll talk about that in

play26:49

some more detail in a moment then we

play26:53

need to consider type checking with

play26:56

reference to polymorphism so this

play26:58

relates to how type checking for

play27:01

messages occur in other words how do we

play27:04

type check methods that are called

play27:08

for a particular class

play27:11

then we have support for single and or

play27:15

multiple inheritance so should the

play27:17

programming language support only single

play27:19

inheritance or should it also allow for

play27:22

multiple inheritance and what kind of

play27:25

problems are associated with multiple

play27:27

inheritance and how can we address those

play27:30

problems

play27:32

next we have object allocation and

play27:34

de-allocation

play27:36

so this relates to whether objects can

play27:39

be allocated on the stack or on the heap

play27:43

and how this allocation happens and how

play27:45

de-allocation of these objects will take

play27:49

place is the allocation manual or does

play27:52

it take place automatically

play27:55

then

play27:57

questions related to dynamic and static

play28:00

binding are also important

play28:02

so this relates again to polymorphic

play28:05

messages where we call polymorphic

play28:08

methods related to a particular class

play28:11

through a polymorphic reference or

play28:14

pointer

play28:16

so

play28:17

is this binding dynamic is it static or

play28:20

can the programmer decide whether it's

play28:23

dynamic or static in certain instances

play28:27

next we have the question of nested

play28:29

classes so some object-oriented

play28:32

programming languages allow classes to

play28:34

be nested others do not if nested

play28:37

classes are allowed then what will the

play28:39

semantics be related to these nested

play28:42

classes

play28:43

so what data can these nested classes

play28:46

directly access

play28:48

and what data can the containing class

play28:51

access within a nested class

play28:54

and then finally we have the

play28:56

initialization of objects how do objects

play29:00

get initialized

play29:02

do they have constructors and if so are

play29:05

these constructors called automatically

play29:08

or do they have to be explicitly called

play29:11

now we'll look at each of these design

play29:13

issues separately and then we'll move on

play29:16

to our programming language examples and

play29:19

look at how each of the programming

play29:21

languages will consider in this chapter

play29:24

answer these various design issues and

play29:27

deal with the various problems that are

play29:29

associated with those decisions

play29:35

so let's start off by looking at the

play29:37

first of our design issues namely the

play29:40

exclusivity of objects so as i mentioned

play29:43

on the previous slide this relates to

play29:46

how heavily the programming language

play29:48

depends on objects and the classes that

play29:52

define these objects now they're broadly

play29:55

speaking three approaches that we can

play29:57

use related to the exclusivity of

play29:59

objects and we'll look at examples of

play30:02

all three of these when we get to the

play30:05

example programming languages towards

play30:07

the end of this chapter

play30:09

so the first approach that can be used

play30:11

is that everything in the programming

play30:14

language is an object now when we say

play30:16

everything we mean every single possible

play30:19

thing that can be represented in the

play30:22

language is an object so this extends to

play30:25

very basic entities things like integers

play30:29

floats doubles and boolean values these

play30:32

are not primitive values these are

play30:34

actually objects that are represented so

play30:38

an example of a programming language

play30:39

that uses this approach is small talk

play30:42

which is a purely object-oriented

play30:45

programming language

play30:46

so the big advantage associated with

play30:50

this approach is that it's very elegant

play30:52

and it's very uniform everything works

play30:55

the same way because everything is an

play30:58

object so everything works by means of

play31:00

message passing

play31:02

and we manipulate

play31:04

objects so we are always working with

play31:07

the same kinds of data entities there

play31:10

are no exceptions

play31:12

the bigger disadvantage however is that

play31:15

simple operations are very slow and this

play31:17

is because there is always some overhead

play31:20

introduced whenever we are working with

play31:22

objects

play31:23

so objects take up a little bit more

play31:26

space in memory because we need to

play31:28

represent information related to how the

play31:31

object is stored in memory and how its

play31:34

resources are allocated also whenever we

play31:38

call a method on an object then there is

play31:41

some additional processing overhead that

play31:43

has to take place to allow for the

play31:46

message passing to happen and this is

play31:48

particularly the case if we are working

play31:51

with polymorphic references to objects

play31:56

the second approach that we can use is

play31:58

that we can add objects to a complete

play32:01

typing system

play32:03

so this is the case in a programming

play32:05

language like c plus

play32:08

here we have a language that is

play32:10

primarily imperative so we have a lot of

play32:13

features that the language supports

play32:15

things like structs things like

play32:17

enumerations things like unions but then

play32:21

in addition to this we then have an

play32:24

object model that is essentially built

play32:27

onto the language

play32:29

so the big advantage with this is that

play32:31

simple operations can be very fast

play32:34

because they are represented in a very

play32:37

primitive fashion we can for example

play32:40

work with unions and as we know unions

play32:42

are very memory efficient and they will

play32:46

also be efficient from an operational

play32:48

perspective because we're not working

play32:50

with objects in that case

play32:52

however the big disadvantage to this

play32:54

approach is that it creates a very

play32:56

confusing type system we now not only

play33:00

have to worry about objects and their

play33:03

classes we also have to worry about all

play33:06

of these other entities that don't

play33:08

follow the object model

play33:12

the third approach that we can use is

play33:15

something of a middle ground between the

play33:17

other two approaches so here we use an

play33:20

imperative typing system for primitives

play33:22

but then we make everything else an

play33:25

object

play33:26

java is an example of a programming

play33:27

language that uses this approach so in

play33:30

java primitive types like ins floats

play33:34

doubles and boolean values are all

play33:36

represented as primitives but then

play33:38

everything else is represented using

play33:41

objects

play33:42

so the advantage here then is that

play33:44

simple operations involving these

play33:46

primitive types can be very fast but the

play33:50

typing system still remains very small

play33:52

and manageable so we only have to deal

play33:55

with a small set of primitive types and

play33:58

then objects and there are no additional

play34:00

types such as unions for instance or

play34:04

structs or anything else that would

play34:06

complicate the system

play34:08

the disadvantage however is that we are

play34:10

still dealing with two type systems that

play34:13

we have to use together however this

play34:15

problem is not as bad as a situation

play34:19

where we have an entire imperative type

play34:22

system

play34:23

with an object model attached to it

play34:26

so what i would like you to do at this

play34:28

point is to pause the video and try to

play34:31

think how each of these three approaches

play34:34

compare in terms of orthogonality

play34:43

the next design issue that needs to be

play34:45

answered for an object-oriented

play34:47

programming language

play34:48

is are subclasses considered to be

play34:52

subtypes

play34:53

so this boils down to the question of

play34:57

whether an is a relationship holds

play35:00

between a subclass object and a parent

play35:04

class object

play35:06

so if we take this back to my previous

play35:09

example where we have a person class in

play35:11

the student class

play35:13

if we can say that a student

play35:16

is a type of person then an is a

play35:20

relationship holds between them

play35:23

and in this case we would then say that

play35:25

the derived class the student class is a

play35:29

subtype of the parent class in other

play35:32

words the person class

play35:35

so even is a relationship holds between

play35:38

a subclass object and a parent class

play35:41

object then objects of the derived class

play35:44

must behave in the same way as the

play35:47

parent class object

play35:49

so in other words whatever behavior is

play35:52

associated with the parent class

play35:55

in terms of messages that the parent

play35:57

class can respond to that same behavior

play36:01

must be implemented in the derived

play36:03

clause

play36:05

so as i said then the derived clause is

play36:07

considered to be a subtype if this is a

play36:10

relationship holds

play36:12

[Music]

play36:13

but

play36:14

subclasses then in this case are

play36:16

somewhat limited so subclasses can only

play36:19

add variables and methods

play36:23

to the variables and methods that are

play36:26

inherited from the parent class it is

play36:29

not possible for the subclass to remove

play36:32

variables or methods if variables or

play36:35

methods are removed by the derived

play36:38

clause then this means that the derived

play36:40

clause no longer behaves in exactly the

play36:42

same way as the parent class did so

play36:46

we're only allowed to add additional

play36:48

functionality in the derived clause

play36:51

also if the derived clause overrides

play36:54

methods that are provided in the parent

play36:57

class then this overriding must happen

play37:00

in a compatible way

play37:02

so the overridden methods must have the

play37:06

same number of parameters as the method

play37:09

that they are overriding and also the

play37:12

parameters and return types must be type

play37:15

compatible with one another some

play37:17

programming languages limit this even

play37:20

further and require that the parameters

play37:22

and return types of the overridden

play37:25

methods must be exactly the same as the

play37:28

methods in the parent class that are

play37:30

being overridden

play37:34

the next design issue that we need to

play37:36

consider is how type checking works in

play37:39

the presence of polymorphism

play37:41

so if our object-oriented programming

play37:43

language is to be strongly typed then we

play37:46

need to check two things whenever a

play37:48

polymorphic message is sent to a method

play37:52

through a polymorphic pointer or

play37:56

reference

play37:57

these two things are firstly that the

play38:00

formal parameters of the method

play38:03

match the parameter types of the message

play38:06

that is being sent to the object

play38:08

and then secondly that the return type

play38:11

of the method matches the expected

play38:14

return type of the message sent to the

play38:18

object

play38:20

now this type checking can occur

play38:22

dynamically at runtime however the two

play38:25

major drawbacks associated with this

play38:28

firstly it's relatively costly and this

play38:30

is because the type checking has to

play38:32

happen at runtime and therefore it

play38:35

consumes runtime resources because it

play38:38

isn't taking place prior to runtime

play38:41

during compilation

play38:43

secondly error detection is delayed

play38:46

until run time so this means that we

play38:48

won't necessarily pick up type

play38:50

mismatches when we compile a program

play38:54

instead we will detect these mismatches

play38:57

at runtime as the program is executing

play39:01

now we can make this type checking

play39:04

static however we then need to introduce

play39:08

an additional restriction

play39:10

to our object-oriented programming

play39:12

language and this is that the overriding

play39:15

methods must be restricted to have

play39:17

exactly the same parameter and return

play39:20

types as the parents method that is

play39:23

being overridden

play39:25

this then ensures that there won't be

play39:28

any difference between the method that

play39:30

is actually being called and the one

play39:33

that is present in the parent class and

play39:36

therefore checking is easy and can

play39:39

happen at compile time because the types

play39:43

are all

play39:44

ensured to be correct

play39:49

the next design issue that we need to

play39:51

consider is whether an object-oriented

play39:54

programming language will support only

play39:56

single inheritance or multiple

play39:59

inheritance

play40:00

so multiple inheritance quite simply is

play40:03

a situation where a newly defined class

play40:05

inherits from two or more parent

play40:08

classes now the advantage associated

play40:11

with support for multiple inheritance is

play40:14

that it gives us some additional

play40:16

flexibility and power

play40:18

it allows us to conveniently express

play40:21

fairly complicated inheritance

play40:23

structures and can be fairly useful in

play40:26

certain situations

play40:28

however multiple inheritance does have

play40:31

two drawbacks associated with it the

play40:34

biggest drawback is that it adds

play40:36

complexity to the language itself

play40:40

as well as some implementation

play40:42

complexity for a programmer who's using

play40:45

multiple inheritance

play40:47

now this primarily relates to collisions

play40:51

between

play40:52

names

play40:53

so this happens in a situation where we

play40:56

have two parent classes that have

play40:58

entities with the same name

play41:01

so let's say for example that we have a

play41:03

class called c

play41:05

and it inherits from two parent classes

play41:08

p1 and p2

play41:10

now if p1 and p2 both implement a print

play41:14

method then this means that we have two

play41:17

print methods that are inherited by the

play41:20

derived class c

play41:22

and in this situation it's up to the

play41:25

programmer typically to specifically

play41:28

indicate which of the parent classes

play41:31

they are referring to when the print

play41:34

method is called in the derived class c

play41:39

now these kinds of naming collisions are

play41:42

implicit when diamond inheritance occurs

play41:46

and we'll look at diamond inheritance in

play41:48

some more detail on the next slide

play41:51

the second disadvantage associated with

play41:54

multiple inheritance is that there's an

play41:57

additional level of inefficiency that is

play42:01

introduced to it

play42:02

and this is because dynamic binding

play42:05

costs a little bit more whenever

play42:07

multiple inheritance is involved the

play42:10

reason for this is that if a method is

play42:12

called in a derived class and it is not

play42:14

defined within that derived class then

play42:18

multiple parents have to be searched for

play42:21

the implementation of that method that

play42:23

is being called and that obviously takes

play42:26

more time during execution

play42:29

however this inefficiency is not a major

play42:32

inefficiency and therefore this

play42:34

disadvantage is not a great one

play42:39

so here we have a diagram illustrating

play42:42

diamond inheritance

play42:44

we have a situation where we have a

play42:47

single derived clause called a in this

play42:50

case

play42:51

and a inherits from two parents

play42:54

b

play42:55

on that side and c on the other side

play42:58

b and c then both inherit from the same

play43:02

parent which is class a right at the top

play43:06

of the diamond

play43:08

so what's important to understand with

play43:10

diamond inheritance

play43:12

is that the problem doesn't depend on

play43:15

what is implemented in either class b

play43:19

or class c

play43:21

instead let's assume that we have a

play43:24

method implemented in class a

play43:26

and this method is a print method

play43:30

so what this means then is that b will

play43:32

inherit the print method from a and c

play43:36

will also inherit the same print method

play43:39

from a now at this point class a has two

play43:44

parents b and c

play43:46

and both of them have a print method

play43:49

present

play43:50

now it doesn't matter that these print

play43:52

methods are exactly the same because

play43:55

they've been inherited from the same

play43:57

parent class a in this example the point

play44:01

is that they are two distinct print

play44:03

methods even though the implementation

play44:05

is exactly the same and therefore when

play44:09

class a refers to the print method it

play44:12

can't be sure whether we are referring

play44:14

to the one in class b or class c

play44:17

so typically in class a we then need to

play44:20

use some kind of scope resolution to

play44:23

indicate that we are referring to the

play44:25

print method either in class a or class

play44:29

b or class c

play44:31

that will then alleviate the problem

play44:33

because we've indicated to the compiler

play44:36

specifically which method we are

play44:38

referring to

play44:43

a number of issues need to be considered

play44:45

when we are looking at our next design

play44:49

issue which relates to the allocation

play44:52

and de-allocation of objects so this all

play44:55

relates to where objects are allocated

play44:59

from and where they are deallocated and

play45:03

this of course then might be either the

play45:05

stack or the heap or a combination of

play45:08

these

play45:10

so if objects in an object oriented

play45:12

programming language behave like adts

play45:15

then it means that we can allocate them

play45:17

from the runtime stack if we simply

play45:20

declare a variable that has the type of

play45:23

a particular class

play45:25

or alternatively we can explicitly

play45:28

create them on the heap

play45:31

typically what would happen here is that

play45:33

we would have to use an explicit

play45:35

operator like new in order to allocate

play45:39

the object on the heap

play45:41

now it is possible that an

play45:43

object-oriented programming language may

play45:46

have all of its objects allocated on the

play45:50

heap

play45:51

and in this case then all of these

play45:54

objects that are used in this

play45:55

object-oriented programming language

play45:57

will be used through either pointers or

play46:00

reference variables now this is the case

play46:04

in java every object is handled by means

play46:08

of a reference

play46:10

so this vastly simplifies assignment

play46:13

because seeing as we're not working with

play46:15

stack allocated objects we don't have to

play46:17

perform a copy from one object to

play46:20

another instead we are simply assigning

play46:24

references or pointers to each other so

play46:26

we are just been performing a reference

play46:29

copy

play46:30

now dereferencing can be implicit within

play46:33

an object-oriented programming language

play46:36

and again this is the case in java we

play46:38

don't explicitly have to de-reference

play46:41

our references to objects we simply use

play46:44

those references and it is as though we

play46:47

are using the objects that are being

play46:49

referred to

play46:51

now if objects are allowed to be stack

play46:54

dynamic then then an additional

play46:56

complexity comes into play and this

play46:59

occurs when we are working with subtypes

play47:03

so let's assume that we have two classes

play47:07

a and b

play47:08

and we assume that b inherits from a and

play47:12

b is also a subtype of a so this means

play47:17

all of the operations then that are

play47:18

valid for a are also valid for b

play47:23

so now let's consider this program code

play47:26

over here so we have a variable called

play47:29

avar which is of type a what's important

play47:33

to understand here is that avar

play47:36

is stack allocated so it is not

play47:39

allocated on the heap it's allocated on

play47:41

the runtime stack

play47:43

then we have another variable bivar

play47:46

which is of type b that's also legal and

play47:49

now we perform an assignment where we

play47:51

are assigning b far to ava now this is

play47:56

legal because as we've already seen a

play48:00

moment ago b is a subclass of a

play48:04

now if we assume that class b adds

play48:08

additional variables in other words it's

play48:10

storing additional data

play48:13

in addition to the data that is defined

play48:15

for class a

play48:17

and what happens here is a truncation or

play48:21

sometimes this is referred to as object

play48:23

slicing

play48:25

so what happens here is because ava and

play48:28

bivar have been allocated on the stack

play48:32

ava only has space for whatever

play48:35

variables are defined for class a

play48:39

b var has also those variables defined

play48:42

for class a but additionally it has some

play48:45

more variables that have been defined

play48:48

but

play48:48

there is no space for those additional

play48:52

variables in ava so what happens then is

play48:56

only the variables that are

play48:59

valid for ava in other words defined

play49:02

within class a are copied from a beaver

play49:06

so this is a partial copy that takes

play49:08

place and part of the data is then lost

play49:12

during this assignment

play49:15

the last question that we need to answer

play49:18

which falls into this category

play49:21

is if we have heap allocated objects

play49:24

then is heap allocation explicit or

play49:27

implicit

play49:28

so in some object-oriented programming

play49:30

languages like c plus we need to

play49:32

explicitly de-allocate heap allocated

play49:35

objects using delete

play49:37

in other programming languages this

play49:40

isn't required so for example in small

play49:43

talk and in java we have the garbage

play49:46

collector which automatically implicitly

play49:49

takes care of cleaning up heap allocated

play49:52

objects for us

play49:56

the next design issue that needs to be

play49:59

considered is whether dynamic and static

play50:02

binding can occur for messages within an

play50:06

object-oriented programming language

play50:08

and if so then how are they dealt with

play50:12

now

play50:13

should every binding then be dynamic in

play50:17

nature well obviously it's not an option

play50:20

for none of the bindings to be dynamic

play50:22

because in that case we can't have

play50:25

dynamic message binding and this is one

play50:28

of the cornerstones that is very central

play50:32

to object oriented programming

play50:35

so we may decide to make all of our

play50:38

bindings be dynamic

play50:40

however this is very inefficient because

play50:43

all of the bindings will then happen at

play50:45

runtime and therefore will consume

play50:48

runtime resources

play50:50

what i would like you to do at this

play50:52

point is to pause the video and try to

play50:55

see if you can think of any advantages

play50:58

to making all of our method bindings

play51:02

dynamic in nature

play51:08

a middle ground thing between these two

play51:10

approaches is that we could allow the

play51:13

programmer to specify which bindings are

play51:16

static and which are dynamic this is the

play51:19

route that c plus provides for us

play51:22

and what i would like you to do at this

play51:24

point is again pause the video and see

play51:27

if you can think of any advantages and

play51:29

disadvantages to this approach

play51:38

the second last design issue we need to

play51:41

consider in an object-oriented

play51:42

programming language is whether nested

play51:45

classes will be supported or not

play51:48

so if a new class is defined and it's

play51:50

needed only by one other class then

play51:53

there's no reason for this new class to

play51:56

be visible to any other classes

play51:59

so an object-oriented programming

play52:01

language may decide to allow for the new

play52:04

class to be nested inside the class that

play52:07

uses it

play52:08

a good example of this would be a linked

play52:11

list class

play52:13

a linked list is built up out of nodes

play52:15

but it is not necessary for anything

play52:18

outside of the linked list class to know

play52:20

about these nodes

play52:22

all that external classes or functions

play52:24

are interested in would be the data that

play52:27

is contained within the linked list so a

play52:30

programming language may allow the node

play52:33

class to be nested inside the linked

play52:36

list class

play52:37

an object oriented programming language

play52:39

may go even further than this and it may

play52:42

allow a new class to be nested inside a

play52:45

sub-program

play52:48

now there are

play52:50

two main issues that need to be

play52:52

considered even is that classes are

play52:54

supported and these both relate to the

play52:56

visibility of members within a class

play53:01

so firstly we need to consider

play53:04

the visibility of members within the

play53:07

nesting class and how they are visible

play53:10

to the nested class

play53:13

and secondly we need to consider how

play53:15

members of the nested class are visible

play53:19

to the nesting class so some programming

play53:22

languages may allow for complete access

play53:25

to all of the members even private

play53:27

members

play53:28

some programming languages may restrict

play53:31

this access somehow and we'll look at

play53:33

some of these examples in the

play53:36

programming language examples we get to

play53:38

later on in this discussion

play53:43

the final design issue relates to how

play53:46

objects are initialized so this relates

play53:49

to the creation of objects

play53:52

so firstly an object-oriented

play53:55

programming language needs to decide if

play53:57

objects are initialized to values when

play54:00

they are created so in other words we're

play54:03

talking about the initialization of the

play54:06

member variables of a class

play54:09

now the initialization might be explicit

play54:12

in which case we would actually

play54:14

explicitly call a constructor

play54:17

or the initialization may be implicit

play54:19

initialization would be implicit in a

play54:21

situation where a programming language

play54:24

provides a default constructor that is

play54:27

implicitly provided and doesn't have to

play54:30

be implemented by the programmer in that

play54:33

case when an object is created then this

play54:35

default constructor would be

play54:37

automatically called

play54:40

we also then need to consider how parent

play54:44

class members are initialized when a

play54:46

sub-class object is created and this is

play54:50

a little bit more interesting than the

play54:52

initialization of data that is

play54:54

specifically defined for a class

play54:57

so again here we may have explicit

play55:00

initialization or implicit

play55:02

initialization

play55:03

with implicit initialization we would

play55:05

have a situation where the parent

play55:07

classes default constructor would be

play55:11

automatically called

play55:13

when the derived classes constructor is

play55:17

called

play55:18

with explicit initialization we would

play55:20

always need to explicitly indicate which

play55:23

constructor in the parent class we want

play55:26

to invoke when a constructor in the

play55:29

child class

play55:30

is initiated

play55:34

we will now move on to the last topic of

play55:37

this lectures discussion where we will

play55:39

look at object-oriented programming

play55:42

support in the small talk programming

play55:45

language

play55:46

so small talk was the very first

play55:49

object-oriented programming language and

play55:52

it is considered to be a purely

play55:54

object-oriented programming language for

play55:57

a very long time it was in fact the only

play56:01

purely object-oriented programming

play56:03

language

play56:04

so as such small talk is the basis for

play56:08

most object-oriented programming

play56:10

concepts in other programming languages

play56:13

as we use them today

play56:15

now in small talk everything is an

play56:17

object so this includes all of the very

play56:20

basic types like integers and floats

play56:23

this means that small talk has no

play56:25

characteristics of imperative

play56:27

programming languages at all and all of

play56:30

its objects are allocated from the heap

play56:33

so there are no stack allocated objects

play56:36

in small talk

play56:38

now the fact that everything is an

play56:40

object in small talk makes the language

play56:42

very slow so what i would like you to do

play56:44

at this point is to pause the video and

play56:46

try to explain why this is the case

play56:53

now in small talk all computation is

play56:56

also handled in a uniform fashion

play56:59

and this is by means of message passing

play57:02

between objects

play57:04

so all of the operations that are

play57:07

performed in small talk are before

play57:10

performed in a standard uniform fashion

play57:13

now this also is another factor that

play57:15

makes small talk relatively slow and

play57:18

what i would like you to do at this

play57:19

point is to again pause the video and

play57:21

try to explain why this is the case

play57:29

now because all objects in small talk

play57:32

are heap allocated they need to be

play57:34

accessed either by means of a pointer or

play57:38

by a reference

play57:40

in the case of small talk object access

play57:43

happens by means of typeless reference

play57:46

variables

play57:47

so

play57:48

there is no need to work with pointers

play57:52

and references are also implicitly

play57:54

de-referenced so there is no need to use

play57:57

complex dereferencing notation in order

play58:00

to access objects instead objects are

play58:04

simply referred to by name

play58:07

now all the allocation of objects takes

play58:10

place implicitly and this is because

play58:13

small talk uses a garbage collector to

play58:16

free up memory that is occupied by

play58:18

objects that are no longer required

play58:21

now this the allocation can be slow

play58:24

depending on how the garbage collector

play58:27

is implemented

play58:28

in whichever version of small talk is

play58:31

being used

play58:32

what i would like you to do at this

play58:34

point is to pause the video and see if

play58:36

you can think of another disadvantage

play58:39

of this reliance on a garbage collector

play58:42

that small talk has

play58:49

small talk of course implements

play58:51

polymorphism and therefore there has to

play58:54

be type checking for messages that are

play58:57

sent to objects

play58:59

so all bindings of messages to methods

play59:02

in small talk takes place dynamically at

play59:06

run time and the procedure that is used

play59:08

to find a matching method is quite

play59:11

simple it's a search process that is

play59:13

performed and the search starts in the

play59:17

object to which the message has been

play59:19

sent

play59:20

if a matching method is not found in

play59:23

this object then we move on to the

play59:27

parent of the object that the message

play59:29

has been seen to and perform a search

play59:32

there the search continues up the

play59:34

hierarchy until eventually the object

play59:37

class is reached the object class is the

play59:40

single class that is at the root of all

play59:43

classes in small talk

play59:46

now if a match is not found by the stage

play59:49

that the object class has been reached

play59:52

then this means that the method has not

play59:55

been found and therefore a type mismatch

play59:59

occurs

play60:00

so type checking then as a result can

play60:03

only occur at run time as well and is

play60:06

therefore dynamic in nature

play60:08

so as i said a type error occurs when no

play60:11

matching method is found through this

play60:13

search process

play60:15

and as a result of this type errors can

play60:17

then only be detected at runtime

play60:21

so this runtime type checking is also

play60:24

another factor that makes more talk slow

play60:26

because once again the checking

play60:28

procedure takes up resources at run time

play60:34

finally inheritance in small talk is

play60:37

also fairly simple and straightforward

play60:41

so in small talk subclasses can inherit

play60:43

from superclasses and a subclass will

play60:47

inherit all of the instance variables

play60:49

instance methods and class methods from

play60:52

its superclass

play60:54

now in small talk all subclasses are

play60:57

subtypes so this means that subclasses

play61:00

can only add to the functionality that

play61:02

they inherit from their super class

play61:06

um it's not possible for the subclass to

play61:10

hide any functionality that appears in

play61:13

the parent class

play61:15

now the inheritance model in small talk

play61:18

is fairly simple

play61:20

methods with the same name and protocol

play61:23

as a parent method override the parent

play61:27

method

play61:29

however it is possible for the derived

play61:32

class to access an overridden method in

play61:35

a parent class it does this by means of

play61:38

the super special word so essentially we

play61:42

just use super to refer to the parent

play61:45

class and then we can access any

play61:48

functionality that has been overridden

play61:50

and is therefore not directly accessible

play61:53

in the parent class

play61:55

small talk also only supports single

play61:58

inheritance and doesn't support multiple

play62:00

inheritance at all

play62:03

all right so that concludes this

play62:04

discussion in the next lecture we will

play62:06

finish off the chapter by looking at

play62:09

some more examples of object-oriented

play62:12

programming languages

Rate This

5.0 / 5 (0 votes)

Related Tags
OOP PrinciplesProgramming ConceptsDesign IssuesInheritance ModelPolymorphismSmalltalk LanguageDynamic BindingAbstract Data TypesSoftware DevelopmentObject-Oriented Languages