- •Using Your Sybex Electronic Book
- •Acknowledgments
- •Contents at a Glance
- •Introduction
- •Who Should Read This Book?
- •How About the Advanced Topics?
- •The Structure of the Book
- •How to Reach the Author
- •The Integrated Development Environment
- •The Start Page
- •Project Types
- •Your First VB Application
- •Making the Application More Robust
- •Making the Application More User-Friendly
- •The IDE Components
- •The IDE Menu
- •The Toolbox Window
- •The Solution Explorer
- •The Properties Window
- •The Output Window
- •The Command Window
- •The Task List Window
- •Environment Options
- •A Few Common Properties
- •A Few Common Events
- •A Few Common Methods
- •Building a Console Application
- •Summary
- •Building a Loan Calculator
- •How the Loan Application Works
- •Designing the User Interface
- •Programming the Loan Application
- •Validating the Data
- •Building a Math Calculator
- •Designing the User Interface
- •Programming the MathCalculator App
- •Adding More Features
- •Exception Handling
- •Taking the LoanCalculator to the Web
- •Working with Multiple Forms
- •Working with Multiple Projects
- •Executable Files
- •Distributing an Application
- •VB.NET at Work: Creating a Windows Installer
- •Finishing the Windows Installer
- •Running the Windows Installer
- •Verifying the Installation
- •Summary
- •Variables
- •Declaring Variables
- •Types of Variables
- •Converting Variable Types
- •User-Defined Data Types
- •Examining Variable Types
- •Why Declare Variables?
- •A Variable’s Scope
- •The Lifetime of a Variable
- •Constants
- •Arrays
- •Declaring Arrays
- •Initializing Arrays
- •Array Limits
- •Multidimensional Arrays
- •Dynamic Arrays
- •Arrays of Arrays
- •Variables as Objects
- •So, What’s an Object?
- •Formatting Numbers
- •Formatting Dates
- •Flow-Control Statements
- •Test Structures
- •Loop Structures
- •Nested Control Structures
- •The Exit Statement
- •Summary
- •Modular Coding
- •Subroutines
- •Functions
- •Arguments
- •Argument-Passing Mechanisms
- •Event-Handler Arguments
- •Passing an Unknown Number of Arguments
- •Named Arguments
- •More Types of Function Return Values
- •Overloading Functions
- •Summary
- •The Appearance of Forms
- •Properties of the Form Control
- •Placing Controls on Forms
- •Setting the TabOrder
- •VB.NET at Work: The Contacts Project
- •Anchoring and Docking
- •Loading and Showing Forms
- •The Startup Form
- •Controlling One Form from within Another
- •Forms vs. Dialog Boxes
- •VB.NET at Work: The MultipleForms Project
- •Designing Menus
- •The Menu Editor
- •Manipulating Menus at Runtime
- •Building Dynamic Forms at Runtime
- •The Form.Controls Collection
- •VB.NET at Work: The DynamicForm Project
- •Creating Event Handlers at Runtime
- •Summary
- •The TextBox Control
- •Basic Properties
- •Text-Manipulation Properties
- •Text-Selection Properties
- •Text-Selection Methods
- •Undoing Edits
- •VB.NET at Work: The TextPad Project
- •Capturing Keystrokes
- •The ListBox, CheckedListBox, and ComboBox Controls
- •Basic Properties
- •The Items Collection
- •VB.NET at Work: The ListDemo Project
- •Searching
- •The ComboBox Control
- •The ScrollBar and TrackBar Controls
- •The ScrollBar Control
- •The TrackBar Control
- •Summary
- •The Common Dialog Controls
- •Using the Common Dialog Controls
- •The Color Dialog Box
- •The Font Dialog Box
- •The Open and Save As Dialog Boxes
- •The Print Dialog Box
- •The RichTextBox Control
- •The RTF Language
- •Methods
- •Advanced Editing Features
- •Cutting and Pasting
- •Searching in a RichTextBox Control
- •Formatting URLs
- •VB.NET at Work: The RTFPad Project
- •Summary
- •What Is a Class?
- •Building the Minimal Class
- •Adding Code to the Minimal Class
- •Property Procedures
- •Customizing Default Members
- •Custom Enumerations
- •Using the SimpleClass in Other Projects
- •Firing Events
- •Shared Properties
- •Parsing a Filename String
- •Reusing the StringTools Class
- •Encapsulation and Abstraction
- •Inheritance
- •Inheriting Existing Classes
- •Polymorphism
- •The Shape Class
- •Object Constructors and Destructors
- •Instance and Shared Methods
- •Who Can Inherit What?
- •Parent Class Keywords
- •Derived Class Keyword
- •Parent Class Member Keywords
- •Derived Class Member Keyword
- •MyBase and MyClass
- •Summary
- •On Designing Windows Controls
- •Enhancing Existing Controls
- •Building the FocusedTextBox Control
- •Building Compound Controls
- •VB.NET at Work: The ColorEdit Control
- •VB.NET at Work: The Label3D Control
- •Raising Events
- •Using the Custom Control in Other Projects
- •VB.NET at Work: The Alarm Control
- •Designing Irregularly Shaped Controls
- •Designing Owner-Drawn Menus
- •Designing Owner-Drawn ListBox Controls
- •Using ActiveX Controls
- •Summary
- •Programming Word
- •Objects That Represent Text
- •The Documents Collection and the Document Object
- •Spell-Checking Documents
- •Programming Excel
- •The Worksheets Collection and the Worksheet Object
- •The Range Object
- •Using Excel as a Math Parser
- •Programming Outlook
- •Retrieving Information
- •Recursive Scanning of the Contacts Folder
- •Summary
- •Advanced Array Topics
- •Sorting Arrays
- •Searching Arrays
- •Other Array Operations
- •Array Limitations
- •The ArrayList Collection
- •Creating an ArrayList
- •Adding and Removing Items
- •The HashTable Collection
- •VB.NET at Work: The WordFrequencies Project
- •The SortedList Class
- •The IEnumerator and IComparer Interfaces
- •Enumerating Collections
- •Custom Sorting
- •Custom Sorting of a SortedList
- •The Serialization Class
- •Serializing Individual Objects
- •Serializing a Collection
- •Deserializing Objects
- •Summary
- •Handling Strings and Characters
- •The Char Class
- •The String Class
- •The StringBuilder Class
- •VB.NET at Work: The StringReversal Project
- •VB.NET at Work: The CountWords Project
- •Handling Dates
- •The DateTime Class
- •The TimeSpan Class
- •VB.NET at Work: Timing Operations
- •Summary
- •Accessing Folders and Files
- •The Directory Class
- •The File Class
- •The DirectoryInfo Class
- •The FileInfo Class
- •The Path Class
- •VB.NET at Work: The CustomExplorer Project
- •Accessing Files
- •The FileStream Object
- •The StreamWriter Object
- •The StreamReader Object
- •Sending Data to a File
- •The BinaryWriter Object
- •The BinaryReader Object
- •VB.NET at Work: The RecordSave Project
- •The FileSystemWatcher Component
- •Properties
- •Events
- •VB.NET at Work: The FileSystemWatcher Project
- •Summary
- •Displaying Images
- •The Image Object
- •Exchanging Images through the Clipboard
- •Drawing with GDI+
- •The Basic Drawing Objects
- •Drawing Shapes
- •Drawing Methods
- •Gradients
- •Coordinate Transformations
- •Specifying Transformations
- •VB.NET at Work: Plotting Functions
- •Bitmaps
- •Specifying Colors
- •Defining Colors
- •Processing Bitmaps
- •Summary
- •The Printing Objects
- •PrintDocument
- •PrintDialog
- •PageSetupDialog
- •PrintPreviewDialog
- •PrintPreviewControl
- •Printer and Page Properties
- •Page Geometry
- •Printing Examples
- •Printing Tabular Data
- •Printing Plain Text
- •Printing Bitmaps
- •Using the PrintPreviewControl
- •Summary
- •Examining the Advanced Controls
- •How Tree Structures Work
- •The ImageList Control
- •The TreeView Control
- •Adding New Items at Design Time
- •Adding New Items at Runtime
- •Assigning Images to Nodes
- •Scanning the TreeView Control
- •The ListView Control
- •The Columns Collection
- •The ListItem Object
- •The Items Collection
- •The SubItems Collection
- •Summary
- •Types of Errors
- •Design-Time Errors
- •Runtime Errors
- •Logic Errors
- •Exceptions and Structured Exception Handling
- •Studying an Exception
- •Getting a Handle on this Exception
- •Finally (!)
- •Customizing Exception Handling
- •Throwing Your Own Exceptions
- •Debugging
- •Breakpoints
- •Stepping Through
- •The Local and Watch Windows
- •Summary
- •Basic Concepts
- •Recursion in Real Life
- •A Simple Example
- •Recursion by Mistake
- •Scanning Folders Recursively
- •Describing a Recursive Procedure
- •Translating the Description to Code
- •The Stack Mechanism
- •Stack Defined
- •Recursive Programming and the Stack
- •Passing Arguments through the Stack
- •Special Issues in Recursive Programming
- •Knowing When to Use Recursive Programming
- •Summary
- •MDI Applications: The Basics
- •Building an MDI Application
- •Built-In Capabilities of MDI Applications
- •Accessing Child Forms
- •Ending an MDI Application
- •A Scrollable PictureBox
- •Summary
- •What Is a Database?
- •Relational Databases
- •Exploring the Northwind Database
- •Exploring the Pubs Database
- •Understanding Relations
- •The Server Explorer
- •Working with Tables
- •Relationships, Indices, and Constraints
- •Structured Query Language
- •Executing SQL Statements
- •Selection Queries
- •Calculated Fields
- •SQL Joins
- •Action Queries
- •The Query Builder
- •The Query Builder Interface
- •SQL at Work: Calculating Sums
- •SQL at Work: Counting Rows
- •Limiting the Selection
- •Parameterized Queries
- •Calculated Columns
- •Specifying Left, Right, and Inner Joins
- •Stored Procedures
- •Summary
- •How About XML?
- •Creating a DataSet
- •The DataGrid Control
- •Data Binding
- •VB.NET at Work: The ViewEditCustomers Project
- •Binding Complex Controls
- •Programming the DataAdapter Object
- •The Command Objects
- •The Command and DataReader Objects
- •VB.NET at Work: The DataReader Project
- •VB.NET at Work: The StoredProcedure Project
- •Summary
- •The Structure of a DataSet
- •Navigating the Tables of a DataSet
- •Updating DataSets
- •The DataForm Wizard
- •Handling Identity Fields
- •Transactions
- •Performing Update Operations
- •Updating Tables Manually
- •Building and Using Custom DataSets
- •Summary
- •An HTML Primer
- •HTML Code Elements
- •Server-Client Interaction
- •The Structure of HTML Documents
- •URLs and Hyperlinks
- •The Basic HTML Tags
- •Inserting Graphics
- •Tables
- •Forms and Controls
- •Processing Requests on the Server
- •Building a Web Application
- •Interacting with a Web Application
- •Maintaining State
- •The Web Controls
- •The ASP.NET Objects
- •The Page Object
- •The Response Object
- •The Request Object
- •The Server Object
- •Using Cookies
- •Handling Multiple Forms in Web Applications
- •Summary
- •The Data-Bound Web Controls
- •Simple Data Binding
- •Binding to DataSets
- •Is It a Grid, or a Table?
- •Getting Orders on the Web
- •The Forms of the ProductSearch Application
- •Paging Large DataSets
- •Customizing the Appearance of the DataGrid Control
- •Programming the Select Button
- •Summary
- •How to Serve the Web
- •Building a Web Service
- •Consuming the Web Service
- •Maintaining State in Web Services
- •A Data-Driven Web Service
- •Consuming the Products Web Service in VB
- •Summary
368 Chapter 8 BUILDING CUSTOM CLASSES
with the old class, while newer applications will work with the newer version of the class. All this can be done without any housekeeping requirements on your part.
Classes are extremely useful in team programming. In large database projects, a team of programmers develops classes that access the database and perform low-level operations. Other developers use these classes to get an abstracted view of the database. For example, programmers who develop frontend applications need not be concerned with the exact structure of the database. They can access methods like AddBook to add a new book to the database, or GetAuthorBooks to get the books of an author. The first method accepts fields like the book’s title and ISBN and creates a new record in the database. The GetAuthorBooks method accepts the ID of an author and returns the books written by this author. The developers working on the front-end applications don’t access the database directly. The appropriate classes give them an abstracted view of the database, and they call simple methods to perform fairly complicated tasks. Another advantage of using classes in database applications is that if you change the structure of the database, or even move the data to another database, you need only change the code in the class and the front-end applications will keep working. The capacity to isolate programmers from unnecessary details is called abstraction.
These are two of the advantages of using classes. In the following section you will learn about inheritance, a feature that will enable you to write truly reusable code. Inheritance is one of the foundations of object-oriented programming, and this is the first version of Visual Basic that supports true inheritance (or implementation inheritance, as it’s called).
Inheritance
The promise of classes, and of object programming at large, is code reuse. The functionality you place into a class is there for your projects, and any other developer can access it as well. To appreciate the power of classes, you must understand what happens when you need to add functionality to your class. There are two ways to extend a class: add new members and revise existing members. Both approaches are quite simple if you’ve written the class. But what if others want to extend your class? Handing out the code is out of the question. Every developer will “improve” your class, and each developer will end up with his own version of it. The class will be no longer reusable. If you unleash the source code of a class to the members of a programming team, it won’t be long before you have dozens of “improved” versions of your class. They may be improved versions, alright, but an application using one of them won’t be able to use any of the others.
Changing your own classes is not simple either. The class is used by multiple applications, so you can’t make changes that will break the existing code. To revise a class without breaking the existing code, you must make sure that the existing members don’t change their interface—that is, you shouldn’t change the types of the properties, or the number and type of the arguments you pass to the methods. The applications using your class don’t see its code. All they care about is that the members they call will keep working. You can rewrite the code of a method, if you come up with a better way to accomplish the task—or other technological advances necessitate the update of the code. If the method doesn’t change name, accepts the same arguments, and returns the same value, the calling application will never know that a different code is executing. Since methods are implemented as functions, it’s possible to overload a method, so that it can be called with different arguments.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
INHERITANCE 369
So, how can we update a class that’s being used by dozens of applications out there? By overriding existing members or supplying the code for new members. Best of all, you don’t need access to the class’s code to extend it. You can add or replace members without seeing the existing code. To understand how useful this can be, let’s start with an example of extending an existing class that’s part of the Framework. Surely, you didn’t think Microsoft would make the code of Windows itself available to all developers. This would break not only existing applications, but the operating system itself. Most of the 3,500 classes that come with the Framework, however, can be extended.
Classes are extended by creating new classes that inherit the functionality of the existing class. And this is the single most important new feature of VB.NET: inheritance. Inheritance is simply the ability to create a new class based on an existing one. The existing class is the parent class, or base class. The new class is said to inherit the base class and is called a subclass, or derived class. The derived class inherits all the functionality of the base class and can add new members and replace existing ones. The replacement of existing members with other ones is called overriding. When you replace a member of the base class, you’re overriding it. Or, you can overload a method by providing multiple forms of the method that accept different arguments.
Inheriting Existing Classes
To demonstrate the power of inheritance, you’re going to extend an existing class, the ArrayList class. This class comes with the Framework, and it’s a dynamic array. (See Chapter 11 for a detailed description of the ArrayList class.) The ArrayList class maintains a list of objects, similar to an array, but it’s dynamic. The class we’ll develop in this section will inherit all the functionality of ArrayList, plus it will expose a custom method we’ll implement here: the EliminateDuplicates method. The project described in this section is the CustomArrayList project on the CD.
Let’s call the new class myArrayList. The first line in the new class must be the Inherits statement, followed by the name of the class we want to inherit, ArrayList. Start a new project, name it CustomArrayList, and add a new Class to it. Name the new class myArrayList:
Class myArrayList
Inherits ArrayList
End Class
If you don’t add a single line of code to this class, the myArrayList class will expose exactly the same functionality as the ArrayList class. If you add a public function to the class, it will become a method of the new class, in addition to the methods of ArrayList. Add the code of the EliminateDuplicates() subroutine (Listing 8.33) to the myArrayList class; this subroutine will become a method of the new class.
Listing 8.33: The EliminateDuplicates Method for the ArrayList Class
Sub EliminateDuplicates()
Dim i As Integer = 0
Dim delEntries As ArrayList
While i <= MyBase.Count - 2
Dim j As Integer = i + 1
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
370 Chapter 8 BUILDING CUSTOM CLASSES
While j <= MyBase.count - 1
If MyBase.Item(i).ToString = MyBase.item(j).ToString Then MyBase.RemoveAt(j)
End If
j = j + 1 End While
i = i + 1 End While
End Sub
The code compares each item with all following items and removes any duplicates. The duplicate items are the ones whose ToString property returns the same value. You may wish to perform very specific comparisons, but the ToString method will do for our demo. To test the derived class, place a button on the test form, and insert the code presented by Listing 8.34 in its Click event handler.
Listing 8.34: Testing the EliminateDuplicates Method
Private Sub Button2_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click Dim mlist As New myArrayList()
mlist.Add(“ 10”) mlist.Add(“A”) mlist.Add(“20”) mlist.Add(“087”) mlist.Add(“c”) mlist.Add(“A”) mlist.Add(“b”) mlist.Add(“a”) mlist.Add(“A”) mlist.Add(“87”) mlist.Add(10) mlist.Add(100) mlist.Add(110) mlist.Add(“1001”)
Console.WriteLine(mlist.GetString())
mlist.EliminateDuplicates()
Console.WriteLine(mlist.GetString()) End Sub
The following table shows the contents of the ArrayList before and after the elimination of the duplicates. Notice that the second list contains the item “10” twice. One of the items is a string, and the other one is a numeric value, and therefore they’re not duplicates.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
INHERITANCE 371
Original List |
After Elimination of Duplicates |
10 |
10 |
A |
A |
20 |
20 |
087 |
087 |
C |
c |
A |
b |
B |
a |
A |
87 |
A |
10 |
87 |
100 |
10 |
|
100 |
|
GetString (Listing 8.35) is not a method of the ArrayList. It’s a method of the extended ArrayList class, which returns the values of all the items in the list (it uses each item’s ToString method to retrieve the string representation of the items).
Listing 8.35: The GetString Method
Function GetString() As String Dim i As Integer
Dim strValue As String
strValue = MyBase.Item(0).ToString For i = 1 To MyBase.Count - 1
strValue = strValue & vbCrLf & MyBase.Item(i).ToString Next
GetString = strValue End Function
Another problem with the ArrayList class is that it can’t sort its elements if they’re not of the same type. You can always provide a custom comparer for custom types, but it’s impossible to write a comparer that can handle all objects. Sometimes, however, we need to know the smallest or largest numeric element, or the alphabetically first or last element. These methods apply to numeric or string elements only; if some of the collection’s elements are objects, we can ignore them. Let’s implement two more custom methods (Listing 8.36) for myArrayList. The Min method returns the alphabetically smallest value; the NumMin method returns the numerically smallest value.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |
372 Chapter 8 BUILDING CUSTOM CLASSES
Listing 8.36: The Min and NumMin Methods of the ArrayList Class
Function Min() As String
Dim i As Integer
Dim minValue As String
minValue = MyBase.Item(0).ToString For i = 1 To MyBase.Count - 1
If MyBase.Item(i).ToString < minValue Then _ minValue = MyBase.Item(i).ToString
Next
Min = minValue End Function
Function NumMin() As Double Dim i As Integer
Dim minValue As Double minValue = 1E+230
For i = 1 To MyBase.Count - 1
If IsNumeric(MyBase.item(i)) And _ val(MyBase.Item(i).tostring) < minValue Then _
minValue = val(MyBase.Item(i).tostring)
Next
NumMin = minValue End Function
You can populate the myArrayList with strings and integers and call the Min and NumMin methods to retrieve the smaller string or numeric value in the list.
What have we done in this section, really? We took an existing class, a very powerful one, and extended it. We did that by writing simple VB statements that could have appeared in any application. We just had to insert the Inherits keyword followed by the name of an existing class on which we want to base our class, and provide the implementation of the new methods. A few more keywords to learn and you can practically customize any class that comes with the Framework. Existing applications won’t break (the ArrayList class is actually used by some system services, which will keep working fine); they see the original class, not myArrayList. Some of your new applications will see the enhanced ArrayList. Another developer might extend the functionality of your derived class. The old applications will work because ArrayList is still around; your applications will also work because myArrayList hasn’t been modified; and someone else’s applications will work with another class derived from yours.
Implementation inheritance is a powerful feature and can be used in many situations, besides enhancing an existing class. You can design base classes that address a large category of objects and then subclass them for specific objects. The typical example is the Person class, from which classes like Contact, Customer, Employee, and so on can be derived. Inheritance is used with large-scale projects to ensure consistent behavior across the application. In the following section, you’re going to see an interesting application of inheritance. We’re going to build classes that describe related objects (shapes), all of which will be based on a single class that encapsulates the basic characteristics of all derived classes.
Copyright ©2002 SYBEX, Inc., Alameda, CA |
www.sybex.com |