To save content items to your account,
please confirm that you agree to abide by our usage policies.
If this is the first time you use this feature, you will be asked to authorise Cambridge Core to connect with your account.
Find out more about saving content to .
To save content items to your Kindle, first ensure no-reply@cambridge.org
is added to your Approved Personal Document E-mail List under your Personal Document Settings
on the Manage Your Content and Devices page of your Amazon account. Then enter the ‘name’ part
of your Kindle email address below.
Find out more about saving to your Kindle.
Note you can select to save to either the @free.kindle.com or @kindle.com variations.
‘@free.kindle.com’ emails are free but can only be saved to your device when it is connected to wi-fi.
‘@kindle.com’ emails can be delivered even when you are not connected to wi-fi, but note that service fees apply.
Data we create via object creation cannot be treated in the same way native data (integers, strings, etc.) are treated. When we are working with strings, for example, it is easy to compare two strings to see if they are equivalent. In contrast, when we are working with two class objects, where each object is a composite of multiple data types, how we report the result of comparing the two objects is not obvious. Visual Basic.NET provides a special interface, IComparable, to aid us in making these types of comparisons.
Class objects also present a problem when we want to store them in a data structure and retrieve them using a For Each loop. The VB.NET compiler cannot automatically return an enumerator for class objects stored in an ArrayList or some other data structure, so we must provide the enumeration code. The.NET Framework again helps us in this task by providing an interface, IEnumerable, that we can implement. In this chapter we'll discuss how to implement both interfaces and provide several examples to see exactly how they're used.
THE ICOMPARABLE INTERFACE
A class type usually represents a complex data type comprising components of one of the built-in data types (String, Integer, Boolean, etc.). For example, an Employee class might include data for an employee's name (including the first, middle, and last name), social security number, salary, the department in which he or she works, etc. If we want to compare two Employee objects to see if they are the same, how do we do it?
It is not enough just to know how to write object-oriented programs; you also have to know how to write object-oriented programs well. As you gain experience writing object-oriented programs, you will discover certain programming idioms that are used over and over again. These idioms are called design patterns.
DESIGN PATTERNS
Design patterns were first described in Design Patterns—Elements of Reusable Object-Oriented Software (Gamma 1995). A design pattern is a solution to a recurring problem in object-oriented design and implementation. There are four parts to a design pattern, as described in Gamma et al.'s book (Gamma 1995, p. 3):
Pattern name—A name for making it easier to discuss using the pattern.
Problem—An explanation of the problem and its context.
Solution—An abstract description of the design problem and how to use VB.NET code to solve it.
Consequences—The pros and cons of implementing the design pattern.
The Shared Factory Method
Using constructors to create instances of classes is not always the preferred approach to instantiating class objects. One problem with constructors is that they don't have names, which can lead to confusing code. Another problem with constructors is that each constructor has to have its own signature, meaning that only one type of class object can be instantiated for each signature.
We can work around these problems by writing methods that create objects. This is a design pattern known as a factory method. In this case, we create a Shared Factory method that can be called without needing an instance of a class.
This chapter introduces the class, the primary means of implementing OOP in VB.NET. The class framework provides the programmer with many techniques for exploiting the three main principles of OOP—encapsulation, inheritance, and polymorphism.
Classes are somewhat similar to structures in that they allow you to combine data members and methods in the same unit. Classes, though, are much more powerful than structures because they have many more tools available to them. These tools include constructor methods for creating new objects and the capabilities of having multiple methods with the same name and inheriting the definition of one class in another class.
This chapter begins with an overview of class construction, followed by the step-by-step creation of a class, and finally ending with several more examples of creating and using classes. The next few chapters in the book will explore many of the topics we introduce in this chapter.
BUILDING A CLASS
Class construction follows naturally from a well-designed ADT. There are some modifications we'll have to make to our ADT design to incorporate some concepts found in classes but not in structures. Still, a complete ADT makes building a class much easier than if you start from scratch.
The Class Heading
Like a structure, a class definition begins with its heading. The heading of a class consists of an access modifier, the reserved word Class, and a name for the class.
The idea of writing a book on all the areas of mathematics that appear in the evaluation of integrals occurred to us when we found many beautiful results scattered throughout the literature.
The original idea was naive: inspired by the paper “Integrals: An Introduction to Analytic Number Theory” by Lian Vardi (1988) we decided to write a text in which we would prove every formula in Table of Integrals, Series, and Products by I. S. Gradshteyn and I. M. Rhyzik (1994) and its precursor by Bierens de Haan (1867). It took a short time to realize that this task was monumental.
In order to keep the book to a reasonable page limit, we have decided to keep the material at a level accesible to a junior/senior undergraduate student. We assume that the reader has a good knowledge of one-variable calculus and that he/she has had a class in which there has been some exposure to a rigorous proof. At Tulane University this is done in Discrete Mathematics, where the method of mathematical induction and the ideas behind recurrences are discussed in some detail, and in Real Analysis, where the student is exposed to the basic material of calculus, now with rigorous proofs. It is our experience that most students majoring in mathematics will have a class in linear algebra, but not all (we fear, few) study complex analysis. Therefore we have kept the use of these subjects to a minimum. In particular we have made an effort not to use complex analysis.
The goal of the book is to present to the reader the many facets involved in the evaluation of definite integrals.
Visual Basic is arguably the most popular application development programming language in use today. Thousands, if not millions, of programmers use it every day to build both commercial and scientific applications. The language is also one of the most maligned programming languages, second perhaps only to Cobol.
The newest version of Visual Basic, Visual Basic.NET (VB.NET), should eventually quiet many of those who call Visual Basic a toy language. Microsoft performed a major redesign of Visual Basic and added many features that put the language on equal footing with the other major.NET language, C#, and with other contemporary languages, especially Java.
One area of the language that has seen significant improvement is VB.NET's object-oriented programming features. In previous versions of Visual Basic, many of these features were partially implemented, not implemented at all, or implemented in a wrong-headed manner. VB.NET provides the programmer with a complete set of object-oriented tools. This book explains in detail how to use these features.
The book is informally partitioned into three parts. Chapters 1 through 6 present the fundamentals of object-oriented programming (OOP) using VB.NET. Chapter 1 provides a review of the syntax of VB.NET. This chapter is especially useful for readers who have experience with an older version of Visual Basic. Chapter 2 discusses the philosophy of OOP, including some sections on object-oriented design and abstract data types. Chapter 3 covers programming with structures, which are similar to user-defined types (UDTs) in Visual Basic 6.
Serialization is the process of capturing the current state of a class object and writing the state to disk. Serialization allows you to make a class object persistent, which means that you can save the current state of an object while a program is running and at a later time retrieve that state and continue using the object. In this chapter, we'll show you how to perform both serialization and deserialization, which is retrieving an object's state from disk.
SERIALIZATION DEFINED
Serialization in VB.NET involves writing out the state of a class object as a series of bytes to a byte stream. The CLR writes out a class object as an object-graph, which consists of the class object and all the member data associated with the object. To let the CLR know that a class can be serialized, it must be marked with the Serializable attribute.
Although classes must be marked to be serialized, primitive types do not have to be marked as such. Therefore, all the primitive types within your class definition will be serialized automatically when the class is marked Serializable. Other objects (such as nested classes) within a class definition must be tagged with the Serializable attribute if they are to be serialized with the rest of the class types.
A class is physically serialized using a formatter. A formatter, as its name suggests, defines the format of the data stream that is written to disk.
As you write more and more complex programs, you will find situations where you want to define classes that are so abstract that you will not want users to implement them directly. Instead, you will want to derive classes from these abstract classes that define more specific data and behavior. Abstract classes are implemented in VB.NET using the MustInherit keyword.
A simple example that beautifully illustrates the concept of abstract classes is food. When you go to a restaurant, you don't order just food. You order some type of food, such as steak, or a salad, or apple pie. Each of these is a specific instance of food, sharing some characteristics with the others, while obviously also differing from the others in substantial ways. Abstract classes let us define a high-level abstract object, such as food, that we can then use as a base class for many different derived classes. Because we would never want to instantiate the abstract class, we mark it abstract (MustInherit) so that it is clear the class is to be used as a base class only.
Creating Abstract Classes
To designate a class as an abstract class in VB.NET, we use the MustInherit keyword. Once a class is defined this way, we can only use the class as a base class for other derived classes.
Within an abstract class, we can declare the usual private data members, constructor methods, property methods, and so on.
One of the most confusing aspects of OOP is determining the proper access modifier to use for classes and class data members and methods. If you provide too much scope for a data member or method, you risk violating data encapsulation, leading to unwanted data access. If your scope is too restrictive, other classes that need access to a class's data or methods won't be able to access them. In this chapter we discuss the different access modifiers, how they are used to manage class member and method scoping, and when to use each modifier. At the end of the chapter we discuss how these access modifiers work with classes themselves.
The access modifiers available in VB.NET are the following:
Public
Private
Protected
Friend
Protected Friend
We also discuss the modifier Shadows in this chapter. A method declared as Shadows in a derived class hides any methods in the base class with the same name. In effect, a method that shadows another method redefines the shadowed method's behavior.
PUBLIC ACCESS
A class member or method marked as Public can be accessed by any part of the class body, by any part of the project in which the class definition is located, or from an assembly built from the project containing the class definition. This is the least restrictive access and is frequently misused by many programmers.
Reflection refers to the ability of a VB.NET program to access the metadata stored in both running and existing assemblies. Using these metadata, you can examine the contents of a program, manipulate the metadata in the assembly, and even dynamically create and execute objects at runtime. Reflection allows us to dynamically invoke class member functions and even instantiate class objects dynamically.
Attributes are custom-written metadata you can add to an existing assembly. Attributes are used for several purposes:
to indicate whether a class is serializable (see Chapter 13 for information on what this means);
to indicate individual class fields that are not serializable;
to perform conditional compilation; and
to create strongly named types.
Attributes are created as classes that inherit from the System.Attribute class. Attributes are accessed using reflection, so these two topics build on each other.
USING REFLECTION
As we've already stated, reflection allows us to examine the metadata found in our VB.NET programs. To use reflection, we have to import the System. Reflection class into our application. From there, we have to decide which assembly we want to inspect and which metadata we want to look at in the assembly.
Returning Metadata from an Assembly
Assembly metadata can be returned from assemblies that exist on a machine and assemblies that are currently running on a machine. An assembly's metadata are stored in the assembly's manifest, either in a PE (portable executable) file with the MSIL code for the assembly or in a standalone PE file.