COS 333: Chapter 11, Part 2

Willem van Heerden
10 Nov 202158:50

Summary

TLDRThis lecture delves into abstract data types (ADTs) and encapsulation, focusing on their implementation in various programming languages. It compares Java, C++, C#, and Ruby, highlighting how each language supports ADTs and access control. The discussion also covers parameterized ADTs, or generics, in C++, Java, and C#, explaining how they allow for type-specific classes at compile time. The lecture concludes with an exploration of encapsulation constructs that facilitate organization and partial compilation in large projects, such as namespaces in C# and Java packages.

Takeaways

  • πŸ“˜ The lecture concludes the discussion on abstract data types (ADTs) and encapsulation, focusing on their implementation in Java, C#, and Ruby, as well as parameterized ADTs.
  • πŸ”„ Java supports ADTs similarly to C++ but with exceptions: all user-defined types are classes, objects are heap-allocated with garbage collection, and access control is specified individually for each member.
  • πŸ—ƒοΈ Java uses 'package' as a scope for classes without access modifiers, allowing access within the same package, which is akin to C++'s 'friend' concept but less strict.
  • πŸ“‘ Java's source files are compiled into bytecode, typically kept in '.class' files, and the '.java' source is not shared with clients to hide implementation details.
  • πŸ“ Javadoc tool in Java is used to generate documentation for classes, which is provided to clients instead of the source code for better encapsulation.
  • πŸ”  C# is influenced by both C++ and Java, offering public, private, protected, internal, protected internal, and private protected access modifiers, and supports structs in addition to classes.
  • πŸ”„ C# structs differ from classes, being lightweight and not supporting inheritance or heap allocation, limiting their use in building ADTs like linked lists.
  • 🏒 C# introduces properties as a convenient mechanism for implementing getters and setters, allowing for direct access to member variables with validation and processing.
  • πŸ’  Ruby uses classes for encapsulation with dynamic interfaces, allowing classes to be modified at runtime, which can be useful for situations requiring flexible programming.
  • πŸ”  Ruby's instance variables are private by default, and all methods are instance methods, with no standalone functions, reflecting the language's 'everything is an object' philosophy.
  • πŸ“ The script also covers parameterized ADTs, which are necessary in statically typed languages to allow the creation of generic classes that can work with different data types.

Q & A

  • What are the main topics discussed in the second part of the lecture on Chapter 11?

    -The main topics discussed include abstract data types (ADTs), encapsulation, and how these concepts are implemented in Java, C#, and Ruby programming languages. The lecture also covers parameterized abstract data types and their implementation in different programming languages.

  • How is the support for ADTs in Java similar to C++?

    -Java's support for ADTs is similar to C++ in that both languages use classes to define user types. However, Java has a few exceptions, such as all objects being allocated from the heap and accessed through reference variables, automatic de-allocation via garbage collection, and explicit access control modifiers for each class member.

  • What is the difference between access control modifiers in C++ and Java?

    -In C++, access control modifiers can be applied to groups of entities using labels like 'public:', affecting everything under it. In contrast, Java requires explicit access control modifiers for each member, such as 'private' or 'public', and does not have a 'protected' modifier like C++ does.

  • What is the concept of package scope in Java, and how does it relate to the concept of 'friends' in C++?

    -Package scope in Java refers to the visibility of entities without access control modifiers within the current package. It is similar to the concept of 'friends' in C++, but 'friends' in C++ is stricter as it requires explicit granting of friendship by a class, whereas in Java, any class within the same package has access to package scope entities.

  • How does the implementation of a Stack class in Java differ from its implementation in C++?

    -In Java, the entire class definition, including member variables and methods, is placed inside a single source file with a .java extension. Java does not separate header and implementation files. Also, Java uses the 'private' keyword to hide member variables from clients, and the source file is compiled into bytecode, which is usually not shared with clients, providing better encapsulation.

  • What are the additional access modifiers provided by C# that relate to assemblies?

    -C# provides three additional access modifiers related to assemblies: 'internal', 'protected internal', and 'private protected'. These modifiers help control the accessibility of classes and members within assemblies, which are collections of user-defined data types and resources.

  • How do structs differ from classes in C#?

    -In C#, structs are lightweight classes that do not support inheritance and can only exist on the stack, unlike classes. They are used for small, lightweight data structures and cannot reference themselves, limiting their use in building ADTs like linked lists.

  • What is the purpose of properties in C# and how do they differ from accessor methods?

    -Properties in C# provide a more convenient mechanism for implementing accessors and mutators without relying on explicit method calls. They allow for direct access to data members while still allowing for validation and processing code within the get and set blocks, unlike traditional accessor methods.

  • What is the significance of dynamic interfaces in Ruby, and how do they affect the programming language evaluation criteria?

    -Dynamic interfaces in Ruby allow the structure of a class to change at runtime, enabling metaprogramming. This affects the evaluation criteria by introducing flexibility and adaptability in how classes and objects can be modified during execution, which can be beneficial for certain use cases but may also introduce complexity.

  • Why don't dynamically typed languages require support for parameterized abstract data types?

    -Dynamically typed languages don't require parameterized ADTs because they allow for flexibility in the types of data that can be used with objects and functions without explicit type declarations. The language runtime handles type checking, making separate implementations for different types unnecessary.

  • What is the difference between template classes in C++ and generic classes in Java?

    -Template classes in C++ are a compile-time construct that generates a new version of the class for each specified type, while generic classes in Java are a runtime construct with a single class that uses object instances and casts to ensure type safety, with the compiler inserting the necessary casts to catch type errors at compile time.

  • How do parameterized ADTs, or generic classes, help in organizing large projects and supporting partial compilation?

    -Parameterized ADTs or generic classes allow for the creation of flexible, reusable code components that can work with different data types. This modularity helps in organizing large projects by separating concerns and enabling partial compilation, as changes to the implementation of a generic class do not require recompilation of the entire project.

  • What are the different encapsulation constructs provided by various programming languages to support large projects?

    -Different encapsulation constructs include nested sub-programs in languages like Python, JavaScript, and Ruby; header and implementation file separation in C and C++; assemblies in C#; and naming encapsulations like namespaces in C# and C++, and packages in Java, which help in organizing code logically and supporting partial compilation.

Outlines

00:00

πŸ“˜ Abstract Data Types and Encapsulation in Java

This paragraph discusses the implementation of Abstract Data Types (ADTs) in Java, highlighting the differences between Java and C++. It emphasizes that all user-defined types in Java are classes, objects are allocated from the heap with garbage collection handling de-allocation, and access control is specified for each member variable. Java's package scope is introduced as a visibility level for class entities within the same package, and an example of a Stack class implementation in Java is provided to illustrate these concepts.

05:03

πŸ“™ Java Source Files and Documentation with Javadoc

The second paragraph explains the structure of Java source files, which contain the full class definition, including member variables and methods, within a single .java file. It discusses the compilation process into bytecode stored in .class files and the distribution of only bytecode to clients to hide implementation details. The role of Javadoc is described for generating documentation from source files, which serves as the client's reference to the class interface, enhancing the encapsulation by keeping member data private.

10:06

πŸ“— C# Access Modifiers and Structs in ADTs

This paragraph delves into C#'s access modifiers, including public, private, protected, internal, protected internal, and private protected, which relate to assemblies. It contrasts classes and structs in C#, explaining that structs are lightweight classes without inheritance support and can only exist on the stack, limiting their use in building ADTs like linked lists. The paragraph also touches on the use of properties in C# as a convenient mechanism for implementing accessor and mutator methods with the ability to include validation logic.

15:08

πŸ“’ C# Properties and ADT Example with Validation

The fourth paragraph provides an example of a Weather class in C# to illustrate the use of properties, including get and set accessors, which allow for direct access to member variables with additional processing such as validation. The Weather class includes a degreeDays property with a set accessor that validates the input before updating the member variable, demonstrating how properties can maintain the integrity of an object's state.

20:11

πŸ“• Ruby's Dynamic Nature and Encapsulation

This paragraph explores the dynamic aspects of Ruby, where classes can be modified at runtime, allowing for metaprogramming. It discusses the use of instance and class variables, the use of 'initialize' as the constructor, and the lack of public instance or class variables, making all data private. The paragraph also explains that while additional constructors can be defined, they are normal methods that call the default 'initialize' constructor. The dynamic nature of Ruby allows classes to have their interfaces changed during execution, affecting the programming language evaluation criteria.

25:12

πŸ“” Ruby's Stack Class Implementation and ADT Dynamics

The sixth paragraph presents a Ruby implementation of a Stack class, showcasing the use of instance variables and methods within the class. It explains the dynamic nature of Ruby's classes, which can have methods added or removed during runtime, enabling the modification of classes and objects while the program is running. This feature is illustrated with the Stack class, which includes an 'initialize' method and a 'push' method, demonstrating how instance variables are set and manipulated.

30:15

πŸ“’ Parameterized ADTs and Generic Classes

This paragraph introduces parameterized Abstract Data Types (ADTs), also known as generic classes, which allow for the creation of classes that work with a specific type specified at the time of instantiation. It explains that parameterized ADTs are necessary in statically typed languages but not in dynamically typed ones. The paragraph outlines the support for parameterized ADTs in various languages like C++ with template classes, Ada, and Java 5 with generic classes, highlighting their compile-time and runtime constructs.

35:16

πŸ“• C++ Template Classes for Parameterized ADTs

The seventh paragraph focuses on C++'s support for parameterized ADTs through template classes, which are similar to template functions but apply to the entire class. It describes how template classes use a generic type 't' for member variables and functions, and how specifying a concrete type for 't' at the time of instantiation generates a new version of the class with the type substituted in. An example of a Stack class implemented as a template class in C++ is provided to illustrate the concept.

40:17

πŸ“˜ Java Generic Classes and their Implementation

This paragraph discusses Java's implementation of generic classes, which, unlike C++, work with objects and not primitive types. It explains that Java's generic classes use a single class with automatic casting to ensure type safety at compile time, avoiding the need for multiple class versions as in C++. The paragraph provides an example of a generic Stack class in Java, demonstrating the use of generic parameters and the automatic casting performed by the compiler to maintain type integrity.

45:18

πŸ“™ C# Generic Classes and Encapsulation Constructs

The ninth paragraph briefly mentions C#'s support for generic classes, which are similar to Java's, and then shifts focus to encapsulation constructs needed for organizing large projects and supporting partial compilation. It explains the concept of grouping logically related sub-programs into a single unit that can be compiled separately, such as C and C++ header and implementation files, C# assemblies, and Java packages. The paragraph also touches on naming encapsulations to avoid name clashes in large projects.

50:20

πŸ“— Encapsulation Constructs and Naming in Programming Languages

The final paragraph concludes the discussion on chapter 11 by examining encapsulation constructs in more detail. It describes how large programs require organization and partial compilation support, leading to the use of encapsulation constructs like nested sub-programs, C/C++ header and implementation files, C# assemblies, and Java packages. The paragraph also explains naming encapsulations, such as C++ namespaces and Java packages, which group related classes and functions, allowing for logical separation and avoiding name clashes.

Mindmap

Keywords

πŸ’‘Abstract Data Types (ADTs)

Abstract Data Types, or ADTs, are high-level descriptions of data structures that define the types of operations that can be performed on them without specifying the details of how these operations are implemented. In the video, ADTs are a central theme, with the discussion focusing on how different programming languages implement ADTs. For example, the script mentions that Java, C#, and Ruby each have their own mechanisms for implementing ADTs, such as classes and access control modifiers.

πŸ’‘Encapsulation

Encapsulation is an object-oriented programming concept that involves bundling the data (attributes) and the methods (functions or operations) that manipulate the data into a single unit or class, and restricting access to some of the object's components. This concept is integral to the video's discussion, as it explores how languages like Java and C++ provide encapsulation through access modifiers and class structures.

πŸ’‘Java

Java is a programming language that is largely based on C++. The script discusses Java's implementation of ADTs, noting that all user-defined types in Java are classes and that Java uses garbage collection for automatic de-allocation of objects. It also mentions Java's access control modifiers, such as 'private' and 'public', and the concept of package scope, which is a unique feature of Java.

πŸ’‘C#

C#, pronounced 'C sharp', is a programming language that is based on both C++ and Java. The script explains that C# has similar access modifiers to C++ but adds additional modifiers like 'internal', 'protected internal', and 'private protected'. It also discusses how C# uses properties as a convenient mechanism for implementing getters and setters, which is a way to control access to class members.

πŸ’‘Ruby

Ruby is a dynamic, object-oriented programming language. The script highlights Ruby's use of classes for encapsulation, its dynamic nature that allows classes to be modified at runtime, and the use of instance variables beginning with an '@' symbol. Ruby's approach to ADTs and encapsulation is contrasted with other languages in the video.

πŸ’‘Access Control Modifiers

Access control modifiers are used in programming languages to specify the accessibility of class members, such as variables and methods. The video script explains how different languages like Java, C++, and C# implement access control modifiers like 'private', 'public', and 'protected' to control access to class members, which is crucial for encapsulation and ADT implementation.

πŸ’‘Garbage Collection

Garbage collection is a form of automatic memory management used by programming languages like Java and C#. The script mentions that in Java, object de-allocation happens automatically in the background through garbage collection, which means there are no explicit calls to trigger de-allocation of an object. This is a key aspect of how these languages manage memory and resources.

πŸ’‘Generic Classes

Generic classes, also known as parameterized ADTs, are classes that can work with a generic type specified at the time of instantiation. The video script discusses how languages like C++, Java, and C# support generic classes, allowing for the creation of classes that can handle different data types while maintaining type safety and reusability.

πŸ’‘Stack Class

The stack class is an example of an ADT used throughout the script to illustrate the implementation of ADTs in different programming languages. It typically has operations like 'push', 'pop', and 'top'. The script provides examples of how a stack class might be implemented in Java, C++, and Ruby, showcasing the language-specific features and syntax.

πŸ’‘Javadoc

Javadoc is a tool used in Java to generate documentation for Java source code. The script explains that Javadoc is executed on Java source files to create HTML files that document the classes. This documentation is provided to clients to hide the implementation details, which is a key aspect of encapsulation and the use of ADTs in Java.

πŸ’‘Namespaces

Namespaces are a naming encapsulation used in languages like C++ and C# to group logically related classes and functions, preventing name clashes in large projects. The script discusses how namespaces help organize code and allow for partial compilation of large projects by compiling units within the same namespace separately.

Highlights

The lecture concludes the discussion on abstract data types (ADTs) and encapsulation, focusing on their implementation in various programming languages.

Java's support for ADTs is similar to C++, with all user-defined types being classes and objects allocated from the heap with garbage collection.

Java uses access control modifiers for individual class entities, unlike C++ which uses clauses for groups of entities.

Java introduces package scope for entities without access modifiers, making them visible within the same package.

C# is based on C++ and Java, offering public, private, protected, internal, protected internal, and private protected access modifiers.

C# structs are lightweight classes without inheritance support and are limited to stack allocation.

C# properties offer a convenient mechanism for implementing getters and setters with additional processing capabilities.

Ruby's encapsulation is achieved through classes, with instance and class variables differentiated by the use of '@' and '@@' prefixes.

Ruby's dynamic classes allow for changes in the class structure at runtime, enabling metaprogramming.

Parameterized ADTs, or generic classes, are necessary in statically typed languages but not in dynamically typed ones.

C++ supports parameterized ADTs through template classes, a compile-time construct generating new class versions for each type.

Java's generic classes work with objects and use casts internally to ensure type safety at compile time.

C#'s generic classes are similar to Java's, allowing for the creation of parameterized collections and other data structures.

Encapsulation constructs help organize large projects and support partial compilation in programming languages.

C and C++ use header and implementation files for separation, allowing for separate compilation of units.

C# uses assemblies to group related classes and methods, which can be accessed as needed within an executable or DLL.

Java packages serve as naming encapsulations, allowing classes within the same package to share data and collaborate closely.

Transcripts

play00:00

welcome to the second and final part of

play00:04

our discussion on chapter 11 where we

play00:07

will finish off our discussion on

play00:09

abstract data types and encapsulation

play00:14

concepts these are the topics that we'll

play00:17

be discussing in today's lecture we will

play00:20

continue where we left off in the last

play00:22

lecture where we looked at c plus as an

play00:26

example programming language in which we

play00:29

could investigate how adts were

play00:32

implemented in this lecture we will

play00:34

continue this discussion by looking at

play00:37

java c-sharp and ruby

play00:41

we'll finish off our discussion with a

play00:43

look at how parameterized abstract data

play00:46

types work in different programming

play00:49

languages

play00:52

we'll start off by looking at how adts

play00:55

are implemented in java now the java

play00:58

programming language is largely based on

play01:02

c plus and as a result the support for

play01:05

adts in java is relatively similar to

play01:08

what is provided in c plus plus however

play01:11

there are a few exceptions so the first

play01:14

exception is that all user defined types

play01:18

in java are classes

play01:20

in c plus user defined types can be

play01:24

classes but there are additionally other

play01:26

user-defined types

play01:28

including for example structs

play01:31

and enumerations

play01:34

the second exception

play01:36

is that all objects in java are

play01:39

allocated from the heap and they are

play01:42

accessed through reference variables

play01:45

object de-allocation happens

play01:48

automatically in the background by means

play01:50

of garbage collection

play01:52

so we don't have any explicit calls

play01:55

that

play01:56

trigger a de-allocation of an object in

play02:00

java

play02:02

the third exception is that individual

play02:05

class entities have access control

play02:08

modifiers

play02:09

rather than the clauses for groups of

play02:12

entities that we saw in c plus so in c

play02:16

plus we could have for example a public

play02:18

label and everything under it would then

play02:20

be defined as public

play02:22

in java we have to explicitly specify

play02:25

for each of the members

play02:28

what the access control modifier would

play02:31

be in each particular case

play02:33

now java has two main access control

play02:37

modifiers

play02:38

namely private and public it doesn't

play02:41

have a protected modifier the way that c

play02:44

plus does

play02:48

the last exception that applies to java

play02:51

is that java also has what is referred

play02:53

to as package scope

play02:56

so package scope involves all entities

play03:00

that don't have access control modifiers

play03:02

in other words they neither have a

play03:05

public nor a private specified for their

play03:08

access control

play03:10

and in this case these entities will

play03:13

then be visible throughout the current

play03:16

package

play03:17

now a package in java is a collection of

play03:20

classes that are related to one another

play03:23

and they're essentially an

play03:24

organizational mechanism for grouping

play03:27

related classes that have the same kind

play03:30

of

play03:30

functionality together in a single group

play03:35

now you can think of package scope as

play03:37

being similar to friends in c

play03:40

however the concept of a friend in c

play03:43

plus is a much stricter concept because

play03:45

as i mentioned in the previous lecture

play03:47

friendship must be granted by a class in

play03:51

the case of java

play03:53

any particular class that exists within

play03:57

the same package as an adt class will

play04:01

have access to the package scope level

play04:06

entities

play04:07

within that adt class

play04:12

the next slide contains

play04:14

an example of an implementation for a

play04:17

stack class in java

play04:19

now this stack class has a fairly

play04:22

similar implementation to what we saw in

play04:24

our stack class example at the end of

play04:27

the previous lecture

play04:29

the stack class objects store exactly

play04:33

the same data as we saw in the c plus

play04:37

examples

play04:39

now in java we don't have a separation

play04:42

between a header file and an

play04:43

implementation file

play04:45

instead the full class definition is

play04:48

placed inside a single source file which

play04:51

is usually a dot java files in the case

play04:54

of our stack class example

play04:57

the entire stack class

play04:59

including all of the member variables

play05:03

and member methods

play05:05

would be included inside a file called

play05:08

stack.java

play05:11

now this source file includes full

play05:14

method implementations for all of the

play05:17

member methods within our adt class and

play05:21

also all of the member data so in other

play05:24

words everything related to the class is

play05:27

contained within this single source file

play05:32

now source files are compiled into

play05:34

bytecode and this byte code is usually

play05:36

contained within a dot class file so in

play05:40

the case of our example our stack class

play05:42

is contained within a stack.java file

play05:46

and when we compile the stack.java file

play05:48

then we get a stack.class

play05:51

file which contains the compiled byte

play05:54

code for our stack class

play05:57

now usually we provide only this byte

play06:00

code to clients so in other words the

play06:04

dot java source file is not provided to

play06:07

a client and this then hides the entire

play06:11

class from the client

play06:13

the class interface thing is provided

play06:16

for reference purposes

play06:19

to the client and this is typically

play06:22

generated by means of javadoc so javadoc

play06:26

is a tool which we execute on all of our

play06:29

source files in other words all of our

play06:31

java files and the javadoc tool will

play06:34

then generate html files which include

play06:38

documentation for the classes

play06:41

represented in the dot java files this

play06:45

documentation is then provided to the

play06:47

client so we can see if this procedure

play06:50

is followed then there is much better

play06:53

hiding of the implementation details

play06:56

from the client than what we saw in c

play06:59

plus and this is because all of the

play07:02

member data within our

play07:05

classes that represent adts

play07:08

will not be exposed to the client at all

play07:13

only the public interface is presented

play07:15

to the client by means of the

play07:17

documentation that has been generated

play07:22

here we have the implementation of our

play07:24

stack class in java

play07:26

we specify once again that we are

play07:28

defining a class and in this case the

play07:31

class is named stack

play07:33

again we use an uppercase s as the first

play07:37

letter of the class name and this is a

play07:39

general convention that we follow

play07:42

we again have opening and closing braces

play07:45

that delimit the class

play07:47

the next two lines contain definitions

play07:50

for the member variables for our stack

play07:54

class and these member variables have

play07:57

the same form as what we saw in our c

play08:00

plus example at the end of the last

play08:01

lecture so we have three member

play08:04

variables firstly stack ref which is an

play08:07

integer array then we have max lin and

play08:12

top sub and these are both integer

play08:15

values

play08:16

notice that we use the private special

play08:21

word to indicate that these member

play08:24

variables are private in nature and

play08:27

therefore not accessible

play08:29

by the clients of the stack class

play08:33

next we then have implementations for

play08:36

each of our member methods as well as

play08:39

the constructor in this case again we

play08:42

have only one constructor which is the

play08:44

default stack class constructor we know

play08:47

that this is a constructor because it

play08:49

has no return type and its name is stack

play08:52

which is the same name as the class and

play08:54

once again we have no parameters for

play08:57

this default constructor

play09:00

once again notice that we have to

play09:01

explicitly indicate that this

play09:03

constructor is public in nature

play09:07

we then initialize stack riff and here

play09:10

we set it up to be a new integer array

play09:13

with space for 100 integers we also set

play09:16

up max lin to have a value of 99 and top

play09:21

up to have a value of negative one

play09:24

now the remaining member methods that we

play09:27

have over here do not have the

play09:30

implementation shown but they would have

play09:32

a full implementation in each of them

play09:35

and once again note that each one

play09:38

individually must be indicated to be

play09:40

public meaning that it is accessible

play09:44

to

play09:45

all of the clients of the stack class

play09:50

the next programming language example

play09:52

that we'll look at is c sharp

play09:55

so as you should know by now

play09:57

c sharp is based on both c

play10:00

plus and java

play10:02

as such it has the same three axis

play10:06

modifiers as c plus has in other words

play10:09

public private and protected however it

play10:13

adds three additional access modifiers

play10:16

to this list we have internal protected

play10:20

internal and private protected

play10:23

now all three of these access modifiers

play10:26

relate to assemblies

play10:28

and assemblies in c sharp are

play10:31

collections of user-defined data types

play10:35

as well as resources that are grouped

play10:37

together and they are usually deployed

play10:39

to a client as a single unit they may

play10:43

take the form either of executables or

play10:47

dynamic link libraries or dlls

play10:51

now classes in c sharp have a default

play10:55

constructor that is predefined for all

play10:57

classes

play10:59

and all class instances are heap dynamic

play11:03

in nature in a similar fashion to what

play11:06

we saw in java

play11:09

c-sharp also uses garbage collections

play11:11

similar to java and this is used for

play11:15

most heap objects so there is auto

play11:19

de-allocation of dynamically allocated

play11:22

objects and as a result of this

play11:24

destructors while they are provided are

play11:27

fairly rarely used in practice

play11:33

now c sharp much like c plus also

play11:36

provides a struct

play11:38

now in c plus plus a struct and a class

play11:42

of virtually exactly the same thing it

play11:45

is for example legal to inherit from a

play11:49

struct

play11:51

the only real difference between a

play11:53

struct and a class in c plus is that a

play11:56

class's default axis modify if it's not

play12:00

explicitly changed by the programmer is

play12:02

private whereas the default axis

play12:05

modifier for a struct is public

play12:08

now c sharps structs are relatively

play12:11

different to c sharp classes

play12:15

so a strut in c sharp is a lightweight

play12:18

class and it doesn't support inheritance

play12:22

so in other words full object

play12:24

orientation is not supported by structs

play12:26

in c-sharp

play12:28

also c-sharp structs only exist on the

play12:32

stack they cannot be allocated on the

play12:35

heap dynamically at runtime

play12:39

now related to this because we can only

play12:42

allocate structs on the stack in c sharp

play12:46

we also cannot have structs that

play12:49

reference themselves

play12:51

so this limits the use of structs in the

play12:53

building of adts we for example can't

play12:56

define a linked list node that has a

play12:59

reference to another linked list node if

play13:02

the linked list node is defined as a

play13:04

struct it must be represented as a class

play13:08

if we are to have a reference to other

play13:11

linked list nodes within the linked list

play13:14

node class

play13:15

so what i would like you to do at this

play13:17

point is to pause the video and try to

play13:20

explain what the use of a struct would

play13:23

be in contrast to what the use of a

play13:26

class would be in c sharp

play13:34

most programming languages that support

play13:36

adts allow us to provide data member

play13:39

access by means of accessor methods

play13:43

which you may know as getter and seater

play13:46

methods so for example if we have a

play13:48

class called student then the student

play13:51

class might have a member variable

play13:53

called student number

play13:55

we could then provide retrieval access

play13:58

for the student number by implementing a

play14:01

set student number method which would

play14:03

simply return the student number for a

play14:06

particular instance of the student class

play14:10

in a similar fashion we can also allow

play14:12

the student number to be changed by

play14:15

implementing a set student number method

play14:18

and the set student number method would

play14:20

receive a new student number by means of

play14:23

a parameter and would then update the

play14:26

student number

play14:27

for the student object on which the set

play14:30

student number method is being called

play14:34

now of course this approach can also be

play14:36

used in c sharp however c sharp also

play14:38

provides a more convenient mechanism

play14:41

for us which is referred to as

play14:44

properties

play14:45

so properties provide a special way to

play14:47

implement gators and setters

play14:50

where we don't rely on explicit method

play14:53

calls

play14:54

now there are two kinds of properties

play14:56

provided by c sharp we have get and set

play15:00

properties

play15:02

and once we implement either a get

play15:04

property or a set property or both then

play15:07

it means that we can access a data

play15:11

member as though we have direct access

play15:14

to it so for instance if we have a

play15:15

student object called s

play15:18

we can then use s dot student number on

play15:21

it

play15:21

now if we assign to the student number

play15:24

then the set property would be the one

play15:27

to be called

play15:29

alternatively if we were just to print

play15:31

out a start student number then the get

play15:34

property would be the one that would be

play15:36

triggered now the important thing to

play15:38

understand is that these properties can

play15:41

implement code so we can for instance

play15:44

implement validation code to ensure

play15:47

that the state of the member variables

play15:50

is always intact and the member

play15:52

variables do not get set to invalid

play15:55

values we'll illustrate this by means of

play15:58

an example shortly

play16:02

on the next slide there is a simple

play16:05

example of an adt implemented in c-sharp

play16:09

most of the detail of this adt is left

play16:12

out because the primary intention is to

play16:15

illustrate how properties work in a

play16:18

c-sharp class

play16:20

so the c-sharp implementation is for a

play16:23

class called weather

play16:25

and

play16:26

within the weather class we have a

play16:28

member variable called degree days now

play16:31

there are two properties defined for the

play16:34

degree days member variable

play16:38

member variable access

play16:40

then occurs as though member variables

play16:43

are public however there's some

play16:45

additional processing that takes place

play16:48

so we have a get property for degree

play16:51

days and this is responsible for

play16:54

retrieving degree days

play16:56

and it can include code to filter the

play16:59

returned value before it is actually

play17:02

returned in the case of this example

play17:04

however there is no filtering we just

play17:06

simply return degree days

play17:09

then we also have a set property and

play17:12

this is responsible for setting the

play17:14

value of the degree days member variable

play17:18

and this can include code in order to

play17:22

validate the value that is being sent in

play17:26

via the

play17:28

set property before the actual member

play17:32

variables value is updated and changed

play17:36

now we can of course choose to implement

play17:38

only a get or reset property and in this

play17:41

case we would then limit the

play17:43

functionality that is available for the

play17:46

degree days member variable

play17:51

here we have the implementation for our

play17:54

weather class in c sharp we can see that

play17:57

we are defining a class named weather

play18:00

and this is a public class in c-sharp

play18:03

again we have braces that delimits the

play18:06

beginning and the end of the class and

play18:08

everything within those braces

play18:11

will be then a member of the weather

play18:14

class

play18:15

now down at the bottom over here we

play18:17

define a member variable called degree

play18:20

days this is a private member variable

play18:23

meaning that the client code does not

play18:25

have direct access to it and the type of

play18:28

this member variable is int

play18:31

now we want to provide some access to

play18:35

this degree days member variables so we

play18:37

do this by means of a property so here

play18:41

we are defining a property for degree

play18:44

days which is an integer value and this

play18:48

is a public property meaning that it is

play18:51

accessible to the client code

play18:55

within this property we then define a

play18:58

get property over here with the special

play19:00

word get and all that we do inside the

play19:03

get property is we return degree days

play19:07

now we could have added additional code

play19:09

in here in order to filter degree days

play19:12

in some way or change its value before

play19:14

returning it but in this example we

play19:17

don't do that we simply return degree

play19:20

days

play19:21

next we have our set property which is

play19:23

defined by means of the set special word

play19:26

and inside this property we then have

play19:30

some validation code

play19:32

so value over here refers to the value

play19:36

that is being used to set the degree

play19:40

days member variable

play19:42

and we over here then have an if

play19:44

statement and this if statement then

play19:47

checks to see whether the value is in a

play19:50

valid range if it isn't then we print

play19:53

out an error message but if the value is

play19:55

in the correct range then we simply set

play19:58

degree days up to

play20:01

that value that has been set so we're

play20:03

performing data validation in other

play20:06

words

play20:07

now down here we have an example of how

play20:10

these properties can be used so we are

play20:13

first of all creating an object called w

play20:16

which is of type weather and we create a

play20:19

new weather object which is allocated on

play20:23

the heap

play20:24

next we have two variables that we will

play20:26

use both of them integers degree days

play20:29

today and old degree days

play20:32

so now over here

play20:34

we are assigning to the variable old

play20:36

degree days

play20:38

w dot degree days and this will then

play20:42

trigger the get property because we are

play20:45

retrieving degree days from w so in that

play20:49

case we will then be executing the get

play20:52

property

play20:54

on the final line over here we are

play20:57

updating degree days so we are assigning

play21:00

to w dot degree days the value of the

play21:04

variable degree days today which we

play21:07

would have set somehow possibly based on

play21:10

user input

play21:12

so in this case the set property will

play21:14

then be the one that will be triggered

play21:17

and that is over here as we saw a moment

play21:21

ago

play21:22

and this will then validate degree days

play21:25

today and ensure that it is in the

play21:28

correct range if it isn't in the correct

play21:30

range an error message will be printed

play21:32

out otherwise the degree days member

play21:35

variable will be updated to degree days

play21:38

today

play21:41

the last programming language example

play21:44

that we'll look at in this chapter is

play21:47

ruby

play21:48

now in ruby the encapsulation construct

play21:52

is the class much as we saw in the cases

play21:55

of c plus

play21:57

java and c sharp

play21:59

now of course ruby has variables and

play22:02

local variables that exist within

play22:05

methods simply have normal names exactly

play22:08

the way as they would in c

play22:11

java or c sharp

play22:14

however instance variable names begin

play22:16

with a single at symbol whereas class

play22:19

variable names begin with two at symbols

play22:23

now instance variables and class

play22:26

variables are not explicitly declared as

play22:29

they would be in c plus java or c sharp

play22:33

instead when they are used then they are

play22:36

implicitly declared for the class in

play22:39

which they appear

play22:42

instance methods in ruby use function

play22:45

syntax

play22:46

and there are only instance methods in

play22:50

ruby not standalone methods or functions

play22:53

and this is because everything in ruby

play22:56

is a class

play22:58

or an instance of a class that you are

play23:01

working with

play23:03

now constructors in ruby are named

play23:06

initialize and there's only one

play23:08

initialized constructor per class

play23:12

and this initialized constructor is

play23:14

implicitly called whenever new is called

play23:17

and this happens when an instance of a

play23:21

class is created in other words an

play23:24

object is generated

play23:26

now it is possible for a programmer to

play23:28

define additional constructors however

play23:31

these additional constructors are just

play23:34

normal methods with with names that have

play23:36

been chosen by the programmer

play23:39

these methods within their definition

play23:42

would then call new which would then

play23:44

result in the default initialize

play23:47

constructor being called

play23:49

then the

play23:51

new constructor which has been defined

play23:53

can perform additional tasks such as for

play23:56

example setting up instance variables

play24:00

with specific values

play24:05

now it is impossible to have a public

play24:08

instance or class variable in ruby so

play24:12

essentially all data related to a class

play24:15

is private within that class

play24:17

however class methods have access

play24:20

control modifiers associated with them

play24:23

in a fairly similar fashion to what we

play24:25

saw in c plus java and c sharp

play24:29

previously

play24:31

so class methods in ruby can be marked

play24:34

as either private or public

play24:36

and if they aren't marked using either

play24:39

private or public then the default is

play24:42

public access

play24:44

now one of the most interesting features

play24:47

associated with adt support in ruby is

play24:50

that classes are dynamic in other words

play24:54

the structure of the class can change

play24:56

through the course of runtime

play24:59

now this is achieved by adding methods

play25:01

to classes or removing methods from

play25:04

classes and what this then means is that

play25:08

the interface of a class can change

play25:11

during the course of execution

play25:14

so this allows for what is referred to

play25:17

as meter programming which is where

play25:20

classes and objects are modified on the

play25:22

fly while the program is still running

play25:26

so what i would like you to do at this

play25:28

point is to pause the video and try to

play25:31

explain

play25:32

what these dynamic interfaces in ruby

play25:37

affect in terms of the programming

play25:39

language evaluation criteria that we've

play25:42

been looking at so far in this course

play25:46

additionally

play25:47

also try to identify what kinds of

play25:51

situations meter programming would be

play25:53

useful for in a practical

play25:57

situation

play25:57

[Music]

play26:02

all right so on the next slide there is

play26:04

a program code example in ruby and this

play26:08

is an implementation of the same stack

play26:12

class that we used when demonstrating

play26:15

adts in c plus and java previously

play26:22

over here we have an implementation of

play26:24

our stack class in ruby the stack class

play26:28

begins up here where we specify the name

play26:31

of the class as stack class and the

play26:34

class ends at the bottom here with the

play26:36

special word end

play26:39

we have a single constructor which is

play26:42

called initialize as you can see up here

play26:45

and the sets values for the three

play26:48

instance variables namely stackriff

play26:51

maxlin and top sub

play26:54

so these variables get initial values

play26:57

notice that all three of them start with

play27:00

a single

play27:02

at symbol

play27:03

and this indicates that they are

play27:06

instance variables

play27:09

and notice also that stack ref maxlin

play27:13

and top sub are not separately defined

play27:15

for our class instead they are

play27:18

implicitly specified within our

play27:21

constructor

play27:22

and this then means that they are

play27:25

defined as instance variables for stack

play27:28

class

play27:30

here we have a

play27:32

member method that is defined for our

play27:36

stack class

play27:37

and we can see that it hasn't been

play27:39

specified as private so that means that

play27:41

it is public it's called push and it

play27:44

receives as a single parameter a number

play27:48

we then have an if else statement and

play27:51

this performs a check

play27:53

to see whether top sub is the same as

play27:58

maxlin

play27:59

notice that both of these are again

play28:01

specified with a single at symbol

play28:04

which once again means that we are

play28:06

referring to our instance variables

play28:10

within our class

play28:11

so if top sub is the same as maxlin it

play28:14

means that we have filled up our array

play28:17

and there's no more space to insert

play28:20

any values into so in that case we then

play28:23

print out an error message to the screen

play28:26

otherwise we have at least one space

play28:28

available so we entered in the else

play28:30

portion

play28:31

and we can see that we then

play28:34

increase top subs value by 1 and then we

play28:38

insert into our stack ref array at

play28:42

subscript top sub and we insert the

play28:45

value number at that position

play28:49

additionally we also then have other

play28:51

member methods that are defined and so

play28:55

we have pop top and empty defined but we

play28:59

won't show the implementations here if

play29:01

you're interested in those

play29:02

implementations you're welcome to refer

play29:05

to the textbook where a more complete

play29:07

rundown of the class is provided

play29:12

the next topic that we'll look at is

play29:14

parameterized abstract data types

play29:18

now parameterized adts are similar in

play29:21

nature to the parameterized sub-programs

play29:24

that we spoke about in the previous

play29:26

chapter

play29:27

there we looked at two examples template

play29:30

functions in c plus and generic methods

play29:34

in java and what we saw is that both of

play29:37

these constructs allowed us to create

play29:40

sub-programs for a specific type

play29:43

and then these sub-programs would work

play29:46

with that type either receiving

play29:49

parameters of that type or returning

play29:52

that type or possibly both and this

play29:55

would depend on how these sub programs

play29:58

were used and what types they were used

play30:01

with

play30:02

so parameterized adts achieve the same

play30:05

thing for an abstract data type in other

play30:08

words they will allow us to create a

play30:11

class that has a particular generic type

play30:14

specified for it

play30:16

usually what would then happen is this

play30:18

class would store this generic type and

play30:21

also the member functions or methods for

play30:25

the class

play30:26

would

play30:27

then ensure that they receive and or

play30:31

return

play30:33

values of that particular generic type

play30:36

we would also have to specify this type

play30:39

when we create

play30:40

instances

play30:42

of this generic adt

play30:45

so parametrized adts are very often

play30:48

referred to as generic classes

play30:50

and formally speaking they are adt's

play30:53

that can store elements of a particular

play30:56

type where this type is specified when

play30:59

an instance of the abstract data type is

play31:02

created now parameterized adts are only

play31:07

necessary in statically typed languages

play31:10

and they don't need to be provided by

play31:13

dynamically typed languages so what i

play31:16

would like you to do at this point is to

play31:18

pause the video and try to explain why

play31:20

dynamically typed languages don't

play31:23

require support for parameterized

play31:26

abstract data types

play31:32

now parameterized abstract data types

play31:34

are supported in a variety of different

play31:36

programming languages

play31:38

in c plus we have template classes ada

play31:42

also supports parameterized abstract

play31:44

data types and in java 5 we have generic

play31:49

classes

play31:51

c sharp

play31:53

2005 also supports generic classes that

play31:56

are relatively similar to java's generic

play31:59

classes

play32:02

so as i just mentioned c plus supports

play32:06

parameterized adts by means of what are

play32:09

called template classes

play32:11

the concept of a template class is

play32:14

fairly similar to that of a template

play32:17

function which we covered in chapter 9

play32:20

however the concept holds for the entire

play32:24

class that represents the adt

play32:27

so the entire class has a generic

play32:29

parameter specified and very often we

play32:32

use the convention of an uppercase t

play32:35

for that type we can then use the type t

play32:39

within the abstract data type so for

play32:42

example if we have a member variable

play32:45

called data we could specify that data's

play32:48

type is t

play32:49

we can also use that t type throughout

play32:53

all of the various member functions

play32:56

within the adt so we can have for

play32:59

example getters which would return type

play33:03

t and we can have setters that would

play33:05

receive type t parameters

play33:09

so the concept then of a parameterized

play33:12

adt in c

play33:13

plus is a compile time construct in

play33:16

exactly the same way as we saw with

play33:19

template functions

play33:21

so when an object of the class is

play33:23

instantiated then we need to specify a

play33:27

type for the generic parameter so over

play33:29

here we have an example of this here we

play33:32

are assuming that we have a stack class

play33:35

and that this is a template class and

play33:38

there is some type t that is specified

play33:41

then for this stack so we will assume

play33:44

that the stack then stores

play33:47

a data member

play33:49

variable which is then of type t so we

play33:53

can now create a variable called my int

play33:56

stack over here and we specify that its

play33:59

type is stack however we also need to

play34:02

then specify

play34:03

the type for which this stack is to be

play34:06

instantiated so here we are specifying

play34:10

that generic type t

play34:12

must concretely for my in stack be an

play34:16

integer and we specify this within

play34:18

angled brackets

play34:20

so what happens then is at compile time

play34:23

the compiler will then generate an

play34:26

entirely new version of the stack class

play34:30

and

play34:31

this version then has all of the

play34:33

instances of its generic parameter t

play34:37

replaced with the specified type which

play34:39

is int in this case so in other words

play34:43

the data member variable would then have

play34:46

its type specified as int

play34:49

we can then create a separate stack

play34:52

variable and for that variable we may

play34:54

specify that the type is float

play34:58

and then a second

play35:00

instance of the stack class would be

play35:03

generated at compile time for us but in

play35:07

this class all of the occurrences of t

play35:10

would then be replaced with floats so

play35:13

essentially a template class is then a

play35:16

shorthand method of specifying multiple

play35:20

classes that each deal with a specific

play35:22

type but we only need to then specify

play35:26

one template class in order to achieve

play35:29

this

play35:32

over here we have an implementation of

play35:35

the stack class as a template class in c

play35:39

plus

play35:40

so you can see that again we start off

play35:44

here defining our class named stack with

play35:47

an uppercase s

play35:49

however we additionally have been in the

play35:52

line just before the first line of the

play35:55

class definition

play35:57

a line specifying that this is a

play36:00

template class

play36:01

and that the type for our template class

play36:06

is t

play36:07

so t then is our generic type and we can

play36:11

use t then within our class definition

play36:15

so here we have the private portion of

play36:18

our definition and this contains all of

play36:21

the member variables we again have

play36:23

stackriff maxlin and top sub as we did

play36:27

in our previous examples what's

play36:29

important to note here however is the

play36:32

type of our stack ref member variable so

play36:36

we can see once again that it's a

play36:38

pointer indicated by means of this

play36:40

asterisk however we can see that the

play36:42

type then is specified as t

play36:46

so whatever type we use with our stack

play36:49

that will then be the type that will be

play36:51

stored inside the stack ref array

play36:56

so here we then have the public portion

play36:59

of our class definition

play37:01

and again we've omitted most of it i've

play37:04

just included one of the constructors as

play37:07

well as the top member function in order

play37:10

to illustrate how this generic type can

play37:13

be used

play37:14

so here is our default constructor this

play37:17

is our stack constructor which receives

play37:20

no parameters and you can see that we

play37:23

define initial values for all of the

play37:26

member variables

play37:27

so we set maxline to 99 and tops up to

play37:31

negative one and as we've seen in

play37:34

previous examples however what's

play37:36

important to note is that the stack ref

play37:39

member variable which is an array now

play37:41

needs to be dynamically allocated on the

play37:44

heap so we use the new special word over

play37:48

here and its size is 100 so it allows

play37:52

for 100 values to be stored but most

play37:55

importantly its type is t

play37:58

which means that the values that this

play38:01

array stores are then values of type t

play38:05

whether that type be integers floats

play38:08

booleans or some other potentially more

play38:12

complex class

play38:14

and then

play38:16

secondly we have a member function

play38:19

called top over here so this just simply

play38:22

retrieves the value at the top of our

play38:24

stack

play38:25

and notice that the name of this member

play38:27

function is top but very importantly its

play38:30

return type is t so in other words

play38:33

whatever type has been stored in the

play38:36

stack ref array this will be the type

play38:39

that the top member function will return

play38:43

so inside this function we simply

play38:46

perform a test on our top subscript and

play38:50

test to see whether it's negative one if

play38:53

it is negative one then it means no

play38:55

values have been stored in the stack yet

play38:57

so we simply print out an error message

play38:59

to the screen

play39:00

otherwise we then have at least one

play39:03

value that is stored within our stacks

play39:06

so we then enter the else portion of our

play39:09

if statement over here

play39:11

where we perform a return and this

play39:14

return is then

play39:16

our

play39:17

stack array

play39:19

stack riff but at subscript top sub

play39:24

so this will then retrieve the value

play39:26

from this array which is of type t

play39:28

and this will be what will be returned

play39:33

we then of course have additional member

play39:35

functions which will be defined for this

play39:38

class

play39:39

when we use the stack class then we use

play39:42

the syntax that we saw on the previous

play39:44

slide so we need to specify which

play39:46

specific type we want to use for it and

play39:49

the important thing is then that this is

play39:52

a compile time construct so whatever

play39:55

type we specify we will then generate a

play39:58

new version of the stack class and the

play40:01

type that we've specified will replace

play40:03

all of the instances of t

play40:06

within our class definition so for

play40:09

example if we specify that we want to

play40:12

create an object of type uh stack

play40:16

and we specify that the generic type

play40:20

associated with it is int then we will

play40:23

place int where t occurs over here

play40:26

meaning that we're working with an array

play40:28

of into values int will also appear here

play40:32

in our constructor which means that we

play40:34

are allocating space for an integer

play40:37

array and the return type of top would

play40:40

be then

play40:42

as well in that case the important thing

play40:46

to understand is that we don't have to

play40:49

physically ourselves as programmers

play40:51

write that implementation of the class

play40:54

it's generated automatically for us by

play40:57

the compiler

play41:01

java also supports parameterized classes

play41:04

in the form of generic classes

play41:07

so in a similar fashion to c plus plus

play41:10

generic classes are similar to generic

play41:13

methods however they apply to an entire

play41:17

class

play41:18

now we saw in chapter 9 that the

play41:21

difference between java's generic

play41:23

methods and c plus pluses template

play41:26

functions

play41:27

was that template functions are a

play41:29

compile-time construct while generic

play41:32

methods in java are a runtime construct

play41:36

and only one version of the generic

play41:38

method exists as opposed to in c plus

play41:42

where multiple versions are generated at

play41:44

compile time as needed

play41:47

so in the same way generic classes in

play41:50

java have only one version of the

play41:52

generic class and the methods within it

play41:57

so usually generic classes are used for

play42:00

generic collections and there are a

play42:03

number of built-in generic collections

play42:05

that java provides for us such as the

play42:09

linked list class and the arraylist

play42:12

class

play42:17

now in java generic parameters must be

play42:20

classes and generic parameters are not

play42:23

allowed to be primitive types so this is

play42:26

unlike c plus where we saw in our

play42:29

previous example of a template stack

play42:32

class in c plus that we could create a

play42:36

stack object of type int

play42:39

that kind of thing isn't possible in

play42:41

java because int is a primitive type it

play42:44

isn't a class

play42:47

so a generic class then only uses

play42:50

objects of the generic parameter type

play42:54

now we saw in the previous chapter that

play42:57

when we were talking about generic

play42:59

methods

play43:00

only one instance of the generic method

play43:03

exists and objects are used for the

play43:06

generic types

play43:08

and then costs are inserted in order to

play43:12

ensure that type errors are picked up at

play43:16

compile time so very much the same kind

play43:19

of thing happens with generic classes in

play43:21

java behind the scenes our generic type

play43:25

is actually dealt within as an object

play43:29

and we work with object instances within

play43:33

our class and those are dealt with in

play43:35

that way internally

play43:38

however the compiler then inserts costs

play43:42

automatically and this is for all method

play43:45

parameters and returns that use the

play43:48

generic type

play43:50

so what this means then is that type

play43:52

errors are caught at compile time not at

play43:55

runtime the most important thing to

play43:58

understand is that this is not the same

play44:02

as in c plus where c plus plus generates

play44:06

a new version of the entire template

play44:09

class each time that it is used with a

play44:12

different type in the case of java

play44:15

our generic class is a single class that

play44:18

exists multiple versions are not

play44:20

generated and we work with objects

play44:23

internally with costs that are inserted

play44:26

in order to ensure that type areas are

play44:29

picked up early at compile time and not

play44:33

at run time

play44:37

here we have an implementation in java

play44:40

of a stack class that is a generic class

play44:44

so we can see up here our class is

play44:48

introduced it's a public class and we're

play44:50

calling this class my stack and then

play44:53

specifying in square brackets that it is

play44:57

a generic class

play45:00

that works with a type specified as t

play45:05

so here we then have the member

play45:07

variables for our my stack class in this

play45:10

case we are going to use stack riff

play45:14

which is an arraylist now an arraylist

play45:18

is a generic class itself

play45:21

so we specify then for that type and in

play45:24

this case the type then is t

play45:27

which is the type that we have received

play45:30

for use with our my stack class

play45:34

we also have an integer variable called

play45:37

maxlin that stores the maximum length

play45:41

for our stack

play45:43

so both of these then are private member

play45:45

variables we then have a public default

play45:49

constructor which you can see over here

play45:51

it's called my stack which is the name

play45:54

of its class it doesn't have any return

play45:57

type or any parameters meaning that it

play46:00

is a default constructor

play46:02

so we then set an initial value for

play46:05

stackriff and here we just create a new

play46:08

arraylist and again we use the generic

play46:12

type t for our arraylist to specify that

play46:17

we are storing whichever type has been

play46:20

seen through in the construction of the

play46:23

my stack object that we are creating we

play46:27

also set maxlin to 99.

play46:31

here we then have an implementation of

play46:34

the push method which is also a member

play46:37

of the mystack class we're leaving out

play46:40

other methods that would naturally need

play46:43

to be defined for the my stack class

play46:46

but those are available in the textbook

play46:49

so here we have then our push method

play46:51

that has been defined it's again a

play46:54

public method and it returns nothing

play46:57

however it receives a single parameter

play46:59

called new value and very importantly

play47:02

the type of this parameter is t

play47:05

so what this means is we are receiving

play47:08

then our generic type that has been

play47:10

specified for the my stack object that

play47:13

we are attempting to push to

play47:16

so here we then have an if else

play47:18

statement that performs a validity check

play47:20

so we check the size

play47:22

of our stack ref arraylist and we

play47:26

compare this

play47:27

to maxlin if the two are equal then it

play47:30

means that our stack is full in which

play47:33

case we print out an error message to

play47:36

the screen but otherwise we can receive

play47:39

the values so we then just simply add to

play47:42

our stack ref array list

play47:45

the new value that has been passed

play47:47

through as the parameter to our push

play47:51

method

play47:53

so down here we have an example of how

play47:56

we could create

play47:57

an object of class my stack

play48:00

our variable is my stack starting with

play48:03

the lowercase n so this is the name of

play48:06

our variable and our type is then

play48:09

mystack but we have to be careful to

play48:11

also additionally specify the type that

play48:15

we want to work with so here we are

play48:18

specifying that my stack should store

play48:21

string objects

play48:23

we then use a new to create an instance

play48:26

of the stack dynamically

play48:29

here we are using the my stack

play48:31

constructor it's the default constructor

play48:33

because no parameter is specified and

play48:36

again we have to specify the type that

play48:39

we want to store within our my stack

play48:43

object which in this case is string

play48:46

so what's important to understand then

play48:48

is that there is only one instance of

play48:52

the mystac class we don't have multiple

play48:55

versions of it created at compile time

play48:58

as in c plus

play49:00

however

play49:01

when we are working with our generic

play49:04

type t

play49:06

what we are actually working with will

play49:08

be objects so in other words the stack

play49:11

riff

play49:13

member which is an arraylist will store

play49:16

objects in a similar fashion our

play49:18

constructor will create an arraylist

play49:21

that stores objects

play49:23

and in a similar fashion we will also

play49:26

then have our parameter for our push

play49:29

method which is new value will then be

play49:33

of type object so what this means then

play49:36

is that any kind of object can be

play49:39

received however the compiler will

play49:41

automatically then insert a cost in

play49:45

order to ensure that a new value is of

play49:47

the correct type

play49:49

so for our example use over here

play49:53

our my stack variable

play49:55

is then specified to be a my mystac

play49:57

object of type string we would then

play50:00

automatically have a cost of this object

play50:03

that has been passed through as the

play50:05

parameter to string and that will then

play50:08

generate an error if we are attempting

play50:11

to push a value of any other type other

play50:15

than string

play50:19

parameterized classes in c-sharp 2005

play50:23

aren't very interesting because they're

play50:25

quite similar to the generic classes

play50:27

provided by java 5.

play50:30

java 5 does support wild card classes

play50:34

these are quite similar to the wild card

play50:36

classes that are allowed for generic

play50:40

methods which we discussed in the

play50:42

previous chapter

play50:44

also

play50:45

in

play50:46

generic classes in c sharp

play50:49

elements of collection classes

play50:52

specifically that are provided by the

play50:54

c-sharp language itself can be accessed

play50:57

through indexing

play50:59

in other words one does not have to use

play51:02

a member method in order to access data

play51:05

within these constructs

play51:07

so parameterized classes in c-sharp can

play51:10

be written by the programmer themselves

play51:12

but they're also predefined for a number

play51:14

of different collections

play51:16

including the array class the list class

play51:19

the stack class the queue class and the

play51:23

dictionary class

play51:27

next we'll look at encapsulation

play51:30

constructs relatively briefly we've

play51:32

already touched on some of the concepts

play51:35

that we'll discuss here

play51:37

previously in our discussion

play51:41

so if we have very large projects and

play51:45

large programs that consist of a large

play51:47

number of classes and potentially

play51:50

functions

play51:52

then there are two special needs that

play51:54

come into play so firstly we need some

play51:57

means of organizing these very large

play52:00

projects other than simply dividing them

play52:03

into sub programs and this is just due

play52:06

to the fact that these projects become

play52:08

incredibly complicated

play52:10

we also need some means of supporting

play52:13

partial compilation

play52:15

and this is a support for compiling

play52:19

smaller units of a larger program

play52:21

separately rather than compiling the

play52:24

entire program so we only compile the

play52:27

portion of the larger project that needs

play52:29

to be compiled after a change has been

play52:32

performed

play52:34

so the obvious solution then to this is

play52:36

to group logically related sub-programs

play52:39

together in a single unit

play52:42

and then we allow these units to be

play52:44

compiled separately

play52:46

so groupings like these are then called

play52:49

encapsulations

play52:53

so here are some examples of

play52:55

encapsulation constructs that are

play52:57

provided by some programming languages

play53:01

firstly nested sub-programs can be

play53:03

considered a kind of encapsulation

play53:06

construct because we are grouping

play53:08

together sub-programs that are related

play53:12

within the body of a containing sub

play53:15

program

play53:16

so nested sub programs are supported in

play53:19

python javascript and ruby

play53:22

the next approach to supporting

play53:25

encapsulation constructs is for c and c

play53:28

plus plus

play53:30

and as we saw previously we have a

play53:33

separation between a header file and an

play53:37

implementation file

play53:39

so what this thing means is that each of

play53:41

the implementation files can be compiled

play53:44

separately

play53:46

and whatever functions or classes

play53:49

or other structures that are defined

play53:52

within that implementation file will

play53:54

then be compiled together as a single

play53:57

unit

play53:58

a header file then provides a mechanism

play54:01

for us to specify an interface which is

play54:04

visible to the client who is using the

play54:09

implementation

play54:10

and that will then specify for them the

play54:13

prototypes of the various functions that

play54:16

they are allowed to use

play54:19

in c-sharp we have the concept of

play54:21

assemblies and assemblies are basically

play54:25

groups of related classes and methods

play54:28

and they are grouped together within an

play54:31

executable or a dynamic link library or

play54:35

dll file

play54:37

so essentially then these related

play54:40

classes and methods

play54:42

can then be

play54:44

accessed as they need to be accessed as

play54:47

long as the executable or the dll is

play54:51

properly included in the project

play54:56

the last concept that we'll look at is

play54:59

that of naming encapsulations which are

play55:02

relatively similar to encapsulation

play55:05

constructs however they are used for a

play55:08

different purpose

play55:10

so in very large programs we would

play55:13

generally define a lot of global names

play55:17

and because eventually there are so many

play55:19

names in a very large project

play55:22

name clashes can then quite easily occur

play55:25

and become quite commonplace

play55:27

so somebody may encounter a name clash

play55:30

when they are working on a completely

play55:32

different part of the project code and

play55:35

this of course then can become very

play55:37

difficult to maintain

play55:39

so programming languages that are

play55:41

intended for the development of very

play55:43

large projects need a way to divide all

play55:46

of these names into logical groupings

play55:50

and this is where the concept of a

play55:52

naming encapsulation comes in

play55:55

so a naming encapsulation then simply

play55:58

creates a new scope

play56:00

for a set of names

play56:04

so c plus and c sharp have name spaces

play56:08

which are naming encapsulations

play56:11

and each library then will be placed

play56:14

within its own namespace

play56:18

so this is then a larger overall

play56:22

grouping than the standard encapsulation

play56:25

constructs that we see in these

play56:27

programming languages they may include a

play56:30

number of separate classes together

play56:33

as well as standalone functions and

play56:37

these can all be then grouped together

play56:39

within a namespace generally speaking

play56:42

whatever is in a namespace would then be

play56:44

related and to everything else in the

play56:47

namespace at least conceptually

play56:51

so generally speaking we can then use

play56:54

things that are defined within a

play56:55

namespace outside of the namespace

play56:58

and what we would have to do then in

play57:00

these languages is to qualify names

play57:04

within the namespace

play57:05

using the name of the namespace so we

play57:08

basically specify the namespace first

play57:11

and then the name of the thing inside

play57:13

the namespace that we are trying to

play57:16

access

play57:19

java also has support for naming

play57:22

encapsulations and it achieves this

play57:25

through java packages

play57:27

so a java package can contain more than

play57:30

one class definition typically these

play57:32

class definitions are all related to one

play57:35

another

play57:36

and classes within a package are

play57:38

considered to be partial friends so what

play57:41

this means is that anything that is

play57:44

defined as having package scope within a

play57:48

class that is in a package will then be

play57:51

visible to every other class contained

play57:54

within that package this essentially

play57:56

allows these classes to collaborate more

play57:59

closely with one another

play58:01

because they can share data amongst

play58:04

themselves

play58:06

now clients who use packages have two

play58:09

options they can either every time that

play58:12

they use a clasp in a package they can

play58:14

use a fully qualified name including the

play58:18

name of the package

play58:19

or alternatively they can use an import

play58:22

statement in order to declare that

play58:25

everything within a package is imported

play58:29

and available to the code that is being

play58:31

written

play58:33

all right so that concludes our

play58:34

discussion on chapter 11 of the textbook

play58:38

in the next lecture we'll be moving on

play58:40

to the last chapter we'll be looking at

play58:43

namely chapter 12 which deals with

play58:46

object oriented programming

Rate This
β˜…
β˜…
β˜…
β˜…
β˜…

5.0 / 5 (0 votes)

Related Tags
Abstract Data TypesEncapsulationJavaC++C#RubyGenericsOOP ConceptsProgramming LectureStack ClassAccess Modifiers