VB 2010 (18)从子类中引发事件

        子类可以访问其基类中的事件,但子类中的代码不能引发该事件。可以在基类中实现一个Protected方法,允许任何派生类引发该方法。

基类

Public Class Person
    Private mName As String
    Private mBirthDate As Date
    Private mID As String

    Public Event NameChanged(ByVal newName As String)
    '供子类引用
    Protected Sub OnNameChanged(ByVal newName As String)
        RaiseEvent NameChanged(newName)
    End Sub

    Public Event DataChanged(ByVal field As String, ByVal newValue As Object)
    Protected Sub OnDataChanged(ByVal field As String, ByVal newValue As Object)
        RaiseEvent DataChanged(field, newValue)
    End Sub

    '可重写的方法
    Public Overridable Property Name() As String
        Get
            Return mName
        End Get
        Set(ByVal value As String)
            mName = value
            '改名事件
            RaiseEvent NameChanged(mName)
        End Set
    End Property

    '可重写的方法
    Public Overridable Property BirthDate() As Date
        Get
            Return mBirthDate
        End Get
        Set(ByVal value As Date)
            mBirthDate = value
            RaiseEvent DataChanged("BirthData", value)
        End Set
    End Property
    '用于继承
    Protected Property Identity As String
        Get
            Return mID
        End Get
        Set(ByVal value As String)
            mID = value
        End Set
    End Property

    '这里是一个有意的错误,年龄是一个负数.用来测试Shadows
    Public ReadOnly Property age() As Integer
        Get
            Return CInt(DateDiff(DateInterval.Year, Now, BirthDate))
        End Get
    End Property

    Public Overrides Function ToString() As String
        Return Me.Name
    End Function

    Public Sub New(ByVal name As String)
        Me.Name = name
        Debug.WriteLine("Person constructor")
    End Sub
End Class
一层派生

Public Enum NameTypes
    Informal = 1
    Formal = 2
    Normal = 3
End Enum
Public Class Employee
    Inherits Person

    '子类属性
    Public Property HireDate As Date
    Private Property mSalary As Double

    'Private mName As String

    '重写BirthDate
    Public Overrides Property BirthDate() As Date
        Get
            Return MyBase.BirthDate
        End Get
        Set(ByVal value As Date)
            If DateDiff(DateInterval.Year, value, Now) > 16 Then
                MyBase.BirthDate = value
            Else
                'Throw New ArgumentException("An employee must be at least 16 years old.")
                MsgBox("An employee must be at least 16 years old.")
            End If
            'OnDataChanged("BirthDate", value)
        End Set
    End Property

    '重载基类Name属性
    'Dictionary<TKey,TValue> 泛型类提供一组键到一组值的映射。 每次对字典的添加都包含一个值和与其关联的键。
    'TKey,字典中的键的类型。
    'TValue,字典中的值的类型。
    Private mNames As Dictionary(Of NameTypes, String)

    'Name属性是一个属性数组,允许在同一个属性中存储多个值.
    Public Overloads Property Name(ByVal type As NameTypes) As String
        Get
            If mNames Is Nothing Then mNames = New Dictionary(Of NameTypes, String)
            Return mNames(type)
        End Get
        Set(ByVal value As String)
            If mNames Is Nothing Then mNames = New Dictionary(Of NameTypes, String)
            If mNames.ContainsKey(type) Then
                mNames.Item(type) = value
            Else
                mNames.Add(type, value)
            End If

            If type = NameTypes.Normal Then
                MyBase.Name = value
            End If


        End Set
    End Property

    '用Overrides关键字来表明重写基类中的Name方法,使用Overloads关键字来表明在子类中重载这个方法。
    Public Overloads Overrides Property Name() As String
        Get
            If mNames Is Nothing Then mNames = New Dictionary(Of NameTypes, String)
            Return mNames(NameTypes.Normal)
        End Get
        Set(ByVal value As String)
            If mNames Is Nothing Then
                mNames = New Dictionary(Of NameTypes, String)
            Else
                mNames(NameTypes.Normal) = value

                OnNameChanged(mNames(NameTypes.Normal))

            End If
        End Set
    End Property

    '遮蔽方法
    Public Shadows Property age() As Integer
        Get
            Return CInt(DateDiff(DateInterval.Year, BirthDate, Now))
        End Get
        Set(ByVal value As Integer)
            BirthDate = DateAdd(DateInterval.Year, -value, Now)
        End Set
    End Property

    Public Property EmployeeNumber As Integer
        Get
            Return CInt(Identity)
        End Get
        Set(ByVal value As Integer)
            Identity = CStr(value)
        End Set
    End Property

    Public Property Salary() As Double
        Get
            Return mSalary
        End Get
        Set(ByVal value As Double)
            mSalary = value

            OnDataChanged("Salary", mSalary)

        End Set
    End Property
    Sub New(ByVal name As String)
        MyBase.new(name)
        Debug.WriteLine("Employee constructor")
    End Sub
End Class
二层派生

Public Class OfficeEmployee
    Inherits Employee
    Private mOffice As String


    Public Property OfficeNumber() As String
        Get
            Return mOffice
        End Get
        Set(ByVal value As String)
            mOffice = value
        End Set
    End Property

    Public Overloads Property Name() As String
        Get
            Return MyBase.Name(NameTypes.Informal)
        End Get
        Set(ByVal value As String)
            MyBase.Name = value

            OnNameChanged(MyBase.Name)
        End Set
    End Property

    'Public Shadows Property Name() As String
    'Get
    'Return MyBase.Name(NameTypes.Informal)
    'End Get
    'Set(ByVal value As String)
    'MyBase.Name = value
    'End Set
    'End Property


    Sub New(ByVal name As String)
        MyBase.New(name)
        Debug.WriteLine("OfficeEmployee constructor")
    End Sub

End Class

客户端

客户端代码

Public Class Form1

    Private Sub btnOk_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOk.Click
        '1.这里把变量声明为Person类型,但是对象却是Employee类的—个实例。

        'Dim person As Person
        'person = New Employee()

        '2.
        'Dim person As Employee
        'person = New Person

        '3.,通过这个对象可以调用Employee类的任意方法,包括从Person类中继承来的方法.
        'Dim person As OfficeEmployee = New OfficeEmployee("Mary")  

        'Dim person As Person = New Person("Mary")

        Dim person As Employee = New Employee("Mary")
        'Dim person As OfficeEmployee = New OfficeEmployee("Mary")

        AddHandler person.NameChanged, AddressOf OnNameChanged

        AddHandler person.DataChanged, AddressOf OnDataChanged

        With person
            .Name = "Fred"
            .BirthDate = #11/1/2001#
            '.age = 20

            '.OfficeNumber = "A42"

            '所以编译有错误, 不可以用子类方法
            .Name(NameTypes.Formal) = "Mr.Frederick R.Jones,Sr."
            .Name(NameTypes.Informal) = "Freddy"
            .HireDate = #1/1/2020#
            .Salary = 30000

            txtName.Text = .ToString '.Name
            txtBirthDate.Text = Format(.BirthDate, "Short date")
            txtAge.Text = CStr(.age)
            'txtOffice.Text = .OfficeNumber

            'DisplayPerson(person)


            txtFomal.Text = .Name(NameTypes.Formal)
            txtInfomal.Text = .Name(NameTypes.Informal)
            txtHireDate.Text = Format(.HireDate, "Short date")
            txtSalary.Text = Format(.Salary, "$0.00")
        End With

    End Sub
    '通用例程
    'Private Sub DisplayPerson(ByVal thePerson As Person)
    Private Sub DisplayPerson(ByVal thePerson As Employee)
        'Private Sub DisplayPerson(ByVal thePerson As OfficeEmployee) 'age属性会用遮蔽方法
        With thePerson
            txtName.Text = .ToString '.Name
            txtBirthDate.Text = Format(.BirthDate, "Short date")
            txtAge.Text = CStr(.age)
            'txtOffice.Text = .OfficeNumber
        End With
    End Sub

    '处理改名事件
    Private Sub OnNameChanged(ByVal newName As String)
        MsgBox("New name:" & newName)
    End Sub
    '处理生日或薪水改变事件
    Private Sub OnDataChanged(ByVal field As String, ByVal newValue As Object)
        MsgBox(field & ":" & newValue)
    End Sub

   
End Class
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ngbshzhn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值