COS 333: Chapter 11, Part 2
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
📘 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.
📙 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.
📗 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.
📒 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.
📕 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.
📔 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.
📒 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.
📕 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.
📘 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.
📙 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.
📗 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)
💡Encapsulation
💡Java
💡C#
💡Ruby
💡Access Control Modifiers
💡Garbage Collection
💡Generic Classes
💡Stack Class
💡Javadoc
💡Namespaces
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
welcome to the second and final part of
our discussion on chapter 11 where we
will finish off our discussion on
abstract data types and encapsulation
concepts these are the topics that we'll
be discussing in today's lecture we will
continue where we left off in the last
lecture where we looked at c plus as an
example programming language in which we
could investigate how adts were
implemented in this lecture we will
continue this discussion by looking at
java c-sharp and ruby
we'll finish off our discussion with a
look at how parameterized abstract data
types work in different programming
languages
we'll start off by looking at how adts
are implemented in java now the java
programming language is largely based on
c plus and as a result the support for
adts in java is relatively similar to
what is provided in c plus plus however
there are a few exceptions so the first
exception is that all user defined types
in java are classes
in c plus user defined types can be
classes but there are additionally other
user-defined types
including for example structs
and enumerations
the second exception
is that all objects in java are
allocated from the heap and they are
accessed through reference variables
object de-allocation happens
automatically in the background by means
of garbage collection
so we don't have any explicit calls
that
trigger a de-allocation of an object in
java
the third exception is that individual
class entities have access control
modifiers
rather than the clauses for groups of
entities that we saw in c plus so in c
plus we could have for example a public
label and everything under it would then
be defined as public
in java we have to explicitly specify
for each of the members
what the access control modifier would
be in each particular case
now java has two main access control
modifiers
namely private and public it doesn't
have a protected modifier the way that c
plus does
the last exception that applies to java
is that java also has what is referred
to as package scope
so package scope involves all entities
that don't have access control modifiers
in other words they neither have a
public nor a private specified for their
access control
and in this case these entities will
then be visible throughout the current
package
now a package in java is a collection of
classes that are related to one another
and they're essentially an
organizational mechanism for grouping
related classes that have the same kind
of
functionality together in a single group
now you can think of package scope as
being similar to friends in c
however the concept of a friend in c
plus is a much stricter concept because
as i mentioned in the previous lecture
friendship must be granted by a class in
the case of java
any particular class that exists within
the same package as an adt class will
have access to the package scope level
entities
within that adt class
the next slide contains
an example of an implementation for a
stack class in java
now this stack class has a fairly
similar implementation to what we saw in
our stack class example at the end of
the previous lecture
the stack class objects store exactly
the same data as we saw in the c plus
examples
now in java we don't have a separation
between a header file and an
implementation file
instead the full class definition is
placed inside a single source file which
is usually a dot java files in the case
of our stack class example
the entire stack class
including all of the member variables
and member methods
would be included inside a file called
stack.java
now this source file includes full
method implementations for all of the
member methods within our adt class and
also all of the member data so in other
words everything related to the class is
contained within this single source file
now source files are compiled into
bytecode and this byte code is usually
contained within a dot class file so in
the case of our example our stack class
is contained within a stack.java file
and when we compile the stack.java file
then we get a stack.class
file which contains the compiled byte
code for our stack class
now usually we provide only this byte
code to clients so in other words the
dot java source file is not provided to
a client and this then hides the entire
class from the client
the class interface thing is provided
for reference purposes
to the client and this is typically
generated by means of javadoc so javadoc
is a tool which we execute on all of our
source files in other words all of our
java files and the javadoc tool will
then generate html files which include
documentation for the classes
represented in the dot java files this
documentation is then provided to the
client so we can see if this procedure
is followed then there is much better
hiding of the implementation details
from the client than what we saw in c
plus and this is because all of the
member data within our
classes that represent adts
will not be exposed to the client at all
only the public interface is presented
to the client by means of the
documentation that has been generated
here we have the implementation of our
stack class in java
we specify once again that we are
defining a class and in this case the
class is named stack
again we use an uppercase s as the first
letter of the class name and this is a
general convention that we follow
we again have opening and closing braces
that delimit the class
the next two lines contain definitions
for the member variables for our stack
class and these member variables have
the same form as what we saw in our c
plus example at the end of the last
lecture so we have three member
variables firstly stack ref which is an
integer array then we have max lin and
top sub and these are both integer
values
notice that we use the private special
word to indicate that these member
variables are private in nature and
therefore not accessible
by the clients of the stack class
next we then have implementations for
each of our member methods as well as
the constructor in this case again we
have only one constructor which is the
default stack class constructor we know
that this is a constructor because it
has no return type and its name is stack
which is the same name as the class and
once again we have no parameters for
this default constructor
once again notice that we have to
explicitly indicate that this
constructor is public in nature
we then initialize stack riff and here
we set it up to be a new integer array
with space for 100 integers we also set
up max lin to have a value of 99 and top
up to have a value of negative one
now the remaining member methods that we
have over here do not have the
implementation shown but they would have
a full implementation in each of them
and once again note that each one
individually must be indicated to be
public meaning that it is accessible
to
all of the clients of the stack class
the next programming language example
that we'll look at is c sharp
so as you should know by now
c sharp is based on both c
plus and java
as such it has the same three axis
modifiers as c plus has in other words
public private and protected however it
adds three additional access modifiers
to this list we have internal protected
internal and private protected
now all three of these access modifiers
relate to assemblies
and assemblies in c sharp are
collections of user-defined data types
as well as resources that are grouped
together and they are usually deployed
to a client as a single unit they may
take the form either of executables or
dynamic link libraries or dlls
now classes in c sharp have a default
constructor that is predefined for all
classes
and all class instances are heap dynamic
in nature in a similar fashion to what
we saw in java
c-sharp also uses garbage collections
similar to java and this is used for
most heap objects so there is auto
de-allocation of dynamically allocated
objects and as a result of this
destructors while they are provided are
fairly rarely used in practice
now c sharp much like c plus also
provides a struct
now in c plus plus a struct and a class
of virtually exactly the same thing it
is for example legal to inherit from a
struct
the only real difference between a
struct and a class in c plus is that a
class's default axis modify if it's not
explicitly changed by the programmer is
private whereas the default axis
modifier for a struct is public
now c sharps structs are relatively
different to c sharp classes
so a strut in c sharp is a lightweight
class and it doesn't support inheritance
so in other words full object
orientation is not supported by structs
in c-sharp
also c-sharp structs only exist on the
stack they cannot be allocated on the
heap dynamically at runtime
now related to this because we can only
allocate structs on the stack in c sharp
we also cannot have structs that
reference themselves
so this limits the use of structs in the
building of adts we for example can't
define a linked list node that has a
reference to another linked list node if
the linked list node is defined as a
struct it must be represented as a class
if we are to have a reference to other
linked list nodes within the linked list
node class
so what i would like you to do at this
point is to pause the video and try to
explain what the use of a struct would
be in contrast to what the use of a
class would be in c sharp
most programming languages that support
adts allow us to provide data member
access by means of accessor methods
which you may know as getter and seater
methods so for example if we have a
class called student then the student
class might have a member variable
called student number
we could then provide retrieval access
for the student number by implementing a
set student number method which would
simply return the student number for a
particular instance of the student class
in a similar fashion we can also allow
the student number to be changed by
implementing a set student number method
and the set student number method would
receive a new student number by means of
a parameter and would then update the
student number
for the student object on which the set
student number method is being called
now of course this approach can also be
used in c sharp however c sharp also
provides a more convenient mechanism
for us which is referred to as
properties
so properties provide a special way to
implement gators and setters
where we don't rely on explicit method
calls
now there are two kinds of properties
provided by c sharp we have get and set
properties
and once we implement either a get
property or a set property or both then
it means that we can access a data
member as though we have direct access
to it so for instance if we have a
student object called s
we can then use s dot student number on
it
now if we assign to the student number
then the set property would be the one
to be called
alternatively if we were just to print
out a start student number then the get
property would be the one that would be
triggered now the important thing to
understand is that these properties can
implement code so we can for instance
implement validation code to ensure
that the state of the member variables
is always intact and the member
variables do not get set to invalid
values we'll illustrate this by means of
an example shortly
on the next slide there is a simple
example of an adt implemented in c-sharp
most of the detail of this adt is left
out because the primary intention is to
illustrate how properties work in a
c-sharp class
so the c-sharp implementation is for a
class called weather
and
within the weather class we have a
member variable called degree days now
there are two properties defined for the
degree days member variable
member variable access
then occurs as though member variables
are public however there's some
additional processing that takes place
so we have a get property for degree
days and this is responsible for
retrieving degree days
and it can include code to filter the
returned value before it is actually
returned in the case of this example
however there is no filtering we just
simply return degree days
then we also have a set property and
this is responsible for setting the
value of the degree days member variable
and this can include code in order to
validate the value that is being sent in
via the
set property before the actual member
variables value is updated and changed
now we can of course choose to implement
only a get or reset property and in this
case we would then limit the
functionality that is available for the
degree days member variable
here we have the implementation for our
weather class in c sharp we can see that
we are defining a class named weather
and this is a public class in c-sharp
again we have braces that delimits the
beginning and the end of the class and
everything within those braces
will be then a member of the weather
class
now down at the bottom over here we
define a member variable called degree
days this is a private member variable
meaning that the client code does not
have direct access to it and the type of
this member variable is int
now we want to provide some access to
this degree days member variables so we
do this by means of a property so here
we are defining a property for degree
days which is an integer value and this
is a public property meaning that it is
accessible to the client code
within this property we then define a
get property over here with the special
word get and all that we do inside the
get property is we return degree days
now we could have added additional code
in here in order to filter degree days
in some way or change its value before
returning it but in this example we
don't do that we simply return degree
days
next we have our set property which is
defined by means of the set special word
and inside this property we then have
some validation code
so value over here refers to the value
that is being used to set the degree
days member variable
and we over here then have an if
statement and this if statement then
checks to see whether the value is in a
valid range if it isn't then we print
out an error message but if the value is
in the correct range then we simply set
degree days up to
that value that has been set so we're
performing data validation in other
words
now down here we have an example of how
these properties can be used so we are
first of all creating an object called w
which is of type weather and we create a
new weather object which is allocated on
the heap
next we have two variables that we will
use both of them integers degree days
today and old degree days
so now over here
we are assigning to the variable old
degree days
w dot degree days and this will then
trigger the get property because we are
retrieving degree days from w so in that
case we will then be executing the get
property
on the final line over here we are
updating degree days so we are assigning
to w dot degree days the value of the
variable degree days today which we
would have set somehow possibly based on
user input
so in this case the set property will
then be the one that will be triggered
and that is over here as we saw a moment
ago
and this will then validate degree days
today and ensure that it is in the
correct range if it isn't in the correct
range an error message will be printed
out otherwise the degree days member
variable will be updated to degree days
today
the last programming language example
that we'll look at in this chapter is
ruby
now in ruby the encapsulation construct
is the class much as we saw in the cases
of c plus
java and c sharp
now of course ruby has variables and
local variables that exist within
methods simply have normal names exactly
the way as they would in c
java or c sharp
however instance variable names begin
with a single at symbol whereas class
variable names begin with two at symbols
now instance variables and class
variables are not explicitly declared as
they would be in c plus java or c sharp
instead when they are used then they are
implicitly declared for the class in
which they appear
instance methods in ruby use function
syntax
and there are only instance methods in
ruby not standalone methods or functions
and this is because everything in ruby
is a class
or an instance of a class that you are
working with
now constructors in ruby are named
initialize and there's only one
initialized constructor per class
and this initialized constructor is
implicitly called whenever new is called
and this happens when an instance of a
class is created in other words an
object is generated
now it is possible for a programmer to
define additional constructors however
these additional constructors are just
normal methods with with names that have
been chosen by the programmer
these methods within their definition
would then call new which would then
result in the default initialize
constructor being called
then the
new constructor which has been defined
can perform additional tasks such as for
example setting up instance variables
with specific values
now it is impossible to have a public
instance or class variable in ruby so
essentially all data related to a class
is private within that class
however class methods have access
control modifiers associated with them
in a fairly similar fashion to what we
saw in c plus java and c sharp
previously
so class methods in ruby can be marked
as either private or public
and if they aren't marked using either
private or public then the default is
public access
now one of the most interesting features
associated with adt support in ruby is
that classes are dynamic in other words
the structure of the class can change
through the course of runtime
now this is achieved by adding methods
to classes or removing methods from
classes and what this then means is that
the interface of a class can change
during the course of execution
so this allows for what is referred to
as meter programming which is where
classes and objects are modified on the
fly while the program is still running
so what i would like you to do at this
point is to pause the video and try to
explain
what these dynamic interfaces in ruby
affect in terms of the programming
language evaluation criteria that we've
been looking at so far in this course
additionally
also try to identify what kinds of
situations meter programming would be
useful for in a practical
situation
[Music]
all right so on the next slide there is
a program code example in ruby and this
is an implementation of the same stack
class that we used when demonstrating
adts in c plus and java previously
over here we have an implementation of
our stack class in ruby the stack class
begins up here where we specify the name
of the class as stack class and the
class ends at the bottom here with the
special word end
we have a single constructor which is
called initialize as you can see up here
and the sets values for the three
instance variables namely stackriff
maxlin and top sub
so these variables get initial values
notice that all three of them start with
a single
at symbol
and this indicates that they are
instance variables
and notice also that stack ref maxlin
and top sub are not separately defined
for our class instead they are
implicitly specified within our
constructor
and this then means that they are
defined as instance variables for stack
class
here we have a
member method that is defined for our
stack class
and we can see that it hasn't been
specified as private so that means that
it is public it's called push and it
receives as a single parameter a number
we then have an if else statement and
this performs a check
to see whether top sub is the same as
maxlin
notice that both of these are again
specified with a single at symbol
which once again means that we are
referring to our instance variables
within our class
so if top sub is the same as maxlin it
means that we have filled up our array
and there's no more space to insert
any values into so in that case we then
print out an error message to the screen
otherwise we have at least one space
available so we entered in the else
portion
and we can see that we then
increase top subs value by 1 and then we
insert into our stack ref array at
subscript top sub and we insert the
value number at that position
additionally we also then have other
member methods that are defined and so
we have pop top and empty defined but we
won't show the implementations here if
you're interested in those
implementations you're welcome to refer
to the textbook where a more complete
rundown of the class is provided
the next topic that we'll look at is
parameterized abstract data types
now parameterized adts are similar in
nature to the parameterized sub-programs
that we spoke about in the previous
chapter
there we looked at two examples template
functions in c plus and generic methods
in java and what we saw is that both of
these constructs allowed us to create
sub-programs for a specific type
and then these sub-programs would work
with that type either receiving
parameters of that type or returning
that type or possibly both and this
would depend on how these sub programs
were used and what types they were used
with
so parameterized adts achieve the same
thing for an abstract data type in other
words they will allow us to create a
class that has a particular generic type
specified for it
usually what would then happen is this
class would store this generic type and
also the member functions or methods for
the class
would
then ensure that they receive and or
return
values of that particular generic type
we would also have to specify this type
when we create
instances
of this generic adt
so parametrized adts are very often
referred to as generic classes
and formally speaking they are adt's
that can store elements of a particular
type where this type is specified when
an instance of the abstract data type is
created now parameterized adts are only
necessary in statically typed languages
and they don't need to be provided by
dynamically typed languages so what i
would like you to do at this point is to
pause the video and try to explain why
dynamically typed languages don't
require support for parameterized
abstract data types
now parameterized abstract data types
are supported in a variety of different
programming languages
in c plus we have template classes ada
also supports parameterized abstract
data types and in java 5 we have generic
classes
c sharp
2005 also supports generic classes that
are relatively similar to java's generic
classes
so as i just mentioned c plus supports
parameterized adts by means of what are
called template classes
the concept of a template class is
fairly similar to that of a template
function which we covered in chapter 9
however the concept holds for the entire
class that represents the adt
so the entire class has a generic
parameter specified and very often we
use the convention of an uppercase t
for that type we can then use the type t
within the abstract data type so for
example if we have a member variable
called data we could specify that data's
type is t
we can also use that t type throughout
all of the various member functions
within the adt so we can have for
example getters which would return type
t and we can have setters that would
receive type t parameters
so the concept then of a parameterized
adt in c
plus is a compile time construct in
exactly the same way as we saw with
template functions
so when an object of the class is
instantiated then we need to specify a
type for the generic parameter so over
here we have an example of this here we
are assuming that we have a stack class
and that this is a template class and
there is some type t that is specified
then for this stack so we will assume
that the stack then stores
a data member
variable which is then of type t so we
can now create a variable called my int
stack over here and we specify that its
type is stack however we also need to
then specify
the type for which this stack is to be
instantiated so here we are specifying
that generic type t
must concretely for my in stack be an
integer and we specify this within
angled brackets
so what happens then is at compile time
the compiler will then generate an
entirely new version of the stack class
and
this version then has all of the
instances of its generic parameter t
replaced with the specified type which
is int in this case so in other words
the data member variable would then have
its type specified as int
we can then create a separate stack
variable and for that variable we may
specify that the type is float
and then a second
instance of the stack class would be
generated at compile time for us but in
this class all of the occurrences of t
would then be replaced with floats so
essentially a template class is then a
shorthand method of specifying multiple
classes that each deal with a specific
type but we only need to then specify
one template class in order to achieve
this
over here we have an implementation of
the stack class as a template class in c
plus
so you can see that again we start off
here defining our class named stack with
an uppercase s
however we additionally have been in the
line just before the first line of the
class definition
a line specifying that this is a
template class
and that the type for our template class
is t
so t then is our generic type and we can
use t then within our class definition
so here we have the private portion of
our definition and this contains all of
the member variables we again have
stackriff maxlin and top sub as we did
in our previous examples what's
important to note here however is the
type of our stack ref member variable so
we can see once again that it's a
pointer indicated by means of this
asterisk however we can see that the
type then is specified as t
so whatever type we use with our stack
that will then be the type that will be
stored inside the stack ref array
so here we then have the public portion
of our class definition
and again we've omitted most of it i've
just included one of the constructors as
well as the top member function in order
to illustrate how this generic type can
be used
so here is our default constructor this
is our stack constructor which receives
no parameters and you can see that we
define initial values for all of the
member variables
so we set maxline to 99 and tops up to
negative one and as we've seen in
previous examples however what's
important to note is that the stack ref
member variable which is an array now
needs to be dynamically allocated on the
heap so we use the new special word over
here and its size is 100 so it allows
for 100 values to be stored but most
importantly its type is t
which means that the values that this
array stores are then values of type t
whether that type be integers floats
booleans or some other potentially more
complex class
and then
secondly we have a member function
called top over here so this just simply
retrieves the value at the top of our
stack
and notice that the name of this member
function is top but very importantly its
return type is t so in other words
whatever type has been stored in the
stack ref array this will be the type
that the top member function will return
so inside this function we simply
perform a test on our top subscript and
test to see whether it's negative one if
it is negative one then it means no
values have been stored in the stack yet
so we simply print out an error message
to the screen
otherwise we then have at least one
value that is stored within our stacks
so we then enter the else portion of our
if statement over here
where we perform a return and this
return is then
our
stack array
stack riff but at subscript top sub
so this will then retrieve the value
from this array which is of type t
and this will be what will be returned
we then of course have additional member
functions which will be defined for this
class
when we use the stack class then we use
the syntax that we saw on the previous
slide so we need to specify which
specific type we want to use for it and
the important thing is then that this is
a compile time construct so whatever
type we specify we will then generate a
new version of the stack class and the
type that we've specified will replace
all of the instances of t
within our class definition so for
example if we specify that we want to
create an object of type uh stack
and we specify that the generic type
associated with it is int then we will
place int where t occurs over here
meaning that we're working with an array
of into values int will also appear here
in our constructor which means that we
are allocating space for an integer
array and the return type of top would
be then
as well in that case the important thing
to understand is that we don't have to
physically ourselves as programmers
write that implementation of the class
it's generated automatically for us by
the compiler
java also supports parameterized classes
in the form of generic classes
so in a similar fashion to c plus plus
generic classes are similar to generic
methods however they apply to an entire
class
now we saw in chapter 9 that the
difference between java's generic
methods and c plus pluses template
functions
was that template functions are a
compile-time construct while generic
methods in java are a runtime construct
and only one version of the generic
method exists as opposed to in c plus
where multiple versions are generated at
compile time as needed
so in the same way generic classes in
java have only one version of the
generic class and the methods within it
so usually generic classes are used for
generic collections and there are a
number of built-in generic collections
that java provides for us such as the
linked list class and the arraylist
class
now in java generic parameters must be
classes and generic parameters are not
allowed to be primitive types so this is
unlike c plus where we saw in our
previous example of a template stack
class in c plus that we could create a
stack object of type int
that kind of thing isn't possible in
java because int is a primitive type it
isn't a class
so a generic class then only uses
objects of the generic parameter type
now we saw in the previous chapter that
when we were talking about generic
methods
only one instance of the generic method
exists and objects are used for the
generic types
and then costs are inserted in order to
ensure that type errors are picked up at
compile time so very much the same kind
of thing happens with generic classes in
java behind the scenes our generic type
is actually dealt within as an object
and we work with object instances within
our class and those are dealt with in
that way internally
however the compiler then inserts costs
automatically and this is for all method
parameters and returns that use the
generic type
so what this means then is that type
errors are caught at compile time not at
runtime the most important thing to
understand is that this is not the same
as in c plus where c plus plus generates
a new version of the entire template
class each time that it is used with a
different type in the case of java
our generic class is a single class that
exists multiple versions are not
generated and we work with objects
internally with costs that are inserted
in order to ensure that type areas are
picked up early at compile time and not
at run time
here we have an implementation in java
of a stack class that is a generic class
so we can see up here our class is
introduced it's a public class and we're
calling this class my stack and then
specifying in square brackets that it is
a generic class
that works with a type specified as t
so here we then have the member
variables for our my stack class in this
case we are going to use stack riff
which is an arraylist now an arraylist
is a generic class itself
so we specify then for that type and in
this case the type then is t
which is the type that we have received
for use with our my stack class
we also have an integer variable called
maxlin that stores the maximum length
for our stack
so both of these then are private member
variables we then have a public default
constructor which you can see over here
it's called my stack which is the name
of its class it doesn't have any return
type or any parameters meaning that it
is a default constructor
so we then set an initial value for
stackriff and here we just create a new
arraylist and again we use the generic
type t for our arraylist to specify that
we are storing whichever type has been
seen through in the construction of the
my stack object that we are creating we
also set maxlin to 99.
here we then have an implementation of
the push method which is also a member
of the mystack class we're leaving out
other methods that would naturally need
to be defined for the my stack class
but those are available in the textbook
so here we have then our push method
that has been defined it's again a
public method and it returns nothing
however it receives a single parameter
called new value and very importantly
the type of this parameter is t
so what this means is we are receiving
then our generic type that has been
specified for the my stack object that
we are attempting to push to
so here we then have an if else
statement that performs a validity check
so we check the size
of our stack ref arraylist and we
compare this
to maxlin if the two are equal then it
means that our stack is full in which
case we print out an error message to
the screen but otherwise we can receive
the values so we then just simply add to
our stack ref array list
the new value that has been passed
through as the parameter to our push
method
so down here we have an example of how
we could create
an object of class my stack
our variable is my stack starting with
the lowercase n so this is the name of
our variable and our type is then
mystack but we have to be careful to
also additionally specify the type that
we want to work with so here we are
specifying that my stack should store
string objects
we then use a new to create an instance
of the stack dynamically
here we are using the my stack
constructor it's the default constructor
because no parameter is specified and
again we have to specify the type that
we want to store within our my stack
object which in this case is string
so what's important to understand then
is that there is only one instance of
the mystac class we don't have multiple
versions of it created at compile time
as in c plus
however
when we are working with our generic
type t
what we are actually working with will
be objects so in other words the stack
riff
member which is an arraylist will store
objects in a similar fashion our
constructor will create an arraylist
that stores objects
and in a similar fashion we will also
then have our parameter for our push
method which is new value will then be
of type object so what this means then
is that any kind of object can be
received however the compiler will
automatically then insert a cost in
order to ensure that a new value is of
the correct type
so for our example use over here
our my stack variable
is then specified to be a my mystac
object of type string we would then
automatically have a cost of this object
that has been passed through as the
parameter to string and that will then
generate an error if we are attempting
to push a value of any other type other
than string
parameterized classes in c-sharp 2005
aren't very interesting because they're
quite similar to the generic classes
provided by java 5.
java 5 does support wild card classes
these are quite similar to the wild card
classes that are allowed for generic
methods which we discussed in the
previous chapter
also
in
generic classes in c sharp
elements of collection classes
specifically that are provided by the
c-sharp language itself can be accessed
through indexing
in other words one does not have to use
a member method in order to access data
within these constructs
so parameterized classes in c-sharp can
be written by the programmer themselves
but they're also predefined for a number
of different collections
including the array class the list class
the stack class the queue class and the
dictionary class
next we'll look at encapsulation
constructs relatively briefly we've
already touched on some of the concepts
that we'll discuss here
previously in our discussion
so if we have very large projects and
large programs that consist of a large
number of classes and potentially
functions
then there are two special needs that
come into play so firstly we need some
means of organizing these very large
projects other than simply dividing them
into sub programs and this is just due
to the fact that these projects become
incredibly complicated
we also need some means of supporting
partial compilation
and this is a support for compiling
smaller units of a larger program
separately rather than compiling the
entire program so we only compile the
portion of the larger project that needs
to be compiled after a change has been
performed
so the obvious solution then to this is
to group logically related sub-programs
together in a single unit
and then we allow these units to be
compiled separately
so groupings like these are then called
encapsulations
so here are some examples of
encapsulation constructs that are
provided by some programming languages
firstly nested sub-programs can be
considered a kind of encapsulation
construct because we are grouping
together sub-programs that are related
within the body of a containing sub
program
so nested sub programs are supported in
python javascript and ruby
the next approach to supporting
encapsulation constructs is for c and c
plus plus
and as we saw previously we have a
separation between a header file and an
implementation file
so what this thing means is that each of
the implementation files can be compiled
separately
and whatever functions or classes
or other structures that are defined
within that implementation file will
then be compiled together as a single
unit
a header file then provides a mechanism
for us to specify an interface which is
visible to the client who is using the
implementation
and that will then specify for them the
prototypes of the various functions that
they are allowed to use
in c-sharp we have the concept of
assemblies and assemblies are basically
groups of related classes and methods
and they are grouped together within an
executable or a dynamic link library or
dll file
so essentially then these related
classes and methods
can then be
accessed as they need to be accessed as
long as the executable or the dll is
properly included in the project
the last concept that we'll look at is
that of naming encapsulations which are
relatively similar to encapsulation
constructs however they are used for a
different purpose
so in very large programs we would
generally define a lot of global names
and because eventually there are so many
names in a very large project
name clashes can then quite easily occur
and become quite commonplace
so somebody may encounter a name clash
when they are working on a completely
different part of the project code and
this of course then can become very
difficult to maintain
so programming languages that are
intended for the development of very
large projects need a way to divide all
of these names into logical groupings
and this is where the concept of a
naming encapsulation comes in
so a naming encapsulation then simply
creates a new scope
for a set of names
so c plus and c sharp have name spaces
which are naming encapsulations
and each library then will be placed
within its own namespace
so this is then a larger overall
grouping than the standard encapsulation
constructs that we see in these
programming languages they may include a
number of separate classes together
as well as standalone functions and
these can all be then grouped together
within a namespace generally speaking
whatever is in a namespace would then be
related and to everything else in the
namespace at least conceptually
so generally speaking we can then use
things that are defined within a
namespace outside of the namespace
and what we would have to do then in
these languages is to qualify names
within the namespace
using the name of the namespace so we
basically specify the namespace first
and then the name of the thing inside
the namespace that we are trying to
access
java also has support for naming
encapsulations and it achieves this
through java packages
so a java package can contain more than
one class definition typically these
class definitions are all related to one
another
and classes within a package are
considered to be partial friends so what
this means is that anything that is
defined as having package scope within a
class that is in a package will then be
visible to every other class contained
within that package this essentially
allows these classes to collaborate more
closely with one another
because they can share data amongst
themselves
now clients who use packages have two
options they can either every time that
they use a clasp in a package they can
use a fully qualified name including the
name of the package
or alternatively they can use an import
statement in order to declare that
everything within a package is imported
and available to the code that is being
written
all right so that concludes our
discussion on chapter 11 of the textbook
in the next lecture we'll be moving on
to the last chapter we'll be looking at
namely chapter 12 which deals with
object oriented programming
5.0 / 5 (0 votes)