logo

Dot Net-Bài 5-Những chức năng Đối Tượng mới của VB.NET (phần II)

Tham khảo tài liệu 'dot net-bài 5-những chức năng đối tượng mới của vb.net (phần ii)', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả
Bài 5 Những chức năng Đối Tượng mới của VB.NET (phần  II) Dùng OO trong VB.NET Tạo một Class mới Class Keyword Trong một .vb file ta có thể viết nhiều Classes, code của mỗi Class nằm trong một  Class ... End Class block. Thí dụ: Public Class TheClass Public Sub Greeting() MessageBox.Show("Hello world", MsgBoxStyle.Information, "TheClass") End Sub End Class MessageBox.Show và MsgBoxStyle.Information trong VB.NET thay thế MsgBox và  vbInformation trong VB6.  Classes và Namespaces Nhắc lại là .NET dùng Namespace để sắp đặt các Classes cho thứ tự theo nhóm,  loại. Namespaces được declared với một Block Structure giống như sau: Namespace Vovisoft Public Class TheClass Public Sub Greeting() MessageBox.Show("Hello world", MsgBoxStyle.Information, "TheClass") End Sub End Class End Namespace Muốn nói đến bất cứ Class, Structure, hay thứ gì được declared bên trong một  Namespace...End Namespace block ta phải dùng tên Namespace trước. Thí dụ: Private myObject As Vovisoft.TheClass Một source file có thể chứa nhiều Namespaces, và bên trong mỗi Namespace lại có  thể có nhiều Classes. Ngoài ra, Classes thuộc về cùng một Namespace có thể nằm trong nhiều files khác  nhau trong một VB.NET project. Thí dụ ta có một source file với code như sau: Namespace Vovisoft Public Class TheClass ' Code End Class End Namespace Và một source file khác trong cùng project với code: Namespace Vovisoft Public Class TheOtherClass ' Code End Class End Namespace Vậy thì trong Namespace Vovisoft ta có hai Classes TheClass và TheOtherClass. Nhớ là, by default, Root Namespace của một VB.NET project là tên của project ấy.  Khi ta dùng Namespace block structure là chúng ta đang thêm một tầng tên vào Root  Namespace. Do đó, trong thí dụ trên nếu tên project là MyProject thì, từ bên ngoài  project ấy, ta có thể declare một variable như sau: Private myObject As MyProject.Vovisoft.TheClass Tạo ra Methods Methods trong VB.NET có hai thứ: Sub và Function. Function thì phải return một  kết quả. By default, parameters của Method là ByVal chớ không phải ByRef. Tức là  nếu muốn parameter nào ByRef thì phải nhớ khai ra rõ ràng. Nhắc lại là khi một variable được passed vào trong một method bằng ByVal thì  system cho method đó một copy (bản sao) của variable, do đó, trị số của variable  không bị thay đổi bởi công tác của method. Ngược lại, nếu một variable được passed  vào trong một method bằng ByRef thì method dùng chính variable đó, do đó, trị số  của variable có thể bị thay đổi bởi công tác của method. Ta có thể giới hạn việc sử dụng một method bằng cách áp đặt một Access Modifier  (sửa đổi quyền truy nhập) hay còn gọi là Scoping keyword (phạm vi hoạt động):  • Private ­ chỉ cho phép code trong cùng Class được gọi.  • Friend ­ chỉ cho phép code trong cùng project/component được  gọi.  • Public ­ cho phép ai gọi cũng được.  • Protected ­ cho phép code trong subclasses (classes con, cháu)  được gọi.  • Protected Friend ­ cho phép code trong cùng project/component  hay code trong subclasses được gọi.  Tạo ra Properties Trong VB.NET ta chỉ dùng một routine duy nhất cho mỗi Property, với hai chữ Get và  Set như sau (không còn dùng chữ Let của VB6 nữa): Private mdescription As String Public Property Description() As String Set (ByVal Value As String) mdescription = Value End Set Get Description = mdescription End Get End Property ReadOnly và WriteOnly property Bây giờ nếu Property là ReadOnly ta sẽ lấy phần Set ra và viết: Public ReadOnly Property Age() As Integer Get Age = 3 End Get End Property hay WriteOnly ta sẽ ấy phần Get ra và viết: Private _data As Integer Public WriteOnly Property Data() As Integer Set (ByVal Value As Integer) _data = Value End Set End Property Default Properties Default Property là property của Object mà program dùng khi ta chỉ cho tên của  Object và không nói rõ property nào. Thí dụ trong VB6 khi ta code: TextBox1 = "The house of rising sun" VB6 hiểu rằng ta muốn dùng Default Property text của Textbox1 nên code ấy tương  đương với: TextBox1.text = "The house of rising sun" Trong VB6 khi ta dùng keyword Set với tên của Object, thí dụ như: Dim myTextBox As Textbox Set myTextBox = TextBox1 program sẽ hiểu là ta muốn nói đến chính Object myTextBox . Nếu không thì nó biết  ta muốn nói đến Object Default Property mà làm biếng code cho rõ ra. Trong VB.NET Default Property phải là một Property array. Một Property array là một  property được Indexed (nói đến từng Item bằng con số Index) giống như một array. Lý  do chính của sự bắt buộc nầy là để khỏi lẫn lộn giữa hai trường hợp ta nói đến  Default property của một Object hay chính Object ấy, vì trong VB.NET ta không  còn dùng Set keyword cho Object assignment nữa (ta chỉ còn dùng keyword Set trong  Property mà thôi). Bây giờ hể muốn nói đến Default Property của Object thì phải dùng Index. Thí dụ để  nói đến chính Object, ta code: myValue = myObject để nói đến Default Property Item 3 của Object, ta code: myValue = myObject(3) Sự thay đổi từ VB6 nầy có nghĩa là một property array procedure phải nhận một  parameter. Thí dụ: Private theData(100) As String Default Public Property Data(ByVal Index As Integer) As String Get Data = theData(Index) End Get Set(ByVal Value As String) theData(Index) = Value End Set End Property Từ nay ta không thể code: TextBox1 = "Good morning!" như trong VB6 được nữa, mà phải code: TextBox1.text = "Good morning!" Vì Property Text không còn là Default Property của TextBox.  Overloading methods Một trong những chức năng đa diện (Polymorphism) hùng mạnh nhất của VB.NET là  overload (quá tải, có rồi mà còn cho thêm) một method. Overloading có nghĩa là ta có  thể dùng cùng một tên cho nhiều methods ­ miễn là chúng có danh sách các  parameters khác nhau, hoặc là parameter dùng data type khác nhau (td: method nầy  dùng Integer, method kia dùng String), hoặc là số parameters khác nhau (td: method  nầy có 2 parameters, method kia có 3 parameters). Overloading không thể được thực hiện chỉ bằng cách thay đổi data type của Return   value của Function. Phải có parameter list khác nhau mới được. Dưới đây là thí dụ ta dùng Overloading để code hai Functions tìm data, một cái cho  String, một cái cho Integer: Public Function FindData(ByVal Name As String) As ArrayList ' find data and return result End Function Friend Function FindData(ByVal Age As Integer) As ArrayList ' find data and return result End Function Để ý là ta có thể cho mỗi overloading Function một phạm vi hoạt động (Scope on  implementation) khác nhau. Trong thí dụ trên ta dùng Access Modifier Public cho  Function đầu và Friend cho Function sau. Object Lifecycle Object Lifecycle (cuộc đời của Object) được dùng để nói đến khi nào Object bắt đầu  hiện hữu và khi nào nó không còn nữa. Sờ dĩ ta cần biết rõ cuộc đời của một Object  bắt đầu và chấm dứt lúc nào là để tránh dùng nó khi nó không hiện hữu, tức là chưa ra  đời hay đã khuất bóng rồi.  New method Trong VB6, khi một Object thành hình thì Sub Class_Initialize được executed. Tương  đương như vậy, trong VB.NET ta có Sub New(), gọi là Constructor. VB.NET bảo  đảm Sub New() sẽ được CLR gọi khi Object được instantiated và nó chạy trước bất cứ  code nào trong Object. Nếu Sub Class_Initialize của một Class Object trong VB6 không nhận parameter thì  Sub New() trong VB.NET chẳng những có nhận parameters mà còn cho phép ta nhiều  cách để gọi nó. Sự khác biệt trong Constructors của VB6 và VB.NET rất quan trọng. Tưởng tượng ta có một Khuôn làm bánh bông lan; khuôn là Class còn những bánh  làm ra từ khuôn sẽ là các Objects bánh bông lan. Nếu ta muốn làm một cái bánh bông  lan với một lớp sô­cô­la trên mặt thì công tác sẽ gồm có hai bước:  1. Dùng khuôn (Class) nướng một cái Object bánh bông lan (dùng  Sub Class_Initialize)  2. Đổ lên mặt bánh một lớp sô­cô­la (dùng class Public Sub  ThoaSôcôla)  Đến đây, mọi chuyên tương đối ổn thỏa. Bây giờ, nếu khách hàng muốn một cái bánh  bông lan dùng trứng vịt thay vì trứng gà thì ta chịu thua thôi, vì không có cách nào bảo  Sub Class_Initialize dùng trứng vịt thay vì trứng gà ngay trong lúc đang tạo dựng ra  Object bánh bông lan. Sub New() trong VB.NET có thể nhận parameters nên nó có thể nhận chỉ thị để dùng  trứng vịt ngay trong lúc nướng cái Object bánh bông lan. Cái dạng đơn giản nhất của Sub New() mà ta có thể dùng là không pass parameter  nào cả (trong trường hợp nầy thì giống như Sub Class_Initialize của VB6). Ta code  Sub New() trong Class như sau: Public Class BanhBongLan Public Sub New() ' Code to initialise object here End Sub End Class Ta instantiate một Object bánh bông lan như sau: Dim myBanhBongLan As New BanhBongLan() Để cho Users có sự lựa chọn khi instantiate Object, ta có thể code thêm những Sub  New khác, mỗi Sub dùng một danh sách parameter khác nhau. Thí dụ: Public Class BanhBongLan Public Sub New() ' Code to initialise object here End Sub Public Sub New(ByVal LoaiTrung As String) Select Case LoaiTrung Case "Vit" ' Code for TrứngVịt here Case "Ga" ' Code for TrứngGà here End Select End Sub End Class Dùng cùng một tên method để implement nhiều methods khác nhau được gọi là  overload. Đó là một trường hợp đa dạng (polymorphism) của OO programming. Trong  thí dụ trên nếu TrứngVịt và TrứngGà là hai loại Data Types khác nhau thì ta cũng có  thể dùng: Sub New (ByVal TrứngVịt As TrứngVịtDataType) để instantiate bánh TrứngVịt và  Sub New (ByVal TrứngGà As TrứngGàDataType) để instantiate bánh TrứngGà. Như thế ta khỏi bận tâm với Select Case LoaiTrung khi chỉ dùng một Sub New duy  nhất với 1 parameter. Trong VisualStudio.NET, khi ta dùng tên của một overloaded method, IntelliSense sẽ  hiển thị để hướng dẫn ta đánh vào parameter list khác nhau tùy theo method ta chọn.  Termination Trong VB6 một Object sẽ bị huỷ diệt khi cái reference (chỗ dùng đến Object) cuối  cùng bị lấy đi. Tức là khi không có code nào khác dùng Object nữa thì Object sẽ bị tự  động huỷ diệt. System giữ một counter để đếm số clients đang dùng Object. Cách nầy  hay ở chỗ khi counter trở thành 0 thì Object bị huỷ diệt ngay. Ta nói nó có  deterministic finalization, nghĩa là ta biết rõ ràng khi nào Object biến mất. Tuy nhiên, nếu ta có hai Object dùng lẫn nhau (gọi là circular references), thì ngay  cả đến lúc chúng không còn hoạt động nữa, chúng vẫn hiện hữu mãi trong bộ nhớ vì  cái Reference counter của cả hai Objects không bao giờ trở thành 0. Nếu trường hợp  nầy xảy ra thường lần lần system không còn memory nữa, ta gọi đó là memory leak  (bị rỉ bộ nhớ) . .NET dùng phương pháp khác để quản lý chuyện nầy. Cứ mỗi chốc, một program sẽ  chạy để kiểm xem có Object nào không còn reference nữa để huỷ diệt. Ta gọi đó là  Garbage Collection (nhặt rác). Ngay cả trường hợp hai Objects có circular  references nhưng nếu không có code nào khác reference một trong hai Objects thì  chúng cũng sẽ được huỷ diệt. Có điều, công tác nhặt rác chạy in the background (phía  sau hậu trường) với ưu tiên thấp, khi CPU rảnh rang, nên ta không biết chắc một  Object sẽ bị hủy diệt đến bao giờ mới thật sự biến mất. Ta nói nó có  nondeterministic finalization. Ta có thể ép CLR nhặt rác lập tức bằng code: System.GC.Collect() Tuy nhiên, ta chỉ làm việc ấy khi kẹt quá thôi. Tốt hơn, ta duyệt lại design của mình để  cho phép các Objects hết xài có thể ngồi chơi trong bộ nhớ chờ đến lúc được hủy diệt.  Dùng Dispose Method Nếu ta có một Object dùng nhiều tài nguyên (resources) như bộ nhớ, database  connection, file handle,.v.v. và ta cần phải thả các tài nguyên ra ngay sau khi Object  không còn hoạt động nữa, ta cần implement một Interface tên IDisposable với  Implements keyword như sau: Public Class TheClass Implements IDisposable Bạn phải viết code cho Sub Dispose giống như sau: Private Sub Dispose() Implements IDisposable.Dispose ' Viết clean up code ở đây để thả các tài nguyên ra End Sub Sau đó bạn vẫn phải viết code cho Client để nó gọi Dispose Method trong IDisposable  interface. Bạn cần phải dùng CType để cast Object Class khi gọi Dispose. Dim objObject As New TheClass() CType (objObject, IDisposable).Dispose() Để lấy đi Reference đến một Object (gọi là Dereference Object) bạn có thể dùng: myObject = Nothing Để ý là ta không có dùng keyword Set như trong VB6. Nhớ là sau khi statement trên  được executed thì myObject không biến mất ngay nhưng nó đợi Garbage Collector  đến giải quyết.  Thừa kế Thừa kế (Inheritance) là khả năng của một Class đạt được interface (giao diện) và  behaviours (tánh tình) của một Class có sẵn. Cái quá trình để làm nên việc ấy được  gọi là Subclassing. Khi ta tạo ra một Class mới thừa kế cả interface lẫn behaviours từ  một Class có sẵn là chúng ta đã tạo ra một subclass của Class nguyên thủy. Người  ta nói đó là một mối liên hệ is­a (là một), ý nói Class mới là một loại Class nguyên  thủy. Ta phân biệt mối liên hệ is­a với mối liên hệ has­a (có một). Trong mối liên hệ has­a,  Object chủ có thể làm chủ một hay nhiều Objects tớ, nhưng Object tớ là một loại có  thể hoàn toàn khác với Object chủ. Để biểu diển đặc tính Inheritance ta hãy xét trường hợp một công ty cung cấp Sản  phẩm và Dịch vụ. Ta có thể code một Class cho Sản phẩm (ProductLine) và một  Class cho Dịch vụ (ServiceLine) , riêng rẽ nhau. Nhưng vì thấy chúng có nhiều điểm  tương đồng nên ta sẽ code một Class gọi là Món hàng (LineItem), rồi inherit từ  LineItem ra ProductLine và ServiceLine. LineItem có các properties ID, Item, Price (giá) và Quantity (số lượng). Nó cũng có một  Public Function để cho Amount (số tiền). Public Class LineItem Private mintID As Integer Private mstrItem As String Private msngPrice As Single Private mintQuantity As Integer Public Property ID() As Integer Get Return mintID End Get Set (ByVal Value As Integer) mintID = Value End Set End Property Public Property Item() As String Get Return mstrItem End Get Set (ByVal Value As String) mstrItem = Value End Set End Property Public Property Price() As Single Get Return msngPrice End Get Set (ByVal Value As Single) msngPrice = Value End Set End Property Public Property Quantity() As Integer Get Return mintQuantity End Get Set (ByVal Value As Integer) mintQuantity = Value End Set End Property Public Function Amount() As Single Return mintQuantity * msngPrice End Function End Class Để tạo Class ProductLine từ Class LineItem ta phải dùng Inherits keyword. Mỗi  Object ProductLine là một Object LineItem với ProductID và Description. ProductID  của ProductLine được pass vào Sub New lúc instantiate Object ProductLine. Còn  Description là một ReadOnly property của ProductLine. Ta có thể code Class  ProductLine như sau: Public Class ProductLine Inherits LineItem Private mstrDescription As String Public ReadOnly Property Description() As String Get Return mstrDescription End Get End Property Public Sub New(ByVal ProductID As String) Item = ProductID mstrDescription = "No description yet" ' Default description ' Viết code ở đây để đọc chi tiết của Product từ Database ' 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) 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. Bạn có thể Download source code của program nầy tại đây.
DMCA.com Protection Status Copyright by webtailieu.net