Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning ASP.NET 2

.0.pdf
Скачиваний:
23
Добавлен:
17.08.2013
Размер:
24.67 Mб
Скачать

Code

Inheritance

Inheritance is another of the key features of objected-oriented software, and works just like real life, where we inherit properties and behavior from our parents. Inheritance can get quite complex, so this section just covers the basics to give you an understanding of what it is and how it works, especially as it’s used in all code-behind files. The essentials of inheritance are that one class (the base class) can be inherited by another (the sub-class), in which case the sub-class automatically has the same methods and properties as the base class. But the sub-class can change the behavior if it needs to, or add to it.

ASP.NET uses inheritance as part of its standard programming model, and you have probably already seen this in action. For example, consider a Default.aspx Web Form, which would have the following in it:

<%@ Page Language=”VB” CodeFile=”Default.aspx.vb” Inherits=”_Default” %>

Here you can see the Inherits keyword being used, telling you that when the Web Form is compiled it should inherit its features from the class _Default. This class is in the code-behind file:

Partial Class _Default

Inherits System.Web.UI.Page

. . .

End Class

This class in turn inherits from System.Web.UI.Page, which is the class that provides all of the base functionality for ASP.NET pages. One thing to notice is the Partial keyword, which tells the compiler that this class is split across multiple files — the Web Form and the code-behind file.

The following Try It Out uses some simple (and rather contrived) examples to show how inheritance works.

Try It Out

Classes and Inheritance

1.Create a new class in the App_Code directory called Vehicles.vb. If the App_Code directory doesn’t exist you can create this directory by selecting the top item in the Solution Explorer and using the right mouse button to select Add ASP.NET Folder and then App_Code Folder, as shown in Figure 9-9.

2.Delete the template class created, and create a new one called Vehicle, which has properties called Wheels and TopSpeed, and a method called Warning:

Public Class Vehicle

Protected _wheels As Integer

Protected _topSpeed As Integer

Protected _warningSound As String

Public Property Wheels() As Integer Get

Return _wheels End Get

Set(ByVal value As Integer) _wheels = value

339

Chapter 9

End Set

End Property

Public Property TopSpeed() As Integer Get

Return _topSpeed End Get

Set(ByVal value As Integer) _topSpeed = value

End Set

End Property

Public Overridable Function Warning() As String

Return _warningSound

End Function

End Class

Figure 9-9

3.After that create another class, in the same file, called Car:

Public Class Car

Inherits Vehicle

Public Sub New()

_wheels = 4

_topSpeed = 150 _warningSound = “Honk”

End Sub

End Class

340

Code

4.And now another class called Bike:

Public Class Bike

Inherits Vehicle

Public Sub New()

Wheels = 2

MyBase.TopSpeed = 30

_warningSound = “Ring Ring”

End Sub

End Class

5.And another class called Skateboard:

Public Class Skateboard

Inherits Vehicle

Public Sub New()

_wheels = 4

_topSpeed = 15

End Sub

End Class

Between the End Sub and End Class, type the following:

Public Overrides

Now press the space bar to see that a little helper tip pops up (see Figure 9-10).

Figure 9-10

6.Select the Warning() As String entry (you can ignore the others) and press Return. See how the function is created for you. Delete the existing return line and add a new one:

Public Overrides Function Warning() As String

Return “No warning – you’ll have to shout yourself”

End Function

7.Save and close the class file.

341

Chapter 9

8.Create a new Web Form called Inheritance.aspx. Add three buttons and three labels, so it looks like Figure 9-11. Make sure the Label next to Wheels is Label1, the Label next to Speed is Label2, and the Label next to Warning is Label3. You can use the Text property of the buttons to change the text shown on them.

Figure 9-11

9.Create event handlers for the Click event for the three buttons. For the Car button:

Public Sub Button1_Click(ByVal Sender As Object, _

ByVal e As Sytem.EventArgs) Handles Button1.Click

Dim MyTransport As New Car()

Label1.Text = MyTransport.Wheels.ToString()

Label2.Text = MyTransport.TopSpeed.ToString()

Label3.Text = MyTransport.Warning()

End Sub

10.For the Bike button:

Public Sub Button2_Click(ByVal Sender As Object, _

ByVal e As Sytem.EventArgs) Handles Button1.Click

Dim MyTransport As New Bike()

Label1.Text = MyTransport.Wheels.ToString()

Label2.Text = MyTransport.TopSpeed.ToString()

Label3.Text = MyTransport.Warning()

End Sub

11.For the Skateboard button:

Public Sub Button3_Click(ByVal Sender As Object, _

ByVal e As Sytem.EventArgs) Handles Button1.Click

Dim MyTransport As New Skateboard()

Label1.Text = MyTransport.Wheels.ToString()

Label2.Text = MyTransport.TopSpeed.ToString()

Label3.Text = MyTransport.Warning()

End Sub

12.In the Solution Explorer right-click Inheritance.aspx, and from the menu select Set As Start Page.

13.Press F5 to run the page. Click the three buttons and notice what is displayed in the labels.

342

Code

How It Works

To see how this works you’ll start with the Vehicle class. This is much as you’ve seen before, but with a few subtle differences. One of the private variables, _warningSound, is not set anywhere — don’t worry about that, it’s deliberate, and will be used in other classes. Also the private variables are declared as Protected, meaning that other classes in the same file will be able to access them. This class will be the base class — the class that other classes inherit from. The other difference is that the Warning method has a new keyword on it — Overridable:

Public Overridable Function Warning() As String

Return _warningSound

End Function

This means that inheriting classes can override this method and provide their own implementation. So let’s look at the inheriting classes, starting with the Car:

Public Class Car

Inherits Vehicle

Public Sub New() _wheels = 4 _topSpeed = 150

_warningSound = “Honk” End Sub

End Class

This defines a new class but in the line after the class name it specifies the class to be inherited from. This means the Car automatically has the properties and methods that the base class has. The base class hasn’t set any values so the car has a constructor to do this, which uses the private variables declared by the base class. It can access those variables because they’ve been declared as Protected.

The Bike class is slightly different:

Public Class Bike

Inherits Vehicle

Public Sub New()

Wheels = 2

MyBase.TopSpeed = 30

_warningSound = “Ring Ring”

End Sub

End Class

The way it inherits is the same, but setting the properties is different. For the number of wheels, instead of using the private variable of the base class, the property of the class is used. Even though the current class doesn’t define the Wheels property itself, it does have a Wheels property because it is inherited from the base class. For the top speed the property of the base class is called directly; the keyword MyBase refers to the base class. There is no property for the warning sound so the private variable is used directly.

343

Chapter 9

All of these methods are acceptable, and you’ll see all three used in various pieces of documentation, books, or online tutorials. In general it’s best to use the properties, because that fits with the objectoriented principles talked about earlier.

The Skateboard class is different again:

Public Class Skateboard

Inherits Vehicle

Public Sub New()

_wheels = 4

_topSpeed = 15

End Sub

Public Overrides Function Warning() As String

Return “No Warning – you’ll have to shout yourself!”

End Function

End Class

The constructor sets the values for wheels and top speed, but not the warning message. The big difference is that the Warning property is overridden, meaning that instead of using the Warning method from the base class, the Skateboard class is defining its own Warning method. This is called polymorphism, and allows different classes to have the same methods and properties but with different behavior.

Using these classes is simple:

Dim MyTransport As New Car()

Label1.Text = MyTransport.Wheels.ToString()

Label2.Text = MyTransport.TopSpeed.ToString()

Label3.Text = MyTransport.Warning()

This simply creates the new class and accesses the properties and the methods. Whatever the class type created you can see that the same properties and methods are available. Even though these classes don’t define the properties themselves, inheritance means they have the properties. The same applies to the methods, where the Car and Bike don’t define the methods, but the Skateboard does, overriding the existing implementation and providing its own.

Variable Scope and Lifetime

Although a topic related to variables, the discussion of scope and lifetime has been left until now because it affects all of the other topics you’ve learned about. The term scope means the degree to which a variable is accessible to other code, and the scope affects the lifetime. You’ve seen how Private and Public affect the visibility of methods and properties, but may not realize that visibility of variables depends on where they are declared. To make this easier, take a look at some code:

Public Class Class1

Private _variable1 As Integer

Private Sub Method1()

344

Code

Dim variable2 As Integer

_variable1 = 1 variable2 = 3

End Sub

Private Sub Method2()

_variable1 = 2

End Sub

End Class

The variable _variable1 is declared within the class, outside of any methods, so it can be accessed from any methods and properties. On the other hand, variable2 is declared within the method Method1, so it can only be accessed within Method1 — no other methods or properties would be able to use it. This is termed a local variable.

The same rules apply to variables declared within code blocks. For example:

Dim number1 As Integer If number1 = 15 Then

Dim number2 As Integer number2 = number1 + 15

End If

Here number1 is declared outside of the If Then block, and can therefore be used within it. But number2 is declared within the code block, so it cannot be used outside of the code block. The same rules apply to other code blocks such as loops.

The For Each loop also has this:

For Each item As CartItem in Cart.Items

Next

The variable item is declared within the statement itself, but follows the same rule — it can only be accessed from within the loop. Trying to access it outside of the loop would generate a compile error.

Generics

Generics refers to classes and methods that work uniformly on values of different types. Generics are often discussed as an advanced topic, and though some of it is advanced, some of it is simple and easy to use. In fact, one feature of generics is used in the shopping cart. Remember how the cart consists of two classes: the CartItem and the ShoppingCart, which uses the CartItem as a collection.

Many of the collections discussed early in the chapter provide storage for objects — the Object being a type. Because they are designed to work with a data type of Object, collections can in fact store any data type. However, when you take items out of a collection they often need to be converted from the Object data type to their native data type. This involves extra coding and reduces performance. Another problem is because collections can store any data type it means you can store any data type in them. If

345

Chapter 9

you had a collection to store the CartItem objects you could in fact store strings, numbers, dates, and so forth in the same collection. For example you could do this:

Dim _items As New List()

Dim item As New CartItem( . . .)

_items.Add(item)

_items.Add(“this isn’t a cart item”) _items.Add(“65”)

When taking items out of the collection you’d have no idea what data type it was unless you tracked which objects you put into the list.

To get around this problem you use generics, or more specifically generic collections. These are stored in the System.Collections.Generic namespace, and the one the shopping cart uses is the List:

Private _items As List(Of CartItem)

This simply states that _items is a List, but a list only of CartItem objects. So now you do this:

Dim _items As New List(Of CartItem)

Dim item As New CartItem( . . .)

_items.Add(item)

But because the list is of a specific data type you can’t do this:

_items.Add(“this isn’t a cart item”)

_items.Add(“65”)

Both of these lines would generate compile time errors. Whenever you need a collection of custom classes, it’s always a good idea to use generic collections, because they improve the readability of your code, reduce the potential for errors, as well as provide performance improvements over the standard collections.

Summar y

This chapter has covered a lot of ground, but it was necessary. Although the rich controls in ASP.NET 2.0 provide a way to create web applications with less code than previous versions, you can’t get away without coding completely. So you’ve learned the fundamentals of coding and what you need to control your program. Specifically, this chapter covered the following topics:

Variables and data types, and how to work with the different data types, seeing that data types have different features. You also looked at arrays and collections, as a way of storing groups of variables.

The control of programs is by way of decisions and loops, which use expressions and operators as part of the decision process. You saw how there are different ways to perform both decisions and loops, depending on the requirements.

346

Code

You then looked at classes, and how they have constructors, properties, and methods. This chapter didn’t look at events explicitly, but like the controls you use on Web Forms, custom classes can have them if required.

Finally, you took a brief look at generics, and saw how they help produce type-safe code and improve code readability and performance.

The next chapter examines componentization, and discusses the use of code-behind files and standalone classes from the design and structure perspective rather than what the code actually means.

Exercises

1.Create a class and shared method (called DeliveryDate) to calculate delivery date given the date of an order. All deliveries should be made within three days of the order.

2.Continuing from Exercise 1, modify the DeliveryDate method to take into account that deliveries do not happen on the weekend.

3.Modify the DeliveryDate method to take into account that an order takes three working days to process. So orders falling on a Thursday will be delivered on the following Monday, and orders from Friday will be delivered on the following Tuesday.

4.For each of the following Boolean expressions, say for what integer values of A each of them will evaluate to True and when they will evaluate to False:

a.NOT A=0

b.A > 0 OR A < 5

c.NOT A > 0 OR A < 5

d.A > 1 AND A < 5 OR A > 7 AND A < 10

e.A < 10 OR A > 12 AND NOT A > 20

347