Các bài tập Microsoft .NET

Keyword MyBase

Keyword Me rất tiện dụng khi ta muốn dùng Class members của chính

Class chứa code. Tương tự như vậy, đôi khi ta muốn dùng Class method

của BaseClass (cũng gọi là SuperClass), chớ không phải một

implementation của method ấy trong SubClass. Nhớ là một virtual

method luôn luôn gọi implementation của Class trẻ nhất.

Từ trong một SubClass, nếu muốn gọi một method của BaseClass ta dùng

keyword MyBase như sau:

pdf174 trang | Chia sẻ: dungnc89 | Lượt xem: 3706 | Lượt tải: 0download
Bạn đang xem trước 20 trang mẫu tài liệu Các bài tập Microsoft .NET, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
tabase
 ' trong đó có thể có Description của Product
 End Sub
End Class
Statement Inherits LineItem khiến ProductLine thừa kế mọi interface và
behaviours của LineItem. Do đó ta có thể code một Sub
BtnProduct_Click để hiển thị chi tiết của ProductLine trong một Listbox
như sau:
Protected Sub BtnProduct_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles BtnProduct.Click
 Dim pl As ProductLine
 pl = New ProductLine("P1234")
 ListBox1.Items.Add("ProductItem:" & pl.Item)
 ListBox1.Items.Add("Description: $" & pl.Description)
Các bài tập Microsoft .NET 81
End Sub
Trong code bên trên ta dùng cả property Item của Class LineItem lẫn
property Description của Class ProductLine. Cả hai đều là property của
ProductLine vì nó là một SubClass của LineItem.
Giống như vậy, một ServiceLine có thể có ghi ngày giờ cung cấp service.
Ta code Class ServiceLine như sau:
Public Class ServiceLine
 Inherits LineItem
 Private mdtDateProvided As Date
 Public Sub New()
 ' Make 1 as default number of services of this kind for invoice
 Quantity = 1
 End Sub
 Public Property DateProvided() As Date
 Get
 Return mdtDateProvided
 End Get
 Set (ByVal Value As Date)
 mdtDateProvided = Value
 End Set
 End Property
End Class
Một lần nữa ta dùng Statement Inherits để nói rằng ServiceLine là một
SubClass của LineItem. Ta thêm property DateProvided vào interface
thừa kế từ Class LineItem.
Các bài tập Microsoft .NET 82
Bài 6
Những chức năng Đối Tượng mới của VB.NET
(phần III)
Dùng OO trong VB.NET
Ngăn cản Thừa kế
Bình thường (By default) class nào cũng có thể được dùng làm base class
để từ đó ta thừa kế. Nhưng đôi khi ta không muốn cho ai thừa kế từ một
Class nào đó, để làm việc ấy ta dùng keyword NotInheritable khi declare
class:
Public NotInheritable Class KhôngCon
End Class
Khi ta đã dùng keyword NotInheritable rồi thì không class nào có thể
dùng keyword Inherits để tạo một subclass từ class ấy.
Thừa kế và Phạm vi hoạt động
Khi ta dùng đặc tính thừa kế để tạo một SubClass thì class mới này có đủ
mọi methods, propertỉes và variables với Access Modifier Public hay
Friend của SuperClass. Bất cứ thứ gì declared là Private trong
SuperClass thì SubClass không thấy hay dùng được.
Có một ngoại lệ là New method. Các Constructor methods cần phải được
implemented (định nghĩa)
lại trong mỗi SubClass. Một chốc nữa ta sẽ bàn vào chi tiết về điểm này.
Để làm sáng tỏ vấn đề SubClass có thể dùng Class Members nào của
SuperClass, ta thử code lại Function Amount trong LineItem class bằng
cách khiến nó gọi một Private Function tên CalculateAmount để tính ra
Amount thay vì để nó tính trực tiếp như trước đây:
Public Function Amount() As Single
 Return CalculateAmount
End Function
Các bài tập Microsoft .NET 83
Private Function CalculateAmount() As Single
 Return mintQuantity * msngPrice
End Function
Khi ta SubClass LineItem để tạo ra ServiceLine class, bất cứ Object
ServiceLine nào cũng thừa kế Function Amount vì Function ấy được
declared Public trong BaseClass LineItem. Ngược lại, vì Function
CalculateAmount là Private nên cả ServiceLine class lẫn bất cứ client
code nào dùng một LineItem Object đều không truy cập nó được.
Như thế, mặc dầu ta gọi Function Amount được, nhưng đến phiên nó gọi
Private Function CalculateAmount thì có bị trở ngại không? Không sao
cả. Vì Function Amount nằm trong cùng Class với Private Function
CalculateAmount nên nó có thể gọi được, dù rằng ta gọi Function
Amount từ ServiceLine hay client code.
Thí dụ trong client code ta có những hàng code như sau:
Protected Sub BtnShowAmount_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles BtnShowAmount.Click
 Dim Service As ServiceLine
 Service = New ServiceLine()
 Service.Item = "Delivery"
 Service.Price = 50
 Service.DateProvided = Now
 MessageBox.Show (Service.Amount.ToString, "Amount", MessageBoxButtons.OK,
MessageBoxIcon.Information)
End Sub
Kết quả sẽ được hiển thị trong message box, cho thấy Function
CalculateAmount được Function Amount gọi dùm cho client code dù
rằng cả client code lẫn ServiceLine code đều không thể gọi trực tiếp
được.
Điểm này nhắc tôi nhớ lại khi còn bé, có lần bà con trong vườn đem ra
chợ cho ba má tôi cả thúng xoài thơm rất ngon. Bạn tôi ở lối xóm thấy
Các bài tập Microsoft .NET 84
vậy biểu tôi lén lấy hai trái xoài để ăn vụn. Vì không phải là người nhà
nên bạn tôi không thể lấy đuợc xoài, bởi Access Modifier của thún xoài là
Private trong nhà tôi. Nhưng vì tôi là Public, nên bạn tôi có thể nhờ tôi
lấy dùm.
Protected Methods
Đôi khi Public hay Private thôi chưa đủ. Nếu ta declare thứ gì Private thì
nó hoàn toàn giới hạn trong class, ngược lại nếu ta declare nó Public (hay
Friend) thì nó có thể được dùng trong subclasses hay client code.
Tuy nhiên, có lúc ta muốn một class member chỉ có thể được dùng trong
subclasses thôi, chớ không cho client code dùng. Trong trường hợp ấy ta
dùng keyword Protected. Thí dụ:
Public Class FatherClass
 Protected DiSản As Single
End Class
Public Class SonClass
 Inherits FatherClass
 Public Function ChiaCủa() As Single
 Return Disản
 End Function
End Class
Ở đây ta có BaseClass FatherClass với Protected Field Disản. Không
có client code nào có thể thấy Field DiSản được. Thế nhưng bất cứ
SubClass nào của FatherClass cũng đều thừa kế và dùng được DiSản.
Trong thí dụ trên, một lần nữa SubClass có một Public method (ChiaCủa)
có thể return một protected value - nhưng chính value ấy, DiSản, không
trực tiếp cho phép client code dùng.
Overriding Methods
Chúng ta biết rằng đặc tính quan trọng của Inheritance là một SubClass
chẳng những thừa kế behaviours của ParentClass mà còn có thể override
Các bài tập Microsoft .NET 85
(lấn quyền) các behaviours ấy nữa. Chúng ta đã thấy một SubClass có thể
extend (thêm ra) ParentClass bằng cách cho thêm các methods Public,
Protected và Friend. Hơn nữa, khi dùng overriding, một SubClass có thể
alter (sửa đổi) behaviours của các methods trong ParentClass.
Bình thường (By default), ta không thể override methods trong
ParentClass trừ khi các methods ấy được declared với keyword
Overridable trong ParentClass. Thí dụ:
Public Class ClassCha
 Public Overridable Sub ChàoHỏi()
 MessageBox.Show("Chào các cháu", "Class Cha")
 End Sub
End Class
Tiếp theo, khi tạo một SubClass, nếu muốn ta có thể override behaviour
của Sub ChàoHỏi bằng cách dùng keyword Overrides như sau:
Public Class ClassCon
 Inherits ClassCha
 Public Overrides Sub ChàoHỏi()
 MessageBox.Show("Thưa các Bác", "Class Con")
 End Sub
End Class
Bây giờ ta có thể viết client code như sau:
Private Sub BtnSubClassObject_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles BtnSubClassObject.Click
 Dim obj As New ClassCon()
 obj.ChàoHỏi()
End Sub
Khi ta click button BtnSubClassObject program sẽ hiển thị message
dialog dưới đây:
Các bài tập Microsoft .NET 86
Virtual Methods
Tuy nhiên, hãy xem trường hợp ta code như sau:
Private Sub BtnParentClassObject_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles BtnParentClassObject.Click
 Dim obj As ClassCha
 obj = New ClassCon()
 obj.ChàoHỏi()
End Sub
Trước hết, ở đây có vẻ kỳ kỳ, tại sao declare một variable loại ClassCha
mà lại instantiate một object ClassCon. Chuyện đó hoàn toàn bình
thường, vì ClassCon là một ClassCha. Tức là một variable loại ClassCha
hay ClassCon đều có thể chứa, thật ra là hold references to (point to, chỉ
tới), một instance của ClassCon.
Điểm này áp dụng tổng quát khi ta dùng Inheritance. Một variable loại
SuperClass có thể hold reference to bất cứ SubClass Object nào thừa kế
từ SuperClass ấy. Đó là một cách để ta implement tính đa dạng
(polymorphism).
Đều có thể làm ta ngạc nhiên là khi ta click button BtnParentClassObject
ta cũng thấy hiển thị message " Thưa các Bác".
Các bài tập Microsoft .NET 87
Sao lạ vậy? Variable obj được declared là ClassCha tại sao message
không phải là "Chào các cháu"? Lý do là Sub ChàoHỏi của ClassCon
được gọi thay vì Sub ChàoHỏi của ClassCha. Ta nói Sub ChàoHỏi là
Virtual method. Tất cả methods trong VB.NET đều là virtual.
Ý niệm virtual để nói rằng cái implementation của con cháu trẻ nhất
trong dòng họ được dùng - không cần biết là variable có data type là
class của thế hệ nào trong dòng họ. Tức là, nếu variable dùng trong client
code hold references to ClassÔngNội, ClassCha, ClassCon hay
ClassCháu thì method trong ClassCháu được gọi. Nếu trong ClassCháu
không có implementation của method thì ta gọi method trong ClassCon,
nếu không có thì gọi method trong ClassCha .v.v.. theo thứ tự từ bề dưới
lên bề trên.
Keyword Me
Keyword Me được dùng khi ta muốn nói rõ (explicitly) rằng ta muốn
dùng method của chính cái Class đang chứa code ấy, chớ không phải một
implementation nào khác của method ấy.
Cũng có trường hợp ta phải dùng keyword Me để nói ta muốn dùng class-
level variable chớ không phải procedure-level variable có cùng tên. Một
procedure-level variable, tức là local variable của một method, có cùng
tên với một class-level variable được gọi là shadowed variable. Thí dụ:
Public Class TheClass
 Private strName As String
 Public Sub DoSomething()
 Dim strName As String
Các bài tập Microsoft .NET 88
 strName = "Quang"
 End Sub
End Class
Ở đây, variable strName được declared ở class-level và bên trong Sub
DoSomething. Bên trong method ấy local variables (kể cả shadowed
variables) sẽ được dùng vì chúng che đậy class-level variables trừ khi ta
nói rõ rằng phải dùng variable của class-level bằng cách dùng keyword
Me:
Public Class TheClass
 Private strName As String
 Public Sub DoSomething()
 Dim strName As String
 strName = "Quang" ' thay đổi value của local (shadowed) variable
 Me.strName = "Kim" ' thay đổi value của class-level variable
 End Sub
End Class
Keyword MyBase
Keyword Me rất tiện dụng khi ta muốn dùng Class members của chính
Class chứa code. Tương tự như vậy, đôi khi ta muốn dùng Class method
của BaseClass (cũng gọi là SuperClass), chớ không phải một
implementation của method ấy trong SubClass. Nhớ là một virtual
method luôn luôn gọi implementation của Class trẻ nhất.
Từ trong một SubClass, nếu muốn gọi một method của BaseClass ta dùng
keyword MyBase như sau:
Public Class ClassCon
 Inherits ClassCha
 Public Overrides Sub ChàoHỏi()
 MessageBox.Show("Thưa các Bác", "Class Con")
 MyBase.ChàoHỏi()
 End Sub
Các bài tập Microsoft .NET 89
End Class
Bây giờ nếu ta chạy Sub ChàoHỏi của ClassCon ta sẽ có hai messages,
một cái từ ClassCon theo sau bởi một cái từ ClassCha.
MyBase chỉ nói đến BaseClass trực tiếp, tức là Class cha thôi chớ không
nói đến Class ông nội. Không có cách nào để nói đến hơn một thế hệ.
Dầu vậy, keyword Mybase có thể được dùng cho bất cứ thứ gì đã được
declared Public, Friend hay Protected trong ParentClass. Điều này kể
luôn cả những thứ mà ParentClass thừa kế từ các thế hệ trước trong gia
đình, tức là ClassÔngNội, ClassÔngCố .v.v..
Keyword MyClass
Vì lý do virtual method, ta sẽ gặp những trường hợp rắc rối như khi code
của ParentClass lại chạy code của SubClasses.
Khi viết code của một class, từ method này ta thường gọi những methods
khác nằm trong cùng class. Thí dụ như:
Public Class ClassCha
 Public Sub VôĐề()
 ChàoHỏi()
 End Sub
 Public Overridable Sub ChàoHỏi()
 MessageBox.Show("Chào các cháu", "Class Cha")
 End Sub
End Class
Trong trường hợp này, VôĐề gọi Sub ChàoHỏi để đón tiếp. Để ý là vì
ChàoHỏi được declared Overridable nên rất có thể một SubClass sẽ
implement method ChàoHỏi và lấn quyền nó. Thí dụ:
Public Class ClassCon
 Inherits ClassCha
 Public Overrides Sub ChàoHỏi()
 MessageBox.Show("Thưa các Bác", "Class Con")
Các bài tập Microsoft .NET 90
 End Sub
End Class
Vì đặc tính virtual của ChàoHỏi nên ta tưởng ClassCha execute chính Sub
ChàoHỏi của nó nhưng té ra nó lại execute code của ChàoHỏi trong
ClassCon. Trong code dưới đây, một Object ClassCon gọi Sub VôĐề của
ClassCha:
Private Sub BtnSubClassObject_Click(ByVal sender As System.Object, _
 ByVal e As System.EventArgs) Handles BtnSubClassObject.Click
 Dim obj As New ClassCon()
 obj.VôĐề()
End Sub
Trong ClassCha, Sub VôĐề gọi ChàoHỏi của chính nó, tuy nhiên Sub
ChàoHỏi ấy bị overridden bởi implementation của ChàoHỏi trong
ClassCon. Do đó, program sẽ hiển thị message "Thưa các Bác".
Nếu ta không muốn như vậy, ta muốn VôĐề execute chính code của
ChàoHỏi trong ClassCha thì phải dùng keyword MyClass như sau:
Public Class ClassCha
 Public Sub VôĐề()
 MyClass.ChàoHỏi()
 End Sub
 Public Overridable Sub ChàoHỏi()
 MessageBox.Show("Chào các cháu", "Class Cha")
 End Sub
End Class
Ở đây ta không thể dùng keyword Me vì VôĐề có gọi ChàoHỏi ở class-
level trong ClassCha chớ không phải trong một SubClass, nhưng bị
overridden. Hình dưới đây minh họa quá trình gọi VôĐề từ client code:
Các bài tập Microsoft .NET 91
Sub VôĐề thật ra nằm trong ClassCha mà ClassCon thừa kế nên VôĐề
được executed trong ClassCha và gọi Sub ChàoHỏi trong cùng class (
ClassCha). Nhưng vì ClassCon có một implementation của Sub ChàoHỏi
nên nó overrides ChàoHỏi của ClassCha.
Overridding Method New
Chúng ta đã thấy ta có thể override methods và dùng các keywords Me,
MyBase và MyClass để gọi các overriden methods trong dây chuyền thừa
kế. Tuy nhiên, đối với Constructor của class thì có những luật lệ đặc biệt
dành riêng cho method New.
Những methods New không tự động di truyền từ BaseClass xuống
SubClass. Mỗi SubClass phải có một implementation riêng cho
Constructor dù rằng, nếu muốn, nó có thể gọi vào BaseClass với keyword
MyBase:
Public Class ClassCon
 Inherits ClassCha
 Public Sub New()
 MyBase.New()
 ' để thêm các code khác để initialise tại đây
 End Sub
End Class
Các bài tập Microsoft .NET 92
Khi gọi Constructor của BaseClass, ta phải gọi nó trước nhất - nếu không
sẽ bị error. Tuy nhiên ta không cần gọi Constructor của BaseClass vì
Constructor của BaseClass được gọi tự động.
Có một luật đặc biệt là nếu tất cả methods New trong BaseClass đều đòi
hỏi parameters thì ta phải implement ít nhất một method New trong
SubClass và ta phải đặt statement MyBase.New ngay phía đầu.
Dĩ nhiên là ta có thể Overload method New trong SubClass, nhưng ta
phải tự lo liệu cách gọi một method New thích hợp trong BaseClass.
Tạo BaseClasses và Abstract Methods
Cho đến giờ ta đã bàn về virtual method với đặc tính override trong
nguyên tắc thừa kế. Trong các thí dụ trước đây BaseClass được
instantiated thành Object để làm chuyện này, chuyện kia. Nhưng đôi khi
ta muốn tạo một BaseClass chỉ để dùng cho thừa kế mà thôi.
Keyword MustInherit (Phải được Thừa Kế)
Trở lại cái thí dụ về Inheritance với Class LineItem. Sở dĩ ta đặt ra Class
LineItem là vì nó chứa những thứ chung cho cả hai classes ProductLine
và ServiceLine. Chớ thật ra một Object của Class LineItem không chứa
đủ mọi đặc tính để làm một việc gì thực tế. Nếu ta muốn nói rõ rằng Class
LineItem chỉ được dùng để tạo những SubClasses bằng cách thừa kế từ
nó, ta có thể declare như sau:
Public MustInherit Class LineItem
Tức là ta chỉ thêm keyword MustInherit thôi, chớ không thay đổi gì
khác. Kết quả là từ nay Client code không thể instantiate một Object từ
Class LineItem. Do đó dòng code sau sẽ bị syntax error:
Dim myObject As New LineItem()
Thay vào đó, nếu muốn dùng LineItem ta phải tạo SubClass từ nó.
Keyword MustOverride (Phải bị Lấn Quyền)
Tương tự với ý niệm Phải-được-thừa-kế trong Class, ta cũng có
MustOverride cho một method. Có thể trong BaseClass ta khai báo một
method, nhưng ta đòi hỏi method ấy phải có một implementation trong
SubClass. Ta declare như sau:
Các bài tập Microsoft .NET 93
Dim MustOverride Sub CalculatePrice
Để ý là ở đây không có thân thể của Sub CalculatePrice hay statement
End Sub gì cả. Khi dùng MustOverride ta không được phép cung cấp một
implementation cho method trong BaseClass. Một method như thế được
gọi là abstract method hay pure virtual function, vì nó chỉ có phần
khai báo chớ không có phần định nghĩa. Những abstract methods phải
được overridden trong bất cứ SubClass nào của BaseClass thì mới dùng
được. Nếu không, ta sẽ không có phần implementation của method đâu cả
và khi compile sẽ gặp syntax error.
Abstract Base Classes
Nếu hợp cả hai ý niệm MustInherit và MustOverride lại ta sẽ tạo ra một
abstract base class. Đây là một Class chỉ có khai báo chớ hoàn toàn
không có implementation. Ta phải SubClass từ nó thì mới làm việc được,
thí dụ như:
Public MustInherit Class ClassCha
 Public MustOverride Sub VôĐề()
 Public MustOverride Sub ChàoHỏi()
End Class
Kỹ thuật này rất thích hợp để ta code cái sườn hay bố cục của program
ngay trong lúc thiết kế. Class nào thừa kế ClassCha thì phải implement
cả Sub VôĐề lẫn Sub ChàoHỏi, nếu không sẽ bị syntax error.
Nhìn về một phương diện, abstract base class rất giống khai báo Interface.
Nếu dùng Interface, chúng ta có thể khai báo như sau:
Public Interface ICha
 Sub VôĐề()
 Sub ChàoHỏi()
End Interface
Bất cứ class nào chịu implement interface ICha thì phải implement cả
Sub VôĐề lẫn Sub ChàoHỏi, nếu không sẽ bị syntax error - do đó, ta
thấy Interface rất giống một abstract base class.
Các bài tập Microsoft .NET 94
Sự khác biệt chính giữa abstract base class với Interface là ở chỗ thừa kế.
Khi ta tạo một class con bằng cách SubClass từ ClassCha, chính class con
ấy lại cũng có thể được SubClassed. Mấy class cháu này sẽ tự động thừa
kế VôĐề và ChàoHỏi từ class con.
Trong khi ấy nói về Interface, mỗi class phải tự implement ICha một cách
độc lập và phải cung cấp hai Subs VôĐề và ChàoHỏi của chính nó. Vì
thế, nếu ta không có ý định dùng lại code của các Subs khi ta tạo các
classes mới thì ta có thể dùng interface. Ngược lại nếu ta muốn dùng lại
code trong SubClass theo nguyên tắc thừa kế thì ta nên dùng abstract base
class.
Các bài tập Microsoft .NET 95
Bài 7
Những chức năng Đối Tượng mới của VB.NET
(phần IV)
Dùng OO trong VB.NET
Shared class members ( Các thành viên để dùng chung của class)
Mặc dù Object rất hiệu năng và hữu ích, có khi ta chỉ muốn truy cập các
variables hay methods của một class để làm việc mà không cần phải
instantiate một Object nào cả. Tức là y như trong quá khứ, khi viết VB6,
ta dùng các variables hay methods của một BAS Module. Đại khái giống
như thay vì ký giao kèo với một thầu (Object) để thực hiện một công
trình, ta chỉ muốn mướn thợ hay chuyên viên làm việc gia công ( gọi các
methods) thôi.
Shared Methods
Trong VB.NET chẳng những một Class có các methods và properties
thông thường như ta đã thấy - tức là những methods và properties của
một Object ta có thể dùng ngay sau khi Object ấy thành hình qua quá
trình instantiation - mà còn có các methods và properties ta có thể dùng
mà không cần phải tạo ra một instance nào từ Class. Chúng được gọi là
shared methods. ( Trong các ngôn ngữ lập trình khác các methods này
còn được gọi là static methods hay class methods).
Ta không thể truy cập một shared method qua một Object như method
bình thường, nhưng phải dùng trực tiếp tên của class. Thí dụ sau đây sẽ
minh họa điều này:
Public Class Math
 Shared Function Add( ByVal x As Single, ByVal y As Single) As Single
 Return x + y
 End Function
End Class
Sau khi định nghĩa Class Math, ta có thể dùng Shared Function Add
mà không cần instantiate một Object thuộc class Math như sau:
Các bài tập Microsoft .NET 96
Dim Result As Single
result = Math.Add(12.5, 36.8)
Để ý thay vì dùng một object variable ta dùng thẳng tên của class Math để
truy cập method Add. Với một method bình thường thì làm như thế sẽ bị
syntax error, nhưng trong trường hợp này thì không sao.
Ta cũng có thể overload shared methods, tức là có thể code nhiều shared
methods với cùng một tên nhưng có những parameter lists khác nhau.
Phạm vi hoạt động bình thường (Default Scope) của shared methods là
Public. Tuy nhiên ta có thể giới hạn việc truy cập chúng bằng cách dùng
những Acce

File đính kèm:

  • pdfMICROSOFT.pdf
Giáo án liên quan