VB.NET
Type Members
1 Interface Method Implementation
Methods, events, and properties can implement
interface members. To implement an interface member, a member declaration
specifies the Implements keyword and lists one or more interface
members. Methods and properties that implement interface members are implicitly NotOverridable unless
declared to be MustOverride, Overridable, or overriding another member. It is an error for a
member implementing an interface member to be Shared. A member's accessibility has no effect on its
ability to implement interface members.
For an interface implementation to be valid, the
implements list of the containing type must name an interface that contains a
compatible member. A compatible member is one whose signature matches the
signature of the implementing member. If an event declared using a delegate
type is implementing an interface event, then a compatible event is one whose
underlying delegate type is the same type. Otherwise, the event uses the
delegate type from the interface event it is implementing. If such an event
implements multiple interface events, all the interface events must have the
same underlying delegate type. For example:
Interface ClickEvents
Event LeftClick(ByVal x As Integer, ByVal y
As Integer)
Event RightClick(ByVal x As Integer, ByVal y As Integer)
End Interface
Class Button
Implements ClickEvents
' OK. Signatures match, delegate type = ClickEvents.LeftClickHandler.
Event LeftClick(ByVal x As Integer, ByVal y As Integer) _
Implements ClickEvents.LeftClick
' OK. Signatures match, delegate type = ClickEvents.RightClickHandler.
Event RightClick(ByVal x As Integer, ByVal y As Integer) _
Implements ClickEvents.RightClick
End Class
Class Label
Implements ClickEvents
' Error. Signatures match, but can't be both delegate types.
Event Click(ByVal x As Integer, ByVal y As Integer) _
Implements ClickEvents.LeftClick, ClickEvents.RightClick
End Class
An interface member in the implements list is
specified using a type name, a period, and an identifier. The type name must be
an interface in the implements list or a base interface of an interface in the
implements list, and the identifier must be a member of the specified
interface. A single member can implement more than one matching interface
member.
Interface ILeft
Sub F()
End Interface
Interface IRight
Sub F()
End Interface
Class Test
Implements ILeft, IRight
Sub
F() Implements ILeft.F, IRight.F
End Sub
End Class
If the interface member being implemented is
unavailable in all explicitly implemented interfaces because of multiple
interface inheritance, the implementing member must explicitly reference a base
interface on which the member is available. For example, if I1 and I2 contain a member M, and I3 inherits
from I1 and I2, a type implementing I3 will implement I1.M and I2.M. If an interface shadows multiply
inherited members, an implementing type will have to implement the inherited
members and the member(s) shadowing them.
Interface ILeft
Sub F()
End Interface
Interface IRight
Sub F()
End Interface
Interface ILeftRight
Inherits ILeft, IRight
Shadows Sub F()
End Interface
Class Test
Implements ILeftRight
Sub LeftF() Implements ILeft.F
End Sub
Sub RightF() Implements IRight.F
End Sub
Sub LeftRightF() Implements ILeftRight.F
End Sub
End Sub
ImplementsClause ::= [ Implements
ImplementsList ]
ImplementsList ::=
InterfaceMemberSpecifier
|
ImplementsList ,
InterfaceMemberSpecifier
InterfaceMemberSpecifier ::= TypeName .
Identifier
2 Methods
Methods contain the executable statements of a program. Methods,
which have an optional list of parameters and an optional return value, are
either shared or nonshared. Shared methods are accessed through the class or
instances of the class. Nonshared methods, also called instance methods, are
accessed through instances of the class. The following example shows a class Stack
that
has several shared methods (Clone
and Flip
), and several instance methods (Push
,Pop
, and ToString
):Imports System
Public Class Stack
Public Shared Function Clone(ByVal s As Stack) As Stack
End Function
Public Shared Function Flip(ByVal s As Stack) As Stack
End Function
Public Function Pop() As Object
End Function
Public Sub Push(ByVal o As Object)
End Sub
Public Overrides Function ToString() As String
End Function
End Class
Module Test
Sub Main()
Dim s As Stack = New Stack()
Dim i As Integer
While i < 10
s.Push(i)
End While
Dim flipped As Stack = Stack.Flip(s)
Dim cloned As Stack = Stack.Clone(s)
Console.WriteLine("Original stack: " & s.ToString())
Console.WriteLine("Flipped stack: " & flipped.ToString())
Console.WriteLine("Cloned stack: " & cloned.ToString())
End Sub
End Module
Methods can be overloaded, which means that multiple methods may
have the same name so long as they have unique signatures. The signature of a
method consists of the name of the method and the number and types of its
parameters. The signature of a method specifically does not include the return
type or parameter modifiers. The following example shows a class with a number
of F
methods:Imports System
Module Test
Sub F()
Console.WriteLine("F()")
End Sub
Sub F(ByVal o As Object)
Console.WriteLine("F(Object)")
End Sub
Sub F(ByVal value As Integer)
Console.WriteLine("F(Integer)")
End Sub
Sub F(ByVal a As Integer, ByVal b As Integer)
Console.WriteLine("F(Integer, Integer)")
End Sub
Sub F(ByVal values() As Integer)
Console.WriteLine("F(Integer())")
End Sub
Sub Main()
F()
F(1)
F(CType(1, Object))
F(1, 2)
F(New Integer() { 1, 2, 3 })
End Sub
End Module
The output of the program is:F()
F(Integer)
F(Object)
F(Integer, Integer)
F(Integer())
MethodMemberDeclaration ::= MethodDeclaration | ExternalMethodDeclaration
3 Constructors
Constructors are
special methods that allow control over initialization. They are run after the
program begins or when an instance of a type is created. Unlike other members,
constructors are not inherited and do not introduce a name into a type's
declaration space. Constructors may only be invoked by object-creation
expressions or by the .NET Framework; they may never be directly invoked.ConstructorMemberDeclaration ::=
[ Attributes ] [ ConstructorModifier+ ] Sub New
[ ( [ ParameterList ] ) ] LineTerminator
[ Block ]
End Sub LineTerminator
ConstructorModifier ::= AccessModifier | Shared
4 Events
Events are used to notify code of a particular occurrence. An
event declaration consists of an identifier, either a delegate type or a
parameter list, and an optional Implements clause. If a delegate type is specified,
the delegate type may not have a return type. If a parameter list is specified,
it may not contain Optional or ParamArray parameters. The accessibility domain of
the parameter types and/or delegate type must be the same as, or a superset of,
the accessibility domain of the event itself. Events may be shared by specifying
the Shared modifier.In addition to the member name added to the type's declaration space, an event declaration implicitly declares several other members. Given an event named
X
, the following members
are added to the declaration space:- If the form of the declaration
is a method declaration, a nested delegate class named
XEventHandler
is introduced. The nested delegate class matches the method declaration and has the same accessibility as the event. The attributes in the parameter list apply to the parameters of the delegate class. - A Private instance
variable typed as the delegate, named
XEvent
. - A method named
add_X
, which takes the delegate type and has the same access type as the event. - A method named
remove_X
, which takes the delegate type and has the same access type as the event.
Class Raiser
Public Event Constructed(ByVal i As Integer)
End Class
is equivalent to the following declarationClass Raiser
Public Delegate Sub ConstructedEventHandler(ByVal i As Integer)
Protected ConstructedEvent As ConstructedEventHandler
Public Sub add_Constructed(ByVal d As ConstructedEventHandler)
ConstructedEvent = _
CType( _
ConstructedEvent.Combine(ConstructedEvent, d), _
Raiser.ConstructedEventHandler)
End Sub
Public Sub remove_Constructed(ByVal d As ConstructedEventHandler)
ConstructedEvent = _
CType( _
ConstructedEvent.Remove(ConstructedEvent, d), _
Raiser.ConstructedEventHandler)
End Sub
End Class
Declaring an event without specifying a delegate type is the
simplest and most compact syntax, but has the disadvantage of declaring a new delegate
type for each event. For example, in the following example, three hidden
delegate types are created, even though all three events have the same
parameter list:Public Class Button
Public Event Click(sender As Object, e As System.EventArgs)
Public Event DoubleClick(sender As Object, e As System.EventArgs)
Public Event RightClick(sender As Object, e As System.EventArgs)
End Class
In the following example, the events simply use the same delegate, EventHandler
:Delegate Sub EventHandler(sender As Object, e As System.EventArgs)
Public Class Button
Public Event Click As EventHandler
Public Event DoubleClick As EventHandler
Public Event RightClick As EventHandler
End Class
Events can be handled in one of two ways: statically or
dynamically. Statically handling events is simpler and only requires a WithEvents variable and a Handles clause. In the following example, class Form1
statically
handles the eventClick
of object Button
:Imports System
Public Class Form1
Public WithEvents Button1 As Button = New Button()
Public Sub Button1_Click(sender As Object, e As System.EventArgs) _
Handles Button1.Click
Console.WriteLine("Button1 was clicked!")
End Sub
End Class
Dynamically handling events is more complex because the event must
be explicitly connected and disconnected to in code. The statement AddHandler
adds a
handler for an event, and the statement RemoveHandler
removes
a handler for an event. The next example shows a class Form1
that
adds Button1_Click
as an event handler for Button1
's Click
event:Imports System
Public Class Form1
Public Sub New()
' Add Button1_Click as an event handler for Button1's Click event.
AddHandler Button1.Click , AddressOf Button1_Click
End Sub
Private Button1 As Button = New Button()
Sub Button1_Click(sender As Object, e As EventArgs)
Console.WriteLine("Button1 was clicked!")
End Sub
Public Sub Disconnect()
RemoveHandler Button1.Click, AddressOf Button1_Click
End Sub
End Class
In method Disconnect
, the
event handler is removed.EventMemberDeclaration ::=
[ Attributes ] [ EventModifiers+ ] Event Identifier ParametersOrType
[ ImplementsClause ] LineTerminator
ParametersOrType ::=
[ ( [ ParameterList ] ) ] |
As TypeName
EventModifiers ::= AccessModifier | Shadows | Shared
5 Constants
A constant is a constant value that is a member of a
type. Constants are implicitly shared. If the declaration contains anAs clause, the clause specifies the type of
the member introduced by the declaration. If the type is omitted and strict
semantics are being used, a compile-time error occurs; otherwise the type of
the constant is implicitly Object. The
type of a constant may only be a primitive type or Object. If a constant is
typed as Object and there is no type character, the real
type of the constant will be the type of the constant expression. Otherwise,
the type of the constant is the type of the constant's type character.The following example shows a class named
Constants
that
has two public constants:Class Constants
Public A As Integer = 1
Public B As Integer = A + 1
End Class
Constants can be accessed through the class, as in the following
example, which prints out the values of Constants.A
and Constants.B
.Module Test
Sub Main()
Console.WriteLine(Constants.A & ", " & Constants.B)
End Sub
End Module
A constant declaration that declares multiple constants is
equivalent to multiple declarations of single constants. The following example
declares three constants in one declaration statement.Class A
Protected Const x As Integer = 1, y As Long = 2, z As Short = 3
End Class
This declaration is equivalent to the following:Class A
Protected Const x As Integer = 1
Protected Const y As Long = 2
Protected Const z As Short = 3
End Class
The accessibility domain of the type of the constant must be the
same as or a superset of the accessibility domain of the constant itself. The
constant expression must yield a value of the constant's type or of a type that
is implicitly convertible to the constant's type. The constant expression may
not be circular; that is, a constant may not be defined in terms of itself.The compiler automatically evaluates the constant declarations in the appropriate order. In the following example, the compiler first evaluates
Y
, then Z
, and finally X
, producing the values 10, 11, and 12, respectively.Class A
Public Const X As Integer = B.Z + 1
Public Const Y As Integer = 10
End Class
Class B
Public Const Z As Integer = A.Y + 1
End Class
When a symbolic name for a constant value is desired, but the type
of the value is not permitted in a constant declaration or when the value
cannot be computed at compile time by a constant expression, a read-only
variable may be used instead.ConstantMemberDeclaration ::=
[ Attributes ] [ ConstantModifier+ ] Const
ConstantDeclarators LineTerminator
ConstantModifier ::= AccessModifier | Shadows
ConstantDeclarators ::=
ConstantDeclarator |
ConstantDeclarators , ConstantDeclarator
ConstantDeclarator ::= Identifier [ As TypeName ] =
ConstantExpression LineTerminator
6 Instance and Shared Variables
An instance or shared variable is a member of a type that can
store information. The Dim modifier must be specified if no modifiers
are specified, but may be omitted otherwise. A single variable declaration may
include multiple variable declarators; each variable declarator introduces a
new instance or shared member. If an initializer is specified, only one
instance or shared variable may be declared by the variable declarator.A variable declared with the Shared modifier is a shared variable. A shared variable identifies exactly one storage location regardless of the number of instances of the type that are created. A shared variable comes into existence when a program begins executing, and ceases to exist when the program terminates.
A variable declared without the Shared modifier is called an instance variable. Every instance of a class contains a separate copy of all instance variables of the class. An instance variable of a reference type comes into existence when a new instance of that type is created, and ceases to exist when there are no references to that instance and theFinalize method has executed. An instance variable of a value type has exactly the same lifetime as the variable to which it belongs. In other words, when a variable of a value type comes into existence or ceases to exist, so does the instance variable of the value type.
If the declarator contains an As clause, the clause specifies the type of the members introduced by the declaration. If the type is omitted and strict semantics are being used, a compile-time error occurs. Otherwise the type of the members is implicitly Object or the type of the members' type character.
Note There is no ambiguity in the syntax: if a
declarator omits a type, it will always use the type of a following declarator.
The accessibility domain of an instance or shared variable's type
or array element type must be the same as or a superset of the accessibility
domain of the instance or shared variable itself.The following example shows a
Color
class
that has internal instance variables named redPart
, greenPart
, andbluePart
:Class Color
Friend redPart As Short
Friend bluePart As Short
Friend greenPart As Short
Public Sub New(red As Short, blue As Short, green As Short)
redPart = red
bluePart = blue
greenPart = green
End Sub
End Class
VariableMemberDeclaration ::=
[ Attributes ] [ VariableModifier+ ] [ Dim ] VariableDeclarators
LineTerminator
VariableModifier ::=
AccessModifier |
Shadows |
Shared |
ReadOnly |
WithEvents
VariableDeclarators ::=
VariableDeclarator |
VariableDeclarators , VariableDeclarator
VariableDeclarator ::=
VariableIdentifiers [ As TypeName ] |
VariableIdentifier [ As [ New ] TypeName [ ( ArgumentList ) ] ]
[ = VariableInitializer ]
VariableIdentifiers ::=
VariableIdentifier |
VariableIdentifiers , VariableIdentifier
VariableIdentifier ::= Identifier [ ArrayNameModifier ]
7 Properties
Properties are a
natural extension of variables; both are named members with associated types,
and the syntax for accessing variables and properties is the same. Unlike
variables, however, properties do not denote storage locations. Instead,
properties have accessors,
which specify the statements to execute in order to read or write their values.Properties are defined with property declarations. The first part of a property declaration resembles a field declaration. The second part includes a Get accessor and/or a Set accessor. In the example below, the
Button
class
defines aCaption
property.Public Class Button
Private captionValue As String
Public Property Caption() As String
Get
Return captionValue
End Get
Set (ByVal Value As String)
captionValue = value
Repaint()
End Set
End Property
End Class
Based on the Button
class above, the following is an example
of use of the Caption
property:Dim okButton As Button = New Button()
okButton.Caption = "OK" ' Invokes Set accessor.
Dim s As String = okButton.Caption ' Invokes Get accessor.
Here, the Set accessor is invoked by assigning a value
to the property, and the Get accessor is invoked by referencing the
property in an expression.If no type is specified for a property and strict semantics are being used, a compile-time error occurs; otherwise the type of the property is implicitly Object or the type of the property's type character. A property declaration may contain either a Get accessor, which retrieves the value of the property, a Set accessor, which stores the value of the property, or both. Because a property implicitly declares methods, a property may be declared with the same modifiers as a method. If the property is defined in an interface or defined with the MustOverride modifier, the property body and theEnd construct must be omitted; otherwise, a compile-time error occurs.
The index parameter list makes up the signature of the property, so properties may be overloaded on index parameters but not on the type of the property. The index parameter list is the same as for a regular method. However, none of the parameters may be modified with the ByRef modifier and none of them may be named
Value
(which
is reserved for the implicit value parameter in the Set accessor).A property may be declared as follows:
- If the property specifies no
property type modifier, the property must have both a Get accessor and
a Setaccessor. The
property is said to be a read-write property.
- If the property specifies the ReadOnly modifier, the
property must have a Get accessor and
may not have a Setaccessor. The
property is said to be read-only property. It is a compile-time error for
a read-only property to be the target of an assignment.
- If the property specifies the WriteOnly modifier, the
property must have a Set accessor and
may not have a Getaccessor. The
property is said to be write-only property. It is a compile-time error to
reference a write-only property in an expression except as the target of
an assignment or as an argument to a method.
Class A
Private nameValue As String
' Error, contains a duplicate member name.
Public ReadOnly Property Name() As String
Get
Return nameValue
End Get
End Property
' Error, contains a duplicate member name.
Public WriteOnly Property Name() As String
Set (ByVal Value As String)
nameValue = value
End Set
End Property
End Class
Since two members declared in the same class cannot have the same
name, the example causes a compile-time error.When a derived type shadows a property, the derived property hides the shadowed property with respect to both reading and writing. In the following example, the
P
property in B
hides
the P
property in A
with
respect to both reading and writing:Class A
Public WriteOnly Property P() As Integer
Set (ByVal Value As Integer)
End Set
End Property
End Class
Class B
Inherits A
Public Shadows ReadOnly Property P() As Integer
Get
End Get
End Property
End Class
Module Test
Sub Main()
Dim x As B = New B
B.P = 10 ' Error, B.P is read-only.
End Sub
End Module
The accessibility domain of the return type or parameter types
must be the same as or a superset of the accessibility domain of the property
itself. A property may only have one Set accessor and one Get accessor.Except for differences in declaration and invocation syntax, Overridable, NotOverridable, Overrides, MustOverride, and MustInherit properties behave exactly like Overridable, NotOverridable, Overrides, MustOverride, andMustInherit methods. When a property is overridden, the overriding property must be of the same type (read-write, read-only, write-only).
In the following example
X
is an Overridable read-only property, Y
is an Overridable read-write property, and Z
is aMustOverride read-write property.MustInherit Class A
Private y As Integer
Public Overridable ReadOnly Property X() As Integer
Get
Return 0
End Get
End Property
Public Overridable Property Y() As Integer
Get
Return y
End Get
Set (ByVal Value As Integer)
y = value
End Set
End Property
Public MustOverride Property Z() As Integer
End Class
Because Z
is MustOverride, the
containing class A
must be declared MustInherit.By contrast, a class that derives from class
A
is
shown below:Class B
Inherits A
Private zValue As Integer
Public Overrides ReadOnly Property X() As Integer
Get
Return MyBase.X + 1
End Get
End Property
Public Overrides Property Y() As Integer
Get
Return MyBase.Y
End Get
Set (ByVal Value As Integer)
If value < 0 Then
MyBase.Y = 0
Else
MyBase.Y = Value
End If
End Set
End Property
Public Overrides Property Z() As Integer
Get
Return zValue
End Get
Set (ByVal Value As Integer)
zValue = Value
End Set
End Property
End Class
Here, the declarations of properties X, Y
, and Z
override the base properties. Each
property declaration exactly matches the accessibility modifiers, type, and
name of the corresponding inherited property. The Get accessor of property X
and
the Set accessor of property Y
use
the MyBase keyword to access the inherited
properties. The declaration of property Z
overrides
the MustOverride property — thus, there are no outstanding MustOverridemembers
in class B
, and B
is
permitted to be a regular class.Properties can be used to delay initialization of a resource until the moment it is first referenced. For example:
Imports System.IO
Public Class ConsoleStreams
Private Shared reader As TextReader
Private Shared writer As TextWriter
Private Shared errors As TextWriter
Public Shared ReadOnly Property [In]() As TextReader
Get
If reader Is Nothing Then
reader = New StreamReader(File.OpenStandardInput())
End If
Return reader
End Get
End Property
Public Shared ReadOnly Property Out() As TextWriter
Get
If writer Is Nothing Then
writer = New StreamWriter(File.OpenStandardOutput())
End If
Return writer
End Get
End Property
Public Shared ReadOnly Property [Error]() As TextWriter
Get
If errors Is Nothing Then
errors = New StreamWriter(File.OpenStandardError())
End If
Return errors
End Get
End Property
End Class
The ConsoleStreams
class contains three properties, In
, Out
, and Error
, that represent the standard input, output, and error devices,
respectively. By exposing these members as properties, the ConsoleStreams
class
can delay their initialization until they are actually used. For example, upon
first referencing the Out
property, as inConsoleStreams.Out.WriteLine("hello,
world")
, the underlying TextWriter
for the output device is created. But if
the application makes no reference to the In
and Error
properties,
then no objects are created for those devices.PropertyMemberDeclaration ::=
[ Attributes ] [ PropertyModifier+ ] Property Identifier
[ ( [ ParameterList ] ) ] [ As TypeName ] [ ImplementsClause ]
LineTerminator
[ PropertyAccessorDeclaration+ ]
[ End Property LineTerminator ]
PropertyModifier ::= ProcedureModifier | Default | ReadOnly | WriteOnly
PropertyAccessorDeclaration ::=
PropertyGetDeclaration |
PropertySetDeclaration
Objects, Properties, Methods, and Events
Objects, properties, methods, and events are the basic units of
object-oriented programming. An object is an element of an application,
representing an instance of a class. Properties, methods, and
events are the building blocks of objects, and constitute their members.
Objects
An object represents an instance of a class such as Form, Control, or Component. In
Visual Basic code, you mustinstantiate an object before you can apply one of the
object's methods or change the value of one of its properties. Instantiation is
the process by which an instance of a class is created and assigned to an
object variable. An example is shown below:Dim x As New MyClass()
In this example, the variable x
is
assigned to refer to a new instance of the class MyClass
.
Properties
A property is an attribute of an object that defines one of the
object's characteristics, such as size, color, or screen location, or an aspect
of its behavior, such as whether it is enabled or visible. To change the
characteristics of an object, you change the values of its corresponding
properties.To set the value of a property, affix the reference to an object with a period, the property name, an equal sign (=), and the new property value. For example, the following procedure changes the caption of a Visual Basic Windows Form by setting the Text property:
Public Sub ChangeName(newTitle)
myForm.Text = newTitle
End Sub
You can't set some properties. The Help topic for each property
indicates whether you can set that property (read/write), only read the
property (read-only), or only write the property (write-only).You can retrieve information about an object by returning the value of one of its properties. The following procedure uses a message box to display the title that appears at the top of the currently active form.
Public Sub GetFormName()
Dim formName As String
formName = myForm.Text
MsgBox(formName)
End Sub
Methods
A method is an action that an object can perform. For example, Add is a method of the ComboBox object, because it adds a new entry to a
combo box.The following example demonstrates the Start method of a Timer component:
' Instantiates a Timer object.
Dim myTimer As New System.Windows.Forms.Timer()
' Invokes the Start method of myTimer.
MyTimer.Start
No comments:
Post a Comment