Lập trình , Thiết kế website, Auto Game Online

C Sharp căn bản – Chương IV – XÂY DỰNG LỚP – ĐỐI TƯỢNG

0
0
(0)

Chương 3 tho lun rất nhiều kiểu dữ liệu cơ bca ngôn ngữ C#, như intlong and char. Tuy nhiên ti tim và linh hồn của C# là khả năntạo ra những kiểu dữ liệu mới, phức tạp. Người ltrình tạo ra c kiu dữ liệu mới bằng cách xây dựnlp đối tượng và đó cũnchính là cávấn đề chúntcn thảo luậtrong chương này.

Đâlà khả năng để tạo ra nhng kiểu dữ limi, một đc tính quan trọng ca ngôn ngữ lập trình hưng đối tưng. Chúng tcó thể xây dựng những kiểu dữ liệu mtrong ngôn ngữ C# bằncách khai báo và định nghĩa nhng lớp. Ngoài ra tcũncó thể định nghĩa các kiểu dữ liu với những giao diện (interfacesẽ đưc bàtrong Chương 8 sau. Thể hiện ca một lớp đưc gọi là những đối tượng (object). Những đối tưng này đưtạo trong bộ nhớ khi chương trình được thc hiện.

Sự khác nhau gia một lớp và một đối tưng cũng giống như sự khác nhau gia khái niệm  giloài  mèo  và một  con mèo Mun  đang nằm  bên chân  của ta. Chúng ta không thể đụng chạm hay đùa giỡn vi khái niệm mèo nhưncó thể thc hiện điu đó đưc với mèo Mun, nó là một thc thể sống động, chứ không trừu tượng như khái niệm họ loài mèo.

Một họ o mô tả những comèo có các đc tínhcó trng lượng, có chicao, màu mt, màu lông,…chúng cũng có hành động như là ăn ngủ, leo trèo,…một con mèo, ví dụ như mèo Mun chng hạn, nó cũng có trọng lượng xác định là 5 kgchiu cao 15 cm, màu mắt đen, lông đen…Nó cũng có nhng khả năng như ăn ngủ letrèo,..

Lợi ích to lớn ca những lớp trong ngôn ngữ lập trình là khả năng đóng gói c thuc tính và tính chcủa một thc thể trong một khối đơn, tự có nghĩa, tự khả năng duy trì . Ví dụ khi chúng ta muốn sắp nội dung những thể hiện hay đối tưng của lớp điều khiển ListBotrên Windows, chỉ cần gọi c đối tưng này thì chúng sẽ tự sắp xếp, còn việchúng làm ra sao thì ta không quatâm, và cũnchỉ cn biết by nhu đó thôi.

Đóng gói cùng với đa hình (polymorphism) và kế tha (inheritance) là các thutính chính yếcủa bất kỳ một ngôn ngữ lp trình hướng đối tượng nào.

Chương 4 này sẽ trình bày các đtính ca ngôn ngữ lập trình C# để xây dng các lớp đối tưng. Thành phn ca một lớp, các hành vi và các thuc tính, đưc xem như là thành viên  của  lớp  (class  member).  Tiếp  theo  chương  cũng  trình  này khái  niệm  về  phương  thức (method) được dùng để định nghĩa hành vi của một lớp, và trạng thácủa các biến thành viên hot động trong một lớp. Một đặc tính mới mà ngôn ngữ C# đưa ra để xây dựng lớp là khái niệm thuc tính (property), thành phần thutính này hoạt động giống như ch phươnthc để tạo một lớp, nhưng bản chấcủa phương thức nàlà tạo một lp giao diệcho bên ngoài tương c với biến thành viên một cách gián tiếp, ta sẽ bàn sâu vấn đề nàtrong chương.

Định nghĩa lớp

 

Để định nghĩa một kiểu dữ liệu mhamột lớp đầu tiên phải khabáo rồi sau đó mới định nghĩcác thuc tính và phương thca kiểu dữ liệu đó. Khai báo một lớp bng cách sử dụng từ khoá classCú pháđy đủ ca khai báo một lớp như sau:

[Thuộtính] [Bổ sung truy cập] clas<Định danh lp> [: Lớp cơ s]

 

{

<Phần thân ca lớp: bao gồm định nghĩa các thutính và

 

phương thc hành động >

 

}

 

Thành phần thuộc tính ca đối tượng sẽ đưtrình bày chi tiết tronchương sau, còthành phn bổ sung trucậcũng sẽ được trình bàtiếngay mục dưiĐnh danh lớp chính là tên ca lớp do người xây dng chươntrình tạo ra. Lớp cơ sở là lớp mà đối tưnsẽ kế tha để phátriển tsẽ bàn sau. Tcả c thành viên của lp được định nghĩa bên trong thân ca lớp, phthânàsẽ đưc bao bọc bi hai du ({}).

Ghi chúTrong ngôn ngữ C# phn kếthúc ca lớp không có đấu chấm phy giống như khai bálớp trong ngôn ngữ C/C++. Tuy nhiên nếu ngưlập trình thêm vào thì trình biên dch C# vchp nhận mà không đưrcảnh o lỗi.

Trong C#, mọi chuyn đều xy ra trong một lớp. Như c ví dụ mà chúng tđã tìm hiểu trong chương 3, cáhàm điều được đưa vào trong một lớp, kể cả hàm đầu vào của chươntrình (hàm Main()):

public class Tester

 

{

 

public static int Main()

 

{

 

//....

 

}

 

}

 

Điu cn nói ở đâlà chúng ta chưtạo bcứ thể hiện nàcủa lớp, tc là to đối tượng cho

lớp Tester. Điu gì khác nhagimột lớp và thể hiện của lớp? để trả lới cho u hỏi này chúnta bắt đu xem xésự khác nhau giữa kiu dữ liệu int và một biến kiểu int Tcó viết như sau:

int var1 = 10;

tuy nhiên ta không thể viết đưc

 

int = 10;

Ta không thể gán giá trị cho một kiểu dữ liu, thay vào đó tchỉ đưgán dữ licho một đối tượng ca kiểu dữ lịêu đó, trong tng hợp trên đối tượng là biếvar1.

Khi chúng ttạo một lớp mới, đó chính là vic định nghĩa các thuc tính và hành vi của tất cả các đối tưncủa lớp. Giả sử chúng ta đanltrình để tạo c điều khiểtrong c ứng dụng trên Windowscác điều khiển này giúp cho ni dùng tương tác tốt với Windows, như là ListBoxTextBoxComboBox,…Một trong nhng điều khin thông dụng là ListBox, điều khiển này cuncấp một danh sách liệt kê c mục chọn và cho phép người dùng chọn các mục tin trong đó.

ListBonàcũng có các thuc tính khác nhau nhu: chiều cao, bề dày, vị trí, và màu sắc thể hiện và các hành vi của chúng như: chúng có thể thêm bới mục tin, sắp xếp,…

 

Ngôn ngữ lập trình hưng đối tượncho phép chúntto kiểu dữ liệu mới là lớp ListBox, lớp  này  bao  bọc  các  thuộc  tính  cũng  như  khả  năng  như:  các  thuc  tính height,  widthlocationcolorc phương thức hay hành vi như Add(), Remove(), Sort(),

Chúng ta không thể gán dữ liệu cho kiểu ListBox, thay vào đó đầu tiên ta phải tạo một đối tượng cho lớp đó:

ListBomyListBox;

Một khi chúng ta đã tạo một thể hiện clListBothì ta có thể gán dữ liệu cho thể hiện đó. Tuy nhiên đoạn lệnh trên chưa thể tạo đối tượng trong bộ nhớ đưc, ta sẽ bàn tiếp. Bâgiờ ta sẽ tìm hiểu cách tạo một lớp và tạcác thể hiện thông qua ví dụ minh họa 4.1. Ví dụ này to một lớp có chc năng hiểu thị thời giatrong một ngày. Lớp nàcó hành vi thể hiện ngày, tháng, năm, giờ, phút, giây hiện hành. Để làm đưc điều trên thì lớp nàcó 6 thuc tính hay còn gọi là biến thành vn, cùng với một phương thức như sau:

Ví dụ 4.1: Tạo một lớp Thoigian đơn giản như sau.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class ThoiGian

 

{

 

public void ThoiGianHienHanh()

 

{

 

Console.WriteLine(Hien thi thoi gian hien hanh”);

 

}

 

// Các biến thành viên int Nam;

int Thang; int Ngay; int Gio;

int Phut;

 

int Giay;

 

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

ThoiGian t = new ThoiGian();

 

t.ThoiGianHienHanh();

 

}

 

}

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

Hien thi thoi gian hien hanh

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Lớp  ThoiGiachỉ  có  một  phương  thức  chính  là  hàm ThoiGianHienHanh(),  phần  tn  của phương thức này đưc định nghĩa bên trong của lớp ThoiGian. Điều này khác với ngôn ngữ C++C# không đòi hỏi phải khai báo tc khi định nghĩa một phươnthức, và cũng không hỗ trợ việc khai báo phương thức trong một ttin và sau đó định nghĩa ở một tập tin khác.

C# không có cátập tin tiêđề, do vtất cả c phương thức đưc định nghĩa hoàtoàn bên trong  của  lớp.  Phần  cuối  của  đnh  nghĩa  lớp  là  phn  khai  báo  c  biến  thành  viên: NamThangNgayGioPhut, va Giay.

Sau khi định nghĩa xong lớp ThoiGian, thì tiếp theo là phn đnh nghĩa lớp Tester, lớp nàcó cha một hàm khá thân thiện với chúng tlà hàMain()Bên trong hàm Main có một thể hiện của lớp ThoiGiađưtạo ra và gán giá trị cho đối tượnt. Bởi vì là thể hiệcủa đối tượng ThoiGiannên hàMain(có thể sử dụng phương thức ct:

t.ThoiGianHienHanh();

 

Thuộc tính truy cập

Thutính truy cập quyết định khả năng các phươnthức ca lớp bao gồm việc c phương thức clp khácó thể nhìn thấy và sử dụng c biếthành viên hay những phương thức bêtrong lớp. Bảng 4.1 tóm tắt các thutính trucậcủa một lớp trong C#.

 

 

Thuộc tính

Giới hạn trucập

public

Không  hạn  chế.  Những  thành  viên  đưc  đánh  du

publicó thể đưc dùng bi bt kì c phương thcủa lớp bao gồm nhng lớp khác.

private

Thành viên trong một lớp A đưc đánh dấu là private

thì chỉ đưtrucập bcác phương thcủa lớp A.

protected

Thành  viên trong lớp  A  đưc  đánh  dấu  là protected

thì chỉ đưc phươnthức bên trong lp A và những phươnthc dẫn xuất từ lớp A trucập.

internal

Thành viên trong lớp A đưc đánh dlà internal thì đưc  truy  cập  bởi  nhng  phương  thc  ca  bất  cứ  lp

nào trong cùng khối hp ngữ vA.

protected internal

Thành  viên trong lớp  A  đưc  đánh  dấu  là protected internal đưc trucập bởi các phương thcủa lớp A, các phương thcủa lớp dẫn xucủa A, và bcứ lp

nào trong cùng khối hp ngữ ca A.

 

Bảng 4.1: Thuộc tính trucập.

Mong muốn chunlà thiết kế các biến thành vn của lớp ở thuc tính private. Khi đó chỉ có phương thức thành viêcủa lớp trucập được giá trị ca biến. C# xem thutính privatlà mc đnh nêtrong ví dụ 4.1 ta không khai báo thuc tính trucập cho 6 biến nên mc định chúnlà private:

// Các biến thành viên privatint Nam;

int Thang; int Ngay; int Gio;

int Phut;

 

int Giay;

Do  lớp Testevà  phương thc  thành  viên ThoiGianHienHanh của lớp  ThoiGian đưc  khai bálà publinên bất kỳ lp nào cũng có thể trucập đưc.

Ghi chúThói quelập trình tốt là khai bátưng minh các thutính truy ccủa biến thành  viên  hay các phương thc  trong  một  lp.  Mặc dù  chúng ta biết  chc  chắn  rng  c thành vca lớp là đưc khai báprivatmặc đnh. Vic khai báo tường minh nàsẽ làm cho chươntrình dễ hiểu, rõ ràng và tự nhn hơn.

 

Tham số của phươnthức

 

Trong các ngôn ngữ lập trình thì tham số và đối mục đưc xem là như nhau, cũng tương

tự khi đang nói về ngôn ngữ hưng đối tưng thì ta gọi một hàlà một  phương thc hay hành viTất cả các tên này điều tương đồng với nhau.

Một phương thcó thể ly bkỳ số lưng tham số nào, Các tham số này theo sau bởi

tên của phươnthức và đưc bao bọc bêtrong du ngotròn (). Mỗi tham số phải khabáo kèm với kiểu dữ liệu. ví dụ ta có một khai báo định nghĩa một phương thức có tên là Method, phương thức không trả về giá trị nào cả (khai báo giá trị trả về là void), và có hatham số là một kiểu invà button:

void  Method( int param1, buttoparam2)

 

{

 

//…

 

}

 

Bên trong thân ca phươnthc, các tham số này đưc xem như nhng biến cc bộ, giống như là ta khai báo biếbên trong phương thc và khởi tạo giá trị bng giá trị ca thasố truyn vào. Ví dụ 4.2 minh họa việtruyền tham số vào một phương thức, trong trưng hp này thì hai tham số của kiểu là int và float.

Ví dụ 4.2: Truyền tham số cho phương thức.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

using System;

 

public class Class1

 

{

 

public void SomeMethod(int p1, float p2)

 

{

 

Console.WriteLine(Ham nhan duoc hai tham so: {0} va {1}, p1,p2);

}

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

int var1 = 5;

 

float var2 = 10.5f;

 

Class1 c = new Class1();

 

c.SomeMethod( var1, var);

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

Ham nhan duoc hai tham so: 5 va 10.5

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Phương thSomeMethod sẽ ly hai tham số invà float rồi hiển thị chúng ta màn hình bng việc dùng hàm Console.WriteLine(). Nhữntham số nàcó tên là p1 và p2 đưc xem như là biến cc bộ bên trong ca phương thc.

Trong phươnthgọi Maincó hai biến cc bộ đưtạo ra là varvà var2. Khi hai biến y đưc truyn cho phương thSomeMethod thì chúng đưc ánh xạ tnh hai tham số p1 và

p2 theo thứ tự danh sách biến đưa vào.

 

Tạo đi tượng

 

Trong Chương 3 có đề cập đến sự khác nhau gia kiu dữ liệu giá trị và kiểu dữ liệu tham chiếu. Những kiểu dữ liệu chuẩn cC# như intcharfloat,… là nhng kiểu dữ liệu giá trị,

và các biến đưtạo ra từ các kiu dữ liệu này đưlưtrên stack. Tuy nhiên, vc đối tượng kiểu dữ liệu tham chiếthì đưc tạo ra trên heap, sử dụng từ khóa new để tạo một đối tượng:

ThoiGian t = new ThoiGian();

 

thật sự không chứa giá trị ca đối tưnThoiGian, nó chỉ chứa đchỉ của đối tượng đưtạo ra trên heap, do vchỉ cha tham chiếu đến một đối tượng mà thôi.

 

Bộ khởi dng

 

Thử xem lại ví dụ minh họa 4.1, u lnh to một đối tượng cho lớp ThoiGiatương tự như việc gọi thc hiện một phương thc:

ThoiGian t = new ThoiGian();

Đúng  như  vy,  một  phương  thc  sẽ  đưc  gi  thực  hin  khi  chúng  ta  tạo  một  đi  tưng. Phương  thc này đưc gọi là bộ  khi  dng (constructor).  Các phương  thc này đưc định nghĩa khi xây dựnlớp, nếta khôntạo ra thì CLR sẽ thay mt chúnta mà to phương thc khởi dựng một cách mc định. Chức năng ca bộ khi dựng là to ra đối tưng đưc xác định bởi một lớp và đtrng thái này hlTc khi bộ khởi dựng đưc thc hiện thì đối tưng chưa đưcấp phát trong bộ nhớ. Sau khi bộ khi dng thc hiện hoàn thành thì bộ nhớ sẽ

lưu giữ một thể hiện hợp lệ của lp va khai báo.

Lớp ThoiGiatrong ví dụ 4.1 không định nghĩa bộ khởi dựng. Do không định nghĩa nên trình biên dch sẽ cung cấp một bộ khởi dựncho chúng ta. Pơng thc khởi dng mặc định đưtạo ra cho một đối tượnsẽ không thc hiệbất cứ hành động nào, tức là bên trong thân ca phương thức rỗng. Các biến thành viên đưc khởi tạo các giá trị tầm thường như  thuc tính nguyên có giá trị là 0 và chuỗi thì khởi tạo rỗng,..Bng 4.2 sau tóm tắt các giá trị mc đnh

được gán cho các kiểu dữ liệu cơ bản.

 

 

Kidữ liệu

Giá trị mặc định

int, long, byte,…

0

bool

false

char

\0’ (null)

enum

0

reference

null

Bảng 4.2: Giá trị mặc đnh của kiểu dữ liệu cơ bản.

Thường thường, khi muốn định nghĩa một phương thc khởi dựng riêng ta phcuncấp các tham số để hàm khi dựng có thể khởi to các giá trị khác ngoài giá trị mặc định cho các đối tượng. Qualại ví dụ 4.1 giả sử ta muốn truyn thời gian hiện hành: năm, tháng, ngày,…để đối tượng có ý nghĩa hơn.

Để định nghĩa một bộ khởi dựng riênta phải khai báo một phươnthcó tên giống như tên

lớp đã khai báo. Phương thc khi dng không có giá trị trả về và đưc khai báo là public. Nếu phương thc khi dng này được truyn tham số thì phi khai báo danh ch tham số giống như khai báo với bất kỳ phương thức nào trong một lp. Ví dụ 4.3 đưc viết li từ ví dụ 4.1 và thêm một bộ khi dựng riêng, phương phc khi dựnnày sẽ nhận một tham số là một đối tượng kiểu DateTime do C# cung cấp.

 

 

Ví dụ 4.3: Định nghĩa một bộ khi dng.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class ThoiGian

 

{

 

public void ThoiGianHienHanh()

 

{

 

Console.WriteLine(“ Thoi gian hien hanla : {0}/{1}/{2}

 

{3}:{4}:{5}”, Ngay, Thang, Nam, Gio, Phut, Giay);

 

}

 

// Hàm khởi dựng

 

public ThoiGian( System.DateTime dt )

 

{

 

Nam = dt.Year; Thang = dt.Month; Ngay = dt.Day;

Gio = dt.Hour; Phut = dt.Minute; Giay = dt.Second;

}

 

// Biến thành viên private int Nam;

int Thang; int Ngay; int Gio;

int Phut;

 

int Giay;

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime  currentTime = System.DateTime.Now; ThoiGian t = new ThoiGian( currentTime ); t.ThoiGianHienHanh();

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

 

 

 

Kết quả:

 

Thoi gian hien hanh la: 5/6/2002  9:10:20

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Trong ví dụ trên phương thc khởi dng lấmột đối tượng DateTime và khtạo tcả các biến thành vn dựa trêgiá trị của đối tưng này. Khi phương thức này thc hiện xong, một đối  tượng  ThoiGiađưc  tạo  ra  và  c  biến  của  đối  tượng  cũng  đã  đưc  khởi  tạo.  Hàm ThoiGianHienHanh đưc gọi trong hàm Main(sẽ hiển thị giá trị thời gian lúc đối tượng đưtạo ra.

Chúng ta thử bỏ một số lệnh khởi to trong phương thức khởi dng và cho thc hichươntrình lại thì c biến không được khtạo sẽ có giá trị mặc định là 0, do là biến nguyên. Một biến thành viên kiểu nguyêsẽ đưc thiết lập giá trị là 0 nếchúng ta không gán nó trong phương thức khởi dựng. Chú ý rng kiểu dữ liệu giá trị không thể không được khtạo, nếu ta không khi tạo thì trình bn dịcsẽ cung cp các giá trị mặc định theo bảng 4.2.

Ngoài ra trong chương trình 4.3 trên có sử dụng đối tượng clDateTime, lớp DateTime này đưc cuncấp bởi thư viện System, lớp này cũng cung cấp các biến thành viêpublinhưYearMonthDayHourMinute, và Second tương tự như lớp ThoiGiacủa chúng ta. Thêm vào đó là lớp nàcó đưa ra một phương thc thành viên tĩnh tên là Now, phươnthNosẽ trả về một tham chiếđến một thể hiện của một đối tượnDateTime đưc khto

với thgian hiện hành. Theo như trên khi lệnh :

System.DataTime  currentTime = System.DateTime.Now();

đưthực hiện thì phươnthc tĩnh Now() sẽ tạo ra một đối tưng DateTimtrên bộ nhớ heap và trả về một tham chiếu và tham chiếu này đưgán cho biến đối tưng currentTime.

Sau khi đối tưng currentTime đưtạo thì câlệnh tiếp thesẽ thc hiện việc truyn đối tượng currentTimcho phương thc khởi dựng để tạo một đối tượng ThoiGian:

ThoiGian t = new ThoiGian( currentTime );

Bên trong phương thức khi dựnnày tham số dt sẽ thachiếu đến đối tưng DateTime là đối tượng vừa tạo mà currentTimng tham chiếu. Nói cách khác lúc này tham số dt và currentTime ng tham chiếu đến một đối tượng DateTime trong bộ nhớ. Nhờ vy phương thức  khởi  dng  ThoiGiacó  thể  truy  cp  đưc  c  biến  thành  vpublic  của  đối  tưng DateTimđưtạo trong  hàm Main().

Có một sự nhấn mạnh ở đâlà đối tưnDateTime đưtruycho bộ dựng ThoiGiachính là đối tượng đã đưtạo trong hàm Main và là kiu dữ  liệu tham chiếu. Do vy khi thc hiện truyn tham số là một kiểu  dữ liệu tham  chiếu  thì  con  trỏ  đưánh  xạ qua chứ hoàtoàn không có một đối tưng nào được sachép li.

 

 

Khởi tạo biến thành viên

 

Các biến thành vcó thể đưc khởi tạtrc tiếp khi khai bátrong quá trình khởi tạo, thay vì phải thực hin việc khởi tạo các biến trong bộ khởi dựng. Để thc hiện việc khởi to này rđơn giản là việc sử dụng phép gán giá trị cho một biến:

 

privatint Giay = 30;     // Khi tạo

Việc khởi tạo biến thành viên sẽ rất có ý nghĩa, vì khi xác định giá trị khởi tạo như vthì biến sẽ không nhận giá trị mặc đnh mà trình biên dch cung cp. Khi đó nếu các biến này không đưc gán li trong các phương thc khởi dựng thì nó sẽ có giá trị mà ta đã khởi to. Ví dụ 4.4 minh ha việc khởi to biến thành viên khi khai báo. Trong ví dụ này sẽ có hai bộ dng ngoài bộ dựng mặc đnh mà trình biên dịccung cp, một bộ dựng thực hin việc gán

giá trị cho tất cả các biến thành viên, còn bộ dựng thứ hai thì cũng tươntự nhưnsẽ không gán giá trị cho biến Giay.

Ví dụ 4.4: Minh hoạ sử dụng khởi tạo biến thành viên.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

public class ThoiGian

 

{

 

public void ThoiGianHienHanh()

 

{

 

System.DateTime now = System.DateTime.Now; System.Console.WriteLine(\n Hien tai: \t {0}/{1}/{2}  {3}:{4}:{5}”,

now.Day, now.Month, now.Yearnow.Hour, now.Minute, now.Second); System.Console.WriteLine(“ Thoi Gian:\t {0}/{1}/{2}  {3}:{4}:{5}”,

Ngay, Thang, Nam, Gio, Phut, Giay);

 

}

 

public ThoiGian( System.DateTime dt)

 

{

 

Nam = dt.Year; Thang = dt.Month; Ngay = dt.Day;

Gio = dt.Hour; Phut = dt.Minute;

Giay = dt.Second;     // có gán chbiến thành viên Giay

 

}

 

public ThoiGian(int Yearint Month, int Date, int Hourint Minute)

 

{

 

Nam = Year; Thang = Month; Ngay = Date;

Gio = Hour;

 

Phut = Minute;

 

}

 

privatint Nam; privatint Thang; privatint Ngay; privatint Gio; privatint Phut;

privatint Giay = 30 ; // biến đưkhi tạo.

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime currentTime = System.DateTime.Now; ThoiGian t1 = new ThoiGian( currentTim); t1.ThoiGianHienHanh();

ThoiGian t2 = new ThoiGian(2001,7,3,10,5);

 

t2.ThoiGianHienHanh();

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

Hien tai:

5/6/2002

10:15:5

Thoi Gian:

5/6/2002

10:15:5

 

 

Hien tai:

5/6/2002

10:15:5

Thoi Gian:

3/7/2001

10:5:30

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Nếu không khởi tạo giá trị của biến thành viên thì bộ khởi dựnmặc định sẽ khtạo giá tr là

mặc đnh cho biến thành viên có kiu nguyên. Tuy nhiên, trontrưng hp này biến thành viên Giay đưc khởi tạo giá trị 30:

Giay = 30;       // Khởi to

Trong trường hợp bộ khởi tạo thứ hai khôntruyn giá trị cho biến Giay nên biến này vly giá trị mà ta đã khởi tạo ban đlà 30:

ThoiGian t2 = new ThoiGian(2001, 7, 3, 10, 5);

 

t2.ThoiGianHienHanh();

 

Ngưc li, nếu một giá trị đưc gán cho biếGiay như trong bộ khtạo thứ nhất thì giá trị mới này sẽ đưchồng lên giá trị khtạo.

Trong ví dụ trên ln đầu tiên to đối tượng ThoiGiado ttruyn vào đối tượnDateTimnên hàm khởi dng thứ nhất đưc thc hiện, hàm này sẽ gán giá trị 5 cho biến Giay. Còn khi tạo đối tượnThoiGiathứ hai, hàm khi dng thứ hai đưc thc hin, hàm này không gán giá trị cho biếGiay nên biến này vẫn còn lưu giữ lại giá trị 30 khi khởi to bađầu.

 

Bộ khởi dng sao chép

 

Bộ khởi dựnsachép thc hin việtạo một đối tượng mới bng ch sao chétất cả các biến từ một đối tượng đã có  và cùng một kiểu dữ liu. Ví dụ chúng ta muốn đưa một đối tượng ThoiGiavào bộ khởi dựng lớp ThoiGiađể tạo một đối tưnThoiGiamới có cùng giá trị với đối tưnThoiGiacũ. Hai đối tưnnày hoàn toàn khác nhau và chỉ ging nhau ở giá trị biến tnh vsao khi khởi dựng.

Ngôn ngữ  C# không cuncấp bộ khi dựnsao cp, do đó chúnta phải tự tạo ra. Visao cc thành phn từ một đối tưng ban đầu cho một đối tưng mới như sau:

public ThoiGian( ThoiGian tg)

 

{

 

Nam = tg.Nam; Thang = tg.Thang; Ngay = tg.Ngay; Gio = tg.Gio;

Phut = tg.Phut; Giay = tg.Giay;

}

 

Khi đó ta có thể sao chétừ một đối tượng ThoiGiađã hiện hu như sau:

 

ThoiGian t2 = new ThoiGian( t1 );

Trong đó t1 là đối tượnThoiGiađã tồn tại, sau khi lệnh trên thc hiện xong thì đối tưng

t2 đưtạo ra như bản sao ca đối tưnt1.

 

Từ khóa this

 

Từ khóa this đưc dùng để tham chiếu đến thể hiện hiện hành ca một đối tưng. Tham chiếthis này được xelà con trỏ n đến tất các phương thức không có thuc tính tĩnh trong một lớp. Mỗi phương thức có thể thachiếu đến nhng phương thc khác và các biến thành viên thông qua tham chiếthis này.

Tham chiếthis này được sử dụng thưng xuyêtheo ba cách:

Sử dụng khi các biếthành viên bị che lấp bởi tham số đưa vào, như  trưng hợp sau:

 

public void SetYear( int Nam)

 

{

 

this.Nam = Nam;

 

 

 

}

Như trong đoạn mã trên phương thSetYeasẽ thiết lập giá trị của biến thành viên Nam, tuy nhiên do tham số đưa vàcó tên là Namtrùng với biến thành viên, nêta phải dùng tham chiếthis để xác đnh rõ các biến thành viên và tham số đưtruyn vào. Khi đó this.Nam chỉ đến biến thành viên ca đối tưng, trong khi Nam chỉ đến tham số.

Sử dụng tham chiếthis để truyn đối tưng hin hành vào một tham số của một phương thức của đối tưng khác:

public void Method1( OtherClass otherObject )

 

{

 

// Sử dụng tham chiếu this để truyn tham số là bản

 

// thân đi tượng đang thực hiệnotherObject.SetObject( this );

}

 

Như tcho thy khi cần truyn một tham số là chính bản thân ca đối tượng đang thc hin

thì ta bắt buc phi dùng tham chiếthis để truyn.

Các thứ ba sử dụng tham chiếthis là mảng chỉ mục (indexer), phn nàsẽ đưtrình bàchi tiết trong chương 9.

Sử dụng các tnviênh (static member)

 

Những  thuộc  tính  và  phương  thức  trong  một  lớp  có  thể  là  nhng  thành  viên  thể  hin (instance members) hay nhng thành viên tĩnh (statimembers). Nhữnthành viên thể hiện hathành viên ca đối tượng liên quan đến thể hicủa một kiểu dữ liệu. Trong khi thành viên tĩnh đưc xem như một phcủa lớp. Chúnta có thể trucập đến tnh viêtĩnh ca một lớp thông qua tên lớp đã đưc khai báo. Ví dụ chúnta có một lớp tên là Button và có hai thể hiện của lớp tên là btnUpdatvà btnDeleteVà giả sử lớp Button nàcó một phương thức tĩnh là Show(). Để truy cp phương thc tĩnh nàta viết :

Button.Show();

Đúng hơn là viết:

 

btnUpdate.Show();

Ghi chú: Trong ngôn ngữ  C# khôncho phép trucập đến c phương thc tĩnh và c biến thành vn tĩnh thông qua một thể hin, nếu chúnta cố làm điều đó thì trình biên dch Csẽ bálỗi, điều này khác với ngôn ngữ  C++.

Trong một số ngôn ngữ thì có sự phân chia giữa phương thc ca lớp và c phương thc khác (toàcctồn ti bêngoài không phụ thuc bất cứ một lớp nào. Tuy nhiên, điềnày không cho phép trong C#, ngôn ngữ C# không cho phép tạo c phươnthức bên ngoài ca lớp, nhưntcó thể tạo đưcác phương thc giống như  vy bằncáctạo c phương thc tĩnh bên trong một lớp.

 

Phương  thức tĩnh  hoạt  động ít  nhiu  ging như phương thức toàn cc, ta  truy cập  phương thức này mà không cn phtạo bcứ thể hiện hay đối tưng của lớp cha phươnthtoàn cục. Tuy nhiên, lợi íccủa phương thtĩnh vưt xa phương thc toàcc vì phương thức tĩnh đưc bao btrong phạm vi cmột lớp nơi nó đưc định nghĩa, do vtsẽ không gp tình trng lộn xộn gic phương thức trùntên do chúng được đt trong namespace.

Ghi chúChúng ta không nên bị cám dỗ bởi việc tạo ra một lớp chứa toàn bộ các phương thức linh tinh. Điều nàcó thể tiện cho công việc ltrình nhưng sẽ điều không mong muốn

và  giảm tính  ý nghĩa  ca việc  thiết  kế hưng  đối  tượng.  Vì  đc  tính  ca việc  tạo  các đối tượng là xây dng các phương thc và hành vi xung quanh các thutính hay dữ liệu ca đối tượng.

 

Gọi một phương thức tĩnh

 

Như chúng ta đã biết phương thMain(là một  phương thc tĩnh.  Phương  tĩnh  đưc xem như là phn hoạt động ca lớp hơn là của thể hiện một lớp. Chúng cũng khôncầcó một tham chiếu this hay bất cứ thể hiện nào tham chiếu tới.

Phương  thức  tĩnh  không  thể  trucập  trực  tiếp  đến  các thành  viên  không  có  tính  cht  tĩnh (nonstatic). Như vMain(không  thể gọi  một  phương  thức không  tĩnh  bên  trong  lớp.  Ta xem lại đoạn chươntrình minh họa trong ví dụ 4.2:

using System;

 

public class Class1

 

{

 

public void SomeMethod(int p1, float p2)

 

{

 

Console.WriteLine(Ham nhan duoc hai tham so: {0} va {1}, p1,p2);

 

}

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

int var1 = 5;

 

float var2 = 10.5f;

 

Class1 c = new Class1();

 

c.SomeMethod( var1, var);

 

}

 

}

Phương thSomeMethod() là phương thức không tĩnh của lớp Class1, do đó để trucập đưc phương thclớp nàcấn phải tạo một thể hin là một đối tượng cho lớp Class1.

 

Sau  khi tạo thì có  thể thông qua đối tượng ta có thể gọi đưc được  phương thSome- Method().

 

Sử dng bộ khởi dựng tĩnh

 

Nếu một lớp khai báo một bộ khởi tạo tĩnh (static constructor), thì đưc đm bo rng phương thc khởi dng tĩnh nàsẽ đưc thc hiện trưbất cứ thể hiện nào clp đưtạo ra.

Ghi chú: Chúnta không thể điu khiển chính xác khi nào thì phươnthức khi dựng tĩnh này được thc hiện. Tuy nhiên ta biếchrng nó sẽ đưc thc hiện sau khi chương trình chy và trưc bt kì biến đối tượng nào đưc to ra.

Theo ví dụ 4.4 ta có thể thêm một bộ khởi dựng tĩnh cho lớp ThoiGian như sau:

 

static ThoiGian()

 

{

 

Ten = “Thoi gian”;

 

}

 

Lưu ý rng ở đây không có bất cứ thuộc tính trucập nào như publitrưc bộ khi dng tĩnh. Thutính trucập không cho phép theo sau một phương thc khi dng tĩnh. Do phương thức tĩnh nên không thể truy cbất cứ biến thành viên không thuộc loi tĩnh, vì vy biến thành vNambên trên cũng phải đưc khai báo là tĩnh:

private static string Ten;

Cuối cùnta thêm một dòng vào phương thức ThoiGianHienHanh(của lớp ThoiGian:

 

public void ThoiGianHienHanh()

 

{

 

System.Console.WriteLine(“ Ten: {0}”, Ten); System.Console.WriteLine(“ Thoi Gian:\t {0}/{1}/{2}  {3}:{4}:{5}”,

Ngay, Thang, Nam, Gio, Phut, Giay);

 

}

 

Sau khi thay đổi ta biên dcvà chy chương trình đưkết quả sau:

 

Ten: Thoi Gian

 

Thoi Gian:  5/6/2002  18:35:20

Mc dù chươntrình thực hiện tốt, nhưng không cần thiết phtạo ra bộ khi dng tĩnh để phục vụ chmục đích này. Thay vào đó ta có thể dùng chức năng khởi tạo biến thành viên như sau:

private static string Ten = “Thoi Gian;

Tuy nhiên, bộ khtạo tĩnh có hữu dụng khi chúng tcn cài đặt một số công vic mà không

thể thc hiện đưc thông qua chức năng khi dựng và công việcài đặt này chỉ đưc thực hiện duy nht một ln.

 

Sử dng bộ khởi dựng private

 

Như đã nói ngôn ngữ C# không có phương thc toàcc và hnsố toàn cục. Do vy chúntcó thể tạo ra những lớp tiện ích nhỏ chỉ để chcác phương thc tĩnh. Cách thc hiện  này luôn  có  hai  mt  tốt  và  không  tốt.  Nếu  chúng  ta  tạo  một  lớp  tiện  ích  như  vvà không muốn bất cứ một thể hiện nào đưtạo ra. Để ngăn nga việtạo bất cứ thể hiện của lớp ta to ra bộ khi dựng không có thasố và không làm gì c, tức là bên trong thân của phương thức rỗng, và thêm vào đó phương thc này đưc đánh dlà private. Do không có bộ khởi dựng public, nên không thể tạo ra bt cứ thể hin nào của lớp.

 

Sử dng các thuộc tính tĩnh

 

Một vn đề đt ra là làm sao kiểm soát đưsố thể hiện cmột lớp đưtạo ra khi thc hiện chương trình. Vì hoàn toàn ta không thể tạo đưc biến toàn cục để làm công việc đếm số thể hiệca một lớp.

Thông thường c biến thành viên tĩnh đưc dùng để đếsố thể hiện đã được được tạo ra ca một lớp. Cách sử dụng này đưáp dụng trong minh họa sau:

Ví dụ 4.5: Sử dụng thuc tính tĩnh để đếm số thể hiện.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Cat

 

{

 

public Cat()

 

{

 

instance++;

 

}

 

public static void HowManyCats()

 

{

 

Console.WriteLine(“{0} cats”, instance);

 

}

 

private static int instance =0;

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

Cat.HowManyCats(); Cat mun = new Cat(); Cat.HowManyCats();

Cat muop = new Cat();

 

Cat miu = new Cat();

 

Cat.HowManyCats();

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

0 cats

 

1 cats

 

3 cats

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Bên trong lớp Cat ta khai báo một biến thành viên tĩnh tên là instance biến này dùng để đếm

số thể hiện của lớp Cat, biến y đưc khởi tạo giá trị 0. Lưu ý rng biến thành viên tĩnh đưc xem là thành phca lớp, không phải là thành viêcủa thể hiện, do vy nó sẽ không đưc khởi tạo btrình biên dch khi tạo các thể hiện. Khởi to tường minh là yêu cu bt buộc với các biến tnh viên tĩnh. Khi một thể hiện đưc to ra thì bộ dựncủa lCat sẽ thực hiện tăng biến instance lêmột đơn vị.

 

Hy đi tượng

 

Ngôn ngữ C# cuncấcơ chế thu dọn (garbage collection) và do vy không cần phải khai bátường minh các phương thức hy. Tuy nhiên, khi làm việc vi các đon mã không đưc qulý thì cần phải khai báo tưng minh các phương thức hủy để gii phóng cátànguyên.

Ccung cấp ngn đnh một phương thức để thực hiện điều khiển công việc này, phương thức

đó là Finalize() hay còn glà bộ kết thúc. Phương thức Finaliznàsẽ đưgọi bởi cơ chế thu dọn khi đối tưng bị hy.

Phương thức kết thúchỉ giải phóng cátài nguyên mà đối tượng nắm giữ, và khôntham chiếu  đến  c đối  tượng  khác.  Nếu  vi  nhng  đon  mã bình  thường  tức  là cha  các tham chiếu kiểm soát đưc thì không cần thiết phto và thực thi phươnthức Finalize(). Chúnta chỉ làm điềnày khi xử lý tài nguyên không kiểm soát đưc.

Chúng ta không bagiờ gọi một phương thức Finalize() của một đối tượng một cáctrc tiếp, ngotrừ gọi phương thc nàcủa lớp cơ sở khi ở bêtrong phương thức Finalize() của chúnta. Trình thu dọn sẽ thc hiện việc gFinalize() cho chúng ta.

 

 

Cách Finalize thực hiện

 

 

 

Bộ  thu  dọn duy trì một  danh sách  nhng  đối tưng  có phương thc  Finalize.  Danh  sách  này  đưc  cp  nht  mỗi  ln  khi  đối tượng cuối cùng đưc to ra habị hủy.

Khi một đối tượntrong danh sách kết thúc ca bộ thu dọn đưchọn  đầu  tiên.  Nó  sẽ  đưc  đt  vào  hàng  đợi  (queue)  cùng  với những đối tượng khác đang chờ kết thúc. Sau khi phương thFinalizcủa đối tượng ththi bộ thu dọn sẽ gom lại đối tưnvà cp  nhật li danh  sách hàng đi,  cũng như là danh sách kết thúc đối tượng.

 

 

Bộ hca C#

 

Cú  pháp  phương  thức  hy  trong  ngôn  ngữ  C#  cũng  ging  như  trong  ngôn  ngữ  C++. Nhưng về hành động cụ thể chúng có nhiđim khác nhau. Ta khao báo một phương thức hủy trong C# như sau:

~Class1() {}

Tuy  nhiên,  trong  ngôn  ngữ  C#  thì  cú  pháp  khai  báo  trên  là  một  shortcut  liên  kết  đến  một phương thức kết thúc Finalizđưc kết với lớp cơ sở, do vy khi viết

~Class1()

 

{

 

// Thực hiện một số công vic

 

}

 

Cũng tương tự như viết :

 

Class1.Finalize()

 

{

 

// Thực hiện một số công vic base.Finalize();

}

 

Do sự tươntự như tn nên khả năng dẫn đến sự lộn xộn nhầm lẫn là không tnh khỏi, nên chúnta phtránh viếcác phương thc hy và viếcác phương thFinaliztường minh nếcó thể được.

 

Phươnthức Dispose

 

Như chúntđã biết thì việc gi một phươnthc kết thúc Finaliztrong Clà không hợp l, vì phương thnày dành cho bộ thu dọn thc hiện. Nếcnta xử lý các tài nguyên không kiểm soát như xử lý cáhandle ctập tin và ta muốn đưc đóng hay giải phóng nhanh chóng bất cứ lúc nào, tcó ththi giao diện IDisposable, phchi tiết IDisposable sẽ đưtrình bàchi tiết trong Chương 8. Giao diện IDisposable yêu cu những thành phn thực thi ca nó định nghĩmột phương thtên là Dispose() để thc hiện công việc dọn dmà tyêcầu. Ý nghĩcủa phương thDispose là cho phép chươntrình thc hiện công việc dọn dẹp hay giải phóng tài nguyên mong muốn mà không phải chờ cho đến khi phương thFinalize() đưc gọi.

Khi cnta cuncấp một phương thức Dispose thì phải ngưng bộ thu dọn gọi phương thức Finalize() trong đối tượng ca chúntaĐể ngưng bộ thu dọn, chúng ta gọi một phương thức tĩnh ca lớp G(garbage collector) là GC.SuppressFinalize() và truyn tham số là tham chiếu  this của  đối  tưng.  Và  sau  đó  phương  thFinalize(sử  dụng  để  gọi  phương  thức Dispose() như đon mã sau:

public void Dispose()

 

{

 

// Thực hiện công vic dọn dp

 

// Yêu cầu bộ thu dọc GC trong thhikếthúc

 

GC.SuppressFinalizethis );

 

}

 

publioverride void Finalize()

 

{

 

Dispose();

 

base.Finalize();

 

}

 

Phươnthức Close

 

Khi xây dựng c đối tưng, chúng ta có muốn cuncấp cho ngưsử dụng phương thức

Close(), vì phươnthCloscó vẻ tự nhiên hơn phương thDispose trong c đối tưng

có liên quan đến xử lý tập tin. Tcó thể xây dựng phương thDispose() với thutính là

privatvà phương thClose() với thuộc tính publicTrong phương thClose() đơn giản

là gthc hiện phương thDispose().

 

Câu lnh using

 

Khi xây dng các đối tưnchúng ta không thể chchắn được rằng ngưsử dụng có

thể gọi hàm Dispose(). Và cũng không kisoát đưc lúc nào thì bộ thu dọn GC thực hin việc dọn dẹp. Do đó để cung cấp khả năng mạnh hơn để kisoát việc giải phóng tài nguyên thì C# đưa ra cú pháchỉ dẫn usingcú pháp này đảm bảo phương thức Dispose() sẽ đưgọi sm nhcó thể đưc. Ý tưởnlà khai báo các đối tượng vcú pháusing và sau đó tạo một phm vi hoạt động cho các đối tượng nàtrong khối được bao bởi dấu ({}). Khi khối phạm vi nàkết thúc, thì phương thức Dispose() của đối tượng sẽ được gọi một cách tự động.

Ví dụ 4.6: Sử dụng chỉ dẫn using.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System.Drawing;

 

class Tester

 

{

 

 

 

 

 

 

public static void Main()

 

{

 

using ( Font Afont = new Font(“Arial”,10.0f))

 

{

 

// Đoạn mã sử dng AFont

 

.......

 

}// Trình biên dịch sẽ gọi Dispose để gii phóng AFont

 

Font TFont = neFont(“Tahoma,12.0f);

 

using (TFont)

 

{

 

// Đoạn mã sử dng TFont

 

.......

 

}// Trình biên dịch gi Dispose để giải phóng TFont

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Trong  phn  khai  báo  đầu  ca  ví  dụ  thì  đối  tưng Font đưc  khai  báo  bên  trong  u  lệnh using. Khi lnh using kết thúc, thì phương thDispose ca đối tưnFont sẽ đưc gọi.

Còn trong phn khai báo thứ hai, một đối tượng Fonđưtạo bên ngoàlệnh using. Khi quyết đnh dùng đối tượng nàtđặt nó vào câlệnh using. Và cũng tươntự như trên khi khối câu lệnh using thc hiện xong thì phương thDispose() của font đưgọi.

Truyền tham số

 

Như đã thảo luận trong chươntrước, tham số có kiểu dữ liệu là giá trị thì sẽ đưtruyn

giá trị vào cho phương thức. Đinàcó nghĩa rng khi một đối tượng có kiểu là giá trị đưtruyn vào cho một phương thức, thì có một bản sao chép đối tưng đó được tạo ra bên trong phương thức. Một khi phương thc đưc thc hiện xong thì đối tượng sachép này sẽ đưc hủy. Tuy nhiên, đâchỉ là trưng hợp bình thường, ngôn ngữ Ccòn cung cp khả năng cho phéta truycác đối tượng có kiểu giá trị dưới hình thlà tham chiếu. Ngôn ngữ C# đưa ra một bổ suntham số là ref cho phép truycác đối tưng giá trị vào trong phương thc theo kiểu  tham  chiếu.  Và  tham  số  bổ  sung out trong  trưng  hp  muốn  truyn dưới  dng  tham chiếu mà không cần phải khởi to giá trị ban đầu cho thasố truynNgoài ra ngôn ngữ C# còn hỗ trợ bổ sunparamcho phép phương thchp nhận nhisố lưng c tham số.

 

Truyền tham chiếu

 

Những phương thức chỉ có thể trả về duy nhất một giá tr, mặc dù giá trị nàcó thể là một

tập hợp c giá trị. Nếchúng tmuốn phương thtrả về nhiều hơn một giá trị thì cách thực hiện là tạcác thasố dưi hình thức tham chiếu. Khi đó trong phương thta sẽ xử lý và

 

 

 

 

gán cágiá trị mới chcác tham số tham chiếu nàykết quả là sau khi phươnthc thc hiện xong ta dùng các thasố truyn vào như là c kết quả trả v. Ví dụ 4.7 sau minh họa việtruyn tham số tham chiếu cho phương thức.

Ví dụ 4.7: Trả giá trị trả về thông qua tham số.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Time

 

{

 

public void DisplayCurrentTime()

 

{

 

Console.WriteLine(“{0}/{1}/{2}/  {3}:{4}:{5}”, DateMonth, Year, Hour, Minute, Second);

}

 

publiint GetHour()

 

{

 

return Hour;

 

}

 

public void GetTime(inhint m, ins)

 

{

 

h = Hour;

 

m =  Minute;

 

s = Second;

 

}

 

publiTime( System.DateTime dt)

 

{

 

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour;

Minute = dt.Minute; Second = dt.Second;

}

 

 

privatint Year; privatint Month; privatint Date; privatint Hour; privatint Minute; privatint Second;

 

 

 

 

 

 

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime currentTime = System.DateTime.NowTime t = neTimecurrentTime);

t.DisplayCurrentTime();

 

int theHour = 0;

 

int theMinute = 0;

 

int theSecond = 0;

 

t.GetTime( theHour, theMinute, theSecond); System.Console.WriteLine(Current time: {0}:{1}:{2},

theHour, theMinute, theSecond);

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

8/6/2002  14:15:20

 

Current time: 0:0:0

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Như  ta  thy,  kết  quả  xuất  ra  ở  dòng  cui  cùng  là  ba  giá  trị 0:0:0,  rõ  ràng  phương  thGetTime() không  thực  hin  như  mong  muốn  là  gán  giá  trị Hour,  Minute,  Second cho  c tham số truyn vào. Tức là ba tham số này đưtruyn vào dưới dng giá trị. Do đó để thc hiện như mục đích cchúng tlà lấcágiá trị của HourMinuteSecond thì phương thức GetTime() có ba tham số đưc truyn dưới dạng tham chiếu. Ta thc hiện như sau, đầu tiên, thêm là tm khai báref vào tc cátham số trong phươnthức GetTime():

public void GetTime( reint href int m, reint s)

 

{

 

h = Hour;

 

m = Minute;

 

s = Second;

 

}

 

Đithay đổi thứ hai là bổ sung cách gọi hàm GetTimđể truyn các thasố dưới dng tham chiếu như sau:

t.GetTime( ref theHour, ref theMinute, ref theSecond);

Nếu chúng ta không thc hiện bưthứ hai, tlà không đưa từ khóa rekhi gọi hàm thì trình biên dch C# sẽ báo một lỗi rng không thể chuyn tham số từ kiểinsang kiểu reint.

 

Cuối cùng khi biên dch lại chươntrình ta đưc kết quả đúng như yêcu. Bng việc khai báo tham số tham chiếu, trình biên dch sẽ truyn các tham số dưới dạng các thachiếu, thay cho việc tạo ra một bản sao ccác tham số nàyKhi đó các tham số bêtrong GetTime() sẽ tham chiếu đếcùng biến đã đưc khai báo trong hàMain(). Như vy mọi sự thay đổi với các biến này điều có hiệu ltương tự như là thay đổi trong hàm Main().

Tóm lại cơ chế truytham số dạng tham chiếu sẽ thc hiện trên chính đối tượng được đưa vào. Còn cơ chế truyn tham số giá trị thì sẽ to ra c bsac đối tượng được truyn vào, do  đó  mọi thay đổi bên trong  phương thức không làm  nh  hưởng đến  c đối tượng đưtruyn vào dưới dng giá trị.

 

Truyền tham chiếu với biến chưa khởi tạo

 

Ngôn ngữ C# bắt buộc phải thực hin một phép gán cho biến trưc khi sử dụng, do đó khi khai báo một biến như kiu cơ bn thì tc khi có lệnh nào sử dụng các biến nàthì phi có lệnh  thc  hin  việc  gán  giá  trị  xác  định  cho  biến.  Như  trong  ví  dụ  4.7  trên,  nếu  chúng  ta không khi to biến theHourtheMinutevà biếtheSecontc khi truyn như tham số vào phương thGetTime() thì trình biên dcsẽ bálỗi. Nếu chúng tslại đoạn mã của

ví dụ 4.7 như sau: int theHour; int theMinute;

int theSecond;

 

t.GetTime( reint theHour, reint theMinute, reint theSecond);

Việc sử dụnc đolnh trên không phải hoàn toàn vô lý vì mục đích cchúng tlà nhn các giá trị của đối tượng Time, việc khởi tạo giá trị của c biến đưa vào là không cần thiết. Tuy nhiên khi biên dch với đoạn mã lệnh như trên sẽ được bácác lỗi sau:

Use of unassigned local variable ‘theHour’ Use of unassigned local variable ‘theMinute’

Use of unassigned local variable ‘theSecond’

Để mở rộng chyêcầu trong trường hợp này ngôn ngữ C# cung cấp thêm một bổ sung tham chiếlà out.  Khi sử dụntham  chiếu out thì yêu cu bắt buộc phi  khởi  tạo các tham  số tham chiếu được bỏ qua. Như các tham số trong phương thGetTime(), các tham số này không cung cấp bcứ thông tin nào cho phương thc mà chỉ đơn giảlà cơ chế nhận thông tin và đưa ra bên ngoài. Do vtcó thể đánh dtất cả các tham số tham chiếu nàlà out, khi đó ta sẽ giảm đưcông việc phải khtạo các biến nàtrưc khi đưvào phươnthc. Lưu ý là bêtrong phương thức có các tham số tham chiếout thì c tham số này phải đưc gán giá trị trưc khi trả về. Ta có một số thay đổi cho phương thGetTime() như sau:

public void GetTime( out int hout inm, out int s)

 

{

 

h = Hour;

 

 

 

 

 

 

m = Minute;

 

s = Second;

 

}

 

và cách gọi mới phương thGetTime() trong Main():

 

t.GetTime( out theHourout theMinute, out theSecond);

Tóm lại ta có các cách khai báo các tham số trong một phương thức như sau: kiểu dữ liệu giá

trị đưtruyvào phương thc bằng giá trị. Sử dụng tham chiếref để truyn kiểu dữ liệu

giá trị vào phương thc dưới dạntham chiếu, cách nàcho phép vsử dụng và có khả năng thay đổi cátham số bên trong phương thc đưc gọi. Tham chiếout đưsử dụng chỉ để trả về giá trị từ một phương thc. Ví dụ 4.8 sau sử dụng ba kiểu tham số trên.

Ví dụ 4.8: Sử dụng tham số.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Time

 

{

 

public void DisplayCurrentTime()

 

{

 

Console.WriteLine(“{0}/{1}/{2}  {3}:{4}:{5}, Date, Month, Year, Hour, Minute, Second);

}

 

publiint GetHour()

 

{

 

return Hour;

 

}

 

public void SetTime(inhr, out int minref int sec)

 

{

 

// Nếu số giây truyn vào >3thì tăng số Minute và Second = 0

 

if ( sec >=30 )

 

{

 

Minute++; Second = 0;

}

 

Hour = hr; // thiết lập giá trị hr được truyn vào

 

// Trả về giá trị mi chmin và sec min = Minute;

sec = Second;

 

}

 

 

publiTime( System.DateTime dt)

 

 

 

 

 

 

 

{

 

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour;

Minute = dt.Minute; Second = dt.Second;

}

 

// biến thành viên private privatint Year;

privatint Month; privatint Date; privatint Hour; privatint Minute; privatint Second;

}

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime currentTime = System.DateTime.NowTime t = neTime(currentTime);

t.DisplayCurrentTime();

 

int theHour = 3;

 

int theMinute;

 

int theSecond = 20;

 

t.SetTime( theHour, out theMinute, ref theSecond); Console.WriteLine(“The Minute is now: {0} and {1} seconds ”,

theMinute, theSecond);

 

theSecond = 45;

 

t.SetTime( theHour, out theMinute, ref theSecond); Console.WriteLine(“The Minute is now: {0} and {1} seconds”,

theMinute, theSecond);

 

}

 

}

 

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

8/6/2002  15:35:24

 

 

 

 

 

 

 

The Minute is now: 35 and 24 seconds

 

The Minute is now: 36 and 0 seconds

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Phương thSetTime trên đã minh họa việc sử dụng ba kiểu truyn tham số vào một phương thứcThasố thứ nhất theHour đưc truyn vào dng giá trị, mục đích của tham số nàlà để thiết lp giá trị cho biến thành viên Houvà tham số này không đưsử dụng để về bất cứ giá trị o.

Tham số thứ hai là theMinutđưc truyn vào phương thức chỉ để nhận giá trị trả về của biến thành vMinute, do đó tham số này đưc khai báo với từ khóout.

Cuối cùng tham số theSeconđưc truyn vào với khai báo ref, biến thasố nàvừa dùng

để thiết lập giá trị trong phương thc. Nếu theSeconlớn hơn 30 thì giá trị ca biến thành viên Minute tăng thêm một đơn vị và biến tnh viên Second đưc thiết lập về 0. Sau cùng thì theSeconđưgán giá trị ca biếthành viên Second và đưc trả về.

Do hai biếtheHour và theSeconđưsử dụng trong phương thức SetTimnên phi đưc khởi to trưc khi truyn vào phương thc. Còn vbiếtheMinute thì không cần thiết vì nó không đưc sử dụng trong phương thc mà chỉ nhận giá tr trả v.

Nạp chồng phương thức

 

Thông thường khi xây dng cálớp, tcó mong muốn là tạo ra nhiu hàm có cùng tên. Cũng như hầu hết trong cáví dụ trưc thì c lớp đicó nhiều hơn một phương thức khi dựng. Như tronlớp Timcó các phương thc khởi dựng nhc tham số khác nhau, như tham số là đối tượng DateTime, hay tham số có thể đưc tùy chọn để thiết lập các giá trị cc biến thành viêthông qua các tham số nguyên. Tóm lại ta có thể xây dựng nhiều các phương thc cùntên nhưng nhận các tham số khác nhau. Chức năng này đưgọi là nchồng phương thức.

Một ký hiệu (signature) của một phương thc được đnh nghĩa như têcủa phương thcùng

với danh sách tham số của phươnthức. Hai phươnthc khác nhau khký hiệu ca chúng khác là khác nhau tlà khác nhau khi tên phương thc khác nhau hadanh ch tham số khác nhau. Danh ch tham số đưc xem là khác nhau bi số lượng tham số holà kiểu dữ lica tham số. Ví dụ đoạn mã sau, phươnthc thứ nht khác phương thức thứ hai do số lưng tham số khác nhau. Phương thc thứ hai khác phương thức thứ ba do kiu dữ liệu tham số khác nhau:

void myMethod( int p1 );

 

void myMethod( int p1, int p2 );

 

void myMethod( int p1, string p2 );

Một lớp có thể có bất cứ số lượng phương thc nào, nhưnmỗi phương thtrong lớp phi

có ký hiệu khác với tất cả các phương thức thành viên còn lại của lớp.

 

 

Ví dụ 4.9 minh ha lớp Time có hai phương thc khởi dựng, một phương thc nhn tham số

là một đối tượng DateTimcòn phương ththứ hai thì nhận sáu tham số nguyên.

Ví dụ 4.9: Minh họa nạp chồng phương thức khởi dựng.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Time

 

{

 

public void DisplayCurrentTime()

 

{

 

Console.WriteLine(“{0}/{1}/{2}  {3}:{4}:{5}, Date, Month, Year, Hour, Minute, Second);

}

 

publiTime( System.DateTime dt)

 

{

 

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour;

Minute = dt.Minute; Second = dt.Second;

}

 

publiTime(int Yearint Month, int Date, int Hour, int Minute, int Second)

 

{

 

this.Year = Year; this.Month = Month; this.Date = Date; this.Hour = Hour; this.Minute = Minute; this.Second = Second;

}

 

// Biến thành viên private privatint Year;

privatint Month; privatint Date; privatint Hour; privatint Minute; privatint Second;

}

 

 

 

 

 

 

 

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime currentTime = System.DateTime.NowTime t1 = neTime( currentTime); t1.DisplayCurrentTime();

Time t2 = neTime(2002,6,8,18,15,20);

 

t2.DisplayCurrentTime();

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

2/1/2002  17:50:17

 

8/6/2002  18:15:20

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Như chúng ta thy, lTime trong ví dụ minh họa 4.9 có hai phương thc khi dng. Nếu hai phương thức có cùng ký hiệu thì tnh biên dch sẽ khônthể biết đưc gọi phương thnào khi khởi tạo hai đối tượng là tvà t2Tuy nhiên, ký hiệu của hai phương thnày khác nhau vì tham số truyn vào khác nhau, do đó trình bn dch sẽ xác định đưc phương thnào đưgọi dvào các tham số.

Khi  thc  hiện  np  chng  một  phương  thc,  bt  buộc  chúng  ta  phi  thay  đổi  ký  hiu  của phương thc, số thasố, hay kiểu dữ liệu của tham số. Chúntcũncó thể toàn quyn thay đổi giá trị trả về, nhưng đâlà tùchọn. Nếu chỉ thay đổi giá trị trả về thì không phải nạp chồng phương thc  mà khi đó  hai phương thc khác nhau, và nếu to  ra hai  phương  thc cùng ký hiệu nhưng khác nhau kiểu giá trị trả về sẽ tạo ra một lỗi biên dịch.

Ví dụ 4.10: Nạp chồng phương thức.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Tester

 

{

 

privatint Triple( int val)

 

{

 

return 3*val;

 

}

 

private long Triple(long val)

 

{

 

 

return 3*val;

 

 

 

 

 

 

 

}

 

public void Test()

 

{

 

int x = 5;

 

int y = Triple(x);

 

Console.WriteLine(x: {0} y: {1}”, x, y);

 

long lx = 10;

 

long ly = Triple(lx);

 

Console.WriteLine(lx: {0} ly:{1}”, lx, ly);

 

}

 

static void Main()

 

{

 

Tester t = new Tester();

 

t.Test();

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quảx: 5 y: 15 lx: 10 ly:30

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Trong ví dụ này, lớp Testenạp chồng hai phương thTriple(), một phương thc nhn tham

số nguyêint, phương thức còlại nhận tham số là số nguyêlong. Kiểu giá trị trả về của hai phương thc khác nhau, mc dù điều này không đòi hỏi nhưng rthích hợp trong trưng hợp này.

Đóng gói dữ liu với thành phn thuộc tính

 

Thutính là khái niệm cho phétructrạng thái của lp thay vì thông qutrucậtrc  tiếp  c  biến  thành  viên,  nó  sẽ  đơc  thay  thế  bng  vic  thực  thi  truy  cập  thông  qua phương thức ca lớp.

Đây thật sự là một điềlý tưởngCác thành phn bên ngoài (client) muốn trucậtrạng thái của một đối tượng và không muốn làm vic với nhng phương thc. Tuy nhiên, người thiết kế lmuốn dtrạnthái bên trong của lớp mà anta xây dựng, và cung cấp một ch gián tiếp thông qua một phươnthc.

Thutính là một đtính mi đưc giới thiệu trong ngôn ngữ C#. Đặc tính nàcung cp khả năng bảo vệ trưng dữ liệu bên trong một lp bng vic đọc và viết chúng thông qua thuc  tính.  Trong  ngôn  ngữ  khác,  điu  này  có  thể  đưc  thc  hin  thông  qua  việc  tạo  các phương thức lấy dữ liệu (getter method) và phương thức thiết lập dữ liệu (setter method).

Thutính được thiết kế nhắm vào hai mục đích: cung cp một giao diện đơn cho phép trucập c biến thành viên, Tuy nhiên cácthức thc thi truy cậgiống như phương thức trong đó dữ liệu đưc che dấu, đảm bảo cho yêu cthiếkế hưng đối tưng. Để hiểu rõ

đặc tính nàta sẽ xem ví dụ 4.11 bên dưới:

Ví dụ 4.11: Sử dụng thuc tính.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public class Time

 

{

 

public void DisplayCurrentTime()

 

{

 

Console.WriteLine(“Time\t: {0}/{1}/{2} {3}:{4}:{5}”, date, month, yearhour, minute, second);

}

 

publiTime( System.DateTime dt)

 

{

 

year = dt.Year; month = dt.Month; date = dt.Day;

hour = dt.Hourminute = dt.Minute; second = dt.Second;

}

 

publiint Hour

 

{

 

 

get

 

{

 

 

}

 

set

 

{

 

 

}

 

}

 

 

 

 

 

return hour;

 

 

 

 

 

 

hour = value;

 

 

// Biến thành viên private privatint year;

privatint month;

 

privatint date;

 

 

 

 

 

 

 

privatint hour;

 

privatint minute;

 

privatint second;

 

}

 

public class Tester

 

{

 

static void Main()

 

{

 

System.DateTime currentTime = System.DateTime.NowTime t = neTimecurrentTim)t.DisplayCurrentTime();

// Ldữ liệtừ thutính Hour int theHour = t.Hour;

Console.WriteLine(“ Retrieved the hour: {0}”, theHour);

 

theHour++;

 

t.Hour = theHour;

 

Console.WriteLine(“Updated the hour: {0}, theHour);

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

Time    : 2/1/2003 17:55:1

 

Retrieved the hour: 17

 

Updated the hour: 18

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Để khai báo thuộc tính, đầu tiêlà khai báo tên thuc tính để trucập, tiếp theo là phần thân định nghĩthuộc tính ntrong cdu ({}). Bên tronthân cthuộc tính là khai báo hai

bộ trucậly và thiết lập dữ liệu:

 

publiint Hour

 

{

 

get

 

{

 

 

}

 

set

 

{

 

 

}

 

 

 

 

 

return hour;

 

 

 

 

 

 

hour = value;

 

 

 

 

 

 

 

 

}

Mỗi bộ truy cp đưc khai báo riêng biệt để làm hai công vic khác nhalà ly hay thiết lập

giá trị cho thuc tính. Giá trị thuc tính có thể đưlưtrong cơ sở dữ liu, khi đó trong phần thân ca bộ truy cp sẽ thc hiện công việc tương tác với cơ sở dữ lịêu. Hoặlà giá trị thuc tính đưlưu trữ trong các biến thành vca lớp như trong ví d:

privatint hour;

 

Truy cập lấy dữ liệu (get accessor)

 

Phần khai báo tương tự như một phương thcủa lp dùng để trả về một đối tượncó kiểu dữ licủa thuc tính. Trong ví dụ trên, bộ truy cập ly dữ liệu gecủa thuc tính Houng tương tự như một phương thức trả về một giá trị int. Nó trả về giá trị của biến thành viên hour nơi mà giá trị của thuộc tính Houlưtr:

get

 

{

 

return hour;

 

}

 

Trong ví dụ này, một biến thành viên cc bộ đưtrả về, nhưng nó cũng có thể truy cập dễ dàng một giá trị nguyêtừ cơ sở dữ lịêu, hay thc hiện việtính toán tùy ý.

Bcứ khi nàchúng ta tham chiếu đến một thuộc tính hay là gán giá trị thuc tính cho một biến thì bộ trucập ly dữ liget sẽ đưc thực hiện để đọc giá trị của thuộc tính:

Time t = neTimecurrentTim);

 

int theHour = t.Hour;

Khi lệnh thứ hai đưc thc hiện thì giá trị của thuc tính sẽ đưtrả v, tlà bộ trucập ly dữ lịêget sẽ đưc thực hiện và kết quả là giá trị ca thuc tính đưc gán cho biến cục bộ theHour.

 

Bộ truy cập thiếlập dữ liệu ( seaccessor)

 

Bộ truy cp nàsẽ thiếlập một giá trị mới cho thutính và tương tự như một phương thức trả về một giá trị void. Khi đnh nghĩa bộ trucập thiết lp dữ lịêcng ta phải sử dụng từ khóa value để đại dicho tham số đưtruyền vào và đượlưtrữ bi thutính:

 

set

 

{

 

hour = value;

 

}

Như đã nói trưc, do ta đang khai báo thuc tính lưu trữ dưi dạng biến thành viên nêtrong phthâcủa bộ truy ctchỉ sử dụng biến thành viên mà thôi. Bộ truy cập thiết lập hoàn toàn cho phép chúng ta có thể viết giá trị vàtrong cơ sở dữ lêu hay cp nhbcứ biến thành vn nào khác của lớp nếcần thiết.

 

Khi cnta gán một giá trị cho thutính thì bộ trucp thiếlập dữ liset sẽ đưtự động thc hiện và một tham số ngầm định sẽ đưtạo ra để lưu giá trị mà ta muốn gán:

theHour++;

 

t.Hour = theHour;

 

Lợi ích của hưng tiếp cận nàcho phép các thành phần bên ngoài (client) có thể tươncvới thutính một cáctrực tiếp, mà không phải hy sinh việche du dữ lêu cũng như đặc tính đóng gói dữ lịêu trong thiết kế hướng đối tưng.

Thuộc tính chỉ đọc

 

Giả sử chúng ta muốn tạo một phiên bn khácho lớp Timcung cấp một số giá trị static để hiển thị ngày và giờ hiện hành. Ví dụ 4.12 minh họa chcách tiếp cận này.

Ví dụ 4.12: Sử dụng thuc tính hằng static.

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

public clasRightNow

 

{

 

// Định nghĩa bộ khi to static cho các biến static static RightNow()

{

 

System.DateTime dt = System.DateTime.Now; Year = dt.Year;

Month = dt.Month; Date = dt.Day; Hour = dt.Hour;

Minute = dt.Minute; Second = dt.Second;

}

 

// Biến thành viên static public static int Year; public static int Month; public static int Date; public static int Hour; public static int Minute; public static int Second;

}

 

public class Tester

 

{

 

static void Main()

 

 

 

 

 

 

{

 

Console.WriteLine(“This year: {0}”, RightNow.Year.ToString());

RightNow.Year = 2003; Console.WriteLine(“This year: {0}”,

RightNow.Year.ToString());

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Kết quả:

 

This year: 2002

 

This year: 2003

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Đoạn chươntrình trên hoạt động tt, tuy nhiên cho đến khi có một ai đó thay đổi giá trị của biến thành vnày. Như ta thấy, biến thành Year trên đã đưc thay đổi đến 2003. Điều này thực sự không như mong muốn ca chúng ta.

Chúng tmuốn đánh dcác thuộc tính tĩnh này không đưc thay đổi. Nhưng khai báo hằng cũng không được vì biến tĩnh không đưc khtạo cho đến khi phương thc khi dng static đưc thi hành. Do vCcung cấp thêm từ khóreadonly phc vụ chính xác cho mục đich trên. Với ví dụ trêtcó cách khabáo lại như sau:

public static readonly int Year; public static readonly int Month; public static readonly int Date; public static readonly int Hour; public static readonly int Minute; public static readonly int Second;

Khi đó ta phải bỏ lnh gán biến thành viên Year, vì nếu không sẽ bị báli:

 

// RightNow.Year = 2003; // error

Chương trình sau khi biên dch và thc hiện như mục đích ca chúnta.

 

Câu hỏi và trả li

 

Câuhỏi 1: Có phi chúntchỉ nên sử dụng lớp với các dữ liệu thành viên?

Trả lời 1Nói chung là chúng ta không nêsử dụng lớp chỉ với dữ liệu thành viên. Ý nghĩa của môt lớp hay ca lập trình hướng đi tượng là khả năng đóng gói cáchc năng và dữ liệu vào trong một gói đơn.

Câu hỏi 2: Có phtất cả nhng dữ liệu thành vn luôn luôn đưc khai bálà publiđể bên ngoài có thể truy cập chúng?

Trả lời 2:  Nói chung là không. Do vấn đề che dấu dữ liệu trong lập trình hướng đối tưng,

xu hưng là dữ liệu bêtrong chỉ nên dùng cho các phương thức thành viên. Tuy nhiên, như chúng ta đã  biết khái niệm thuc tính  cho  phép các biến thành  viên được truy cập  từ bên ngoài thông qua hình thc như là phương thức.

Câuhỏi 3: Có phi có rt nhiều lớp đưc xây dựng sẵn và tôi có thể tìm chúng ở đâu?

Trả lời 3: Microsoft cung cấp rất nhiu các lp gọi là các lớp cơ sở .NET. Nhng lớp này đưtổ chc bêtrong các namespace. Chúng ta có thể tìm tài liệu về cálớp này trong thư vin trc tuyếcủa Microsoft. Và một số lp thường sử dụng cũng đưc trình bày lần lượt trong các ví dụ ca giáo trình này.

Câuhỏi 4: Sự khác nhau gia tham số (parameter) và đối mục (argument)?

Trả lời 4Tham số đưc định nghĩa là nhng thứ được truyền vào trong một phương thức. Một tham số xuất hiện với đnh nghĩa của phương thức ở đầu phương thc. Một đối mc là giá trị đưc truyền vào phương thức. Chúng ttruyền nhng đối mvào phương thức phù hợp với những tham số đã khai báo ca phương thức.

Câuhỏi 5: Chúng tcó thể tạo phương thbên ngoàcủa lớp hay không?

Trả lời 5: Mặc dù trong  những ngôn  ngữ  kc,  chúng  ta  có  thể tạo các phương thức  bên ngoài  của  lớp.  Nhưng  trong  C#  thì  không,  C#  là  hưng  đối  tượng,  do  vậy  tất  cả  các  mã nguồn phải được đặt bên trong một lớp.

Câu hỏi 6: Có phải những phương thvà lớp trong C# hot động tươntự như trong các ngôn ngữ khác như C++ hay Java?

Trả lời 6Trong hầu hết các phần thì chúng tương tự như nhau. Tuy nhiên, mỗi ngôn ngữ cũng có những khác biệt riêng. Một ví dụ sự khác nhau là C# không cho phép tham số mc định  bên  trong  một  phương  thc.  Trong  ngôn  ngữ  C++  thì  chúng  ta  có  thể  khai  báo  các tham số mc định lúc đnh nghĩa phương thức và khi gọi phương thc thì có thể không cần truygiá trị vào, phương thc sẽ dùng giá trị mc định. Trong C# thì không đưc phép. Nói chung là còn nhiều sự khác nhau nữa, nhưng xin dành cho bạn đc tự tìm hiểu.

Câu hỏi 7Phương thức tĩnh  có thể trucập đưc thành viên nào và không truy cập đưc thành vn nào trong một lớp?

Trả lời 7Phương thức tĩnh chỉ truy cập được các thành vn tĩnh trong một lp.

 

Câu hỏi thêm

 

Câu hỏi 1: Sự khác nhau giữa thành viên đưkhai báo là publivà các thành viên không đưc khai báo là public?

Câuhỏi 2Từ khoá nào đưsử dụng trong việc thực thi thuộc tính của lp?

 Câuhỏi 3: Nhng kiu dữ liệu nào được trả về từ phương thức?

Câu hỏi 4:  Sự  khác  nhau  giữa  truyền  biến  tham  chiếu  và  truyền  biến  tham  trị  vào  một phương thức?

Câuhỏi 5: Làm sao truyền tham chiếu với biến kiểu giá trị vào trong một phương thức?

Câuhỏi 6: Khi nào thì phương thức khi dựng đưc gọi?

Câuhỏi 7Pơng thức khởi dựng tĩnh được gọi khi nào?

Câuhỏi 8: Có thể truyền biến chưa khởi tạo vào một hàm đưkhông?

Câuhỏi 9: Sự khác nhau giữa một lớp và một đối tượng của lớp?

Câu hỏi 10: Thành viên nào trong một lớp có thể đưc truy cập mà không phải tạo thể hin của lớp?

Câuhỏi 11Lớp mà chúng ta xây dựng thuộc kiểu dữ liệu nào?

 Câuhỏi 12Từ khóa this đưc dùng làm gì trong một lớp?

Bài tập

 

Bài tập 1: Xây dng một lớp đường tròn lưu giữ bán kính và tâm của đưng tròn. Tạo các phương thức để tính chu vi, diện tích của đường tròn.

Bài tập2Thêm thuộc tính BanKinh vào lớp được tạo ra từ bài tập 1.

Bài tập 3Tạo ra một lp lưu trữ giá trị nguyên têmyNumber. Tạo thutính cho thành viên này. Khi số đưc lưu trữ thì nhân cho 100. Và khi số đưc truy cập thì chicho 100.

Bài tập 4Cơng trình sau có lỗi. Hãy sửa lỗi của chương trình và biên dcchương trình. Dòng lnh nào gây ra lỗi?

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

using System;

 

using System.Console;

 

class VD1

 

{

 

public string first;

 

}

 

class Tester

 

{

 

public static void Main()

 

{

 

VD1 vd = new VD1(); Write(“Nhap vao mot chuoi: ”); vd.first = ReadLine();

Write(“Chuoi nhap vao: {0}”, vd.first);

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Bài tập 5Cơng trình sau có lỗi. Hãy sửa lỗi của chương trình và biên dcchương trình. Dòng lnh nào gây ra lỗi?

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

 

 

 

 

 

class Class1

 

{

 

public static void GetNumber(ref int x, reint y)

 

{

 

x = 5;

 

y = 10;

 

}

 

public static void Main()

 

{

 

int a = 0, b = 0; GetNumber(a, b);

System.Console.WriteLine(a = {0} \nb = {1}a, b);

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Câuhỏi 6: Chương trình sau đây có lỗi. Hãy sửa lỗi và cho biết lệnh nào phát sinh lỗi?

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

 

Class Tester

 

{

 

public static void Main()

 

{

 

Display();

 

}

 

public static void Display()

 

{

 

System.Console.WriteLine(Hello!);

 

return 0;

 

}

 

}

 

—-—-—-—-—-—-—-—-—-—-—-—-—-—-

Câu hỏi 7: Viết lớp giải phương trình bậc hai. Lớp này có các thutính a, b, c và nghiệm

x1,  x2Hãy xây dng theo hướng đối tượng lp trên. Lớp cho phép bên ngoài xem đưcác nghiệm ca phương trình và cho pp thiết lập hay xecác giá trị a, b, c.

 

Hết chương 4.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Leave A Reply

Your email address will not be published.