Sử dụng thành viên tĩnh (static member) Sử dụng thành viên tĩnh (static member) Bởi: Khuyet Danh Sử dụng thành viên tĩnh(static member) Chúng ta truy cập đến thành viên tĩnh lớp thông qua tên lớp khai báo Ví dụ có lớp tên Button có hai thể lớp tên btnUpdate btnDelete Và giả sử lớp Button có phương thức tĩnh Show() Để truy cập phương thức tĩnh ta viết : Button.Show(); Đúng viết: btnUpdate.Show(); Trong ngôn ngữ C# không cho phép truy cập đến phương thức tĩnh biến thành viên tĩnh thông qua thể hiện, cố làm điều trình biên dịch C# báo lỗi, điều khác với ngôn ngữ C++ Trong số ngôn ngữ có phân chia phương thức lớp phương thức khác (toàn cục) tồn bên không phụ thuộc lớp Tuy nhiên, điều không cho phép C#, ngôn ngữ C# không cho phép tạo phương thức bên lớp, ta tạo phương thức giống cách tạo phương thức tĩnh bên lớp Phương thức tĩnh hoạt động nhiều giống phương thức toàn cục, ta truy cập phương thức mà không cần phải tạo thể hay đối tượng lớp chứa phương thức toàn cục Tuy nhiên, lợi ích phương thức tĩnh vượt xa phương thức toàn cục phương thức tĩnh bao bọc phạm vi lớp nơi định nghĩa, ta không gặp tình trạng lộn xộn phương thức trùng tên chúng đặt namespace 1/9 Sử dụng thành viên tĩnh (static member) Chúng ta không nên bị cám dỗ việc tạo lớp chứa toàn phương thức linh tinh Điều tiện cho công việc lập trình điều không mong muốn giảm tính ý nghĩa việc thiết kế hướng đối tượng Vì đặc tính việc tạo đối tượng xây dựng phương thức hành vi xung quanh thuộc tính hay liệu đối tượng Gọi phương thức tĩnh Như biết phương thức Main() phương thức tĩnh Phương tĩnh xem phần hoạt động lớp thể lớp Chúng không cần có tham chiếu this hay thể tham chiếu tới Phương thức tĩnh truy cập trực tiếp đến thành viên tính chất tĩnh (nonstatic) Như Main() gọi phương thức không tĩnh bên lớp Ta xem lại đoạn chương trình minh họa ví dụ trướ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, var2 ); } } Phương thức SomeMethod() phương thức không tĩnh lớp Class1, để truy cập phương thức lớp cấn phải tạo thể đối tượng cho lớp Class1 Sau tạo thông qua đối tượng c ta gọi được phương thức SomeMethod() Sử dụng khởi dựng tĩnh Nếu lớp khai báo khởi tạo tĩnh (static constructor), đảm bảo phương thức khởi dựng tĩnh thực trước thể lớp tạo Chúng ta điều khiển xác phương thức khởi dựng tĩnh thực Tuy nhiên ta biết thực sau chương trình chạy trước biến đối tượng tạo Ta thêm khởi dựng tĩnh cho lớp ThoiGian sau: 2/9 Sử dụng thành viên tĩnh (static member) static ThoiGian() { Ten = "Thoi gian"; } Ở thuộc tính truy cập public trước khởi dựng tĩnh Thuộc tính truy cập không cho phép theo sau phương thức khởi dựng tĩnh Do phương thức tĩnh nên truy cập biến thành viên không thuộc loại tĩnh Vì biến thành viên Name bên phải khai báo tĩnh: private static string Ten; Cuối ta thêm dòng vào phương thức ThoiGianHienHanh() 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 thay đổi ta biên dịch chạy chương trình kết sau: Ten: Thoi Gian Thoi Gian: 5/6/2002 18:35:20 Mặc dù chương trình thực tốt, không cần thiết phải tạo khởi dựng tĩnh để phục vụ cho mục đích Thay vào ta dùng chức khởi tạo biến thành viên sau: private static string Ten = "Thoi Gian"; Tuy nhiên, khởi tạo tĩnh có hữu dụng cần cài đặt số công việc mà thực thông qua chức khởi dựng công việc cài đặt thực lần Sử dụng khởi dựng private Như nói ngôn ngữ C# phương thức toàn cục số toàn cục Do tạo lớp tiện ích nhỏ để chứa phương thức tĩnh Cách thực có hai mặt tốt không tốt Nếu tạo lớp tiện ích không muốn thể tạo Để ngăn ngừa việc tạo thể lớp ta tạo khởi dựng tham số không làm cả, tức bên thân phương thức rỗng, thêm vào phương thức đánh dầu private Do khởi dựng public, nên tạo thể lớp 3/9 Sử dụng thành viên tĩnh (static member) Sử dụng thuộc tính tĩnh Một vấn đề đặt kiểm soát số thể lớp tạo thực chương trình Vì hoàn toàn ta tạo biến toàn cục để làm công việc đếm số thể lớp Thông thường biến thành viên tĩnh dùng để đếm số thể được tạo lớp Cách sử dụng áp dụng minh họa sau: Sử dụng thuộc tính tĩnh để đếm số thể 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 { 4/9 Sử dụng thành viên tĩnh (static member) static void Main() { Cat.HowManyCats(); Cat mun = new Cat(); Cat.HowManyCats(); Cat muop = new Cat(); Cat miu = new Cat(); Cat.HowManyCats(); } } Kết quả: cats cats cats Bên lớp Cat ta khai báo biến thành viên tĩnh tên instance biến dùng để đếm số thể lớp Cat, biến khởi tạo giá trị Lưu ý biến thành viên tĩnh xem thành phần lớp, thành viên thể hiện, không khởi tạo trình biên dịch tạo thể Khởi tạo tường minh yêu cầu bắt buộc với biến thành viên tĩnh Khi thể tạo dựng lớp Cat thực tăng biến instance lên đơn vị Hủy đối tượng Ngôn ngữ C# cung cấp chế thu dọn (garbage collection) không cần phải khai báo tường minh phương thức hủy Tuy nhiên, làm việc với đoạn mã 5/9 Sử dụng thành viên tĩnh (static member) không quản lý cần phải khai báo tường minh phương thức hủy để giải phóng tài nguyên C# cung cấp ngần định phương thức để thực điều khiển công việc này, phương thức Finalize() hay gọi kết thúc Phương thức Finalize gọi chế thu dọn đối tượng bị hủy Phương thức kết thúc giải phóng tài nguyên mà đối tượng nắm giữ, không tham chiếu đến đối tượng khác Nếu với đoạn mã bình thường tức chứa tham chiếu kiểm soát không cần thiết phải tạo thực thi phương thức Finalize() Chúng ta làm điều xử lý tài nguyên không kiểm soát Chúng ta không gọi phương thức Finalize() đối tượng cách trực tiếp, ngoại trừ gọi phương thức lớp sở bên phương thức Finalize() Trình thu dọn thực việc gọi Finalize() cho Bộ hủy C# Cú pháp phương thức hủy ngôn ngữ C# giống ngôn ngữ C++ Nhưng hành động cụ thể chúng có nhiều điểm khác Ta khao báo phương thức hủy C# sau: ~Class1() {} Tuy nhiên, ngôn ngữ C# cú pháp khai báo shortcut liên kết đến phương thức kết thúc Finalize kết với lớp sở, viết ~Class1() { // Thực số công việc } Cũng tương tự viết : Class1.Finalize() { // Thực số công việc base.Finalize(); } 6/9 Sử dụng thành viên tĩnh (static member) Do tương tự nên khả dẫn đến lộn xộn nhầm lẫn không tránh khỏi, nên phải tránh viết phương thức hủy viết phương thức Finalize tường minh Phương thức Dispose Như biết việc gọi phương thức kết thúc Finalize C# không hợp lệ, phương thức dành cho thu dọn thực Nếu xử lý tài nguyên không kiểm soát xử lý handle tập tin ta muốn đóng hay giải phóng nhanh chóng lúc nào, ta có thực thi giao diện IDisposable, phần chi tiết IDisposable trình bày chi tiết Chương Giao diện IDisposable yêu cầu thành phần thực thi định nghĩa phương thức tên Dispose() để thực công việc dọn dẹp mà ta yêu cầu Ý nghĩa phương thức Dispose cho phép chương trình thực công việc dọn dẹp hay giải phóng tài nguyên mong muốn mà chờ phương thức Finalize() gọi Khi cung cấp phương thức Dispose phải ngưng thu dọn gọi phương thức Finalize() đối tượng Để ngưng thu dọn, gọi phương thức tĩnh lớp GC (garbage collector) GC.SuppressFinalize() truyền tham số tham chiếu this đối tượng Và sau phương thức Finalize() sử dụng để gọi phương thức Dispose() đoạn mã sau: public void Dispose() { // Thực công việc dọn dẹp // Yêu cầu thu dọc GC thực kết thúc GC.SuppressFinalize( this ); } public override void Finalize() { Dispose(); base.Finalize(); } Phương thức Close Khi xây dựng đối tượng, có muốn cung cấp cho người sử dụng phương thức Close(), phương thức Close tự nhiên phương thức Dispose đối tượng có liên quan đến xử lý tập tin Ta xây dựng phương thức Dispose() với thuộc tính private phương thức Close() với thuộc tính public Trong phương thức Close() đơn giản gọi thực phương thức Dispose() Câu lệnh using Khi xây dựng đối tượng chắn người sử dụng gọi hàm Dispose() Và không kiểm soát lúc thu dọn GC thực việc dọn dẹp Do để cung cấp khả mạnh để kiểm soát việc giải phóng tài nguyên C# đưa cú pháp dẫn using, cú pháp đảm bảo phương 7/9 Sử dụng thành viên tĩnh (static member) thức Dispose() gọi sớm Ý tưởng khai báo đối tượng với cú pháp using sau tạo phạm vi hoạt động cho đối tượng khối bao dấu ({}) Khi khối phạm vi kết thúc, phương thức Dispose() đối tượng gọi cách tự động Sử dụng dẫn using using System.Drawing; class Tester { public static void Main() { using ( Font Afont = new Font("Arial",10.0f)) { // Đoạn mã sử dụng AFont }// Trình biên dịch gọi Dispose để giải phóng AFont Font TFont = new Font("Tahoma",12.0f); using (TFont) { // Đoạn mã sử dụng TFont }// Trình biên dịch gọi Dispose để giải phóng TFont } 8/9 Sử dụng thành viên tĩnh (static member) } Còn phần khai báo thứ hai, đối tượng Font tạo bên câu lệnh using Khi định dùng đối tượng ta đặt vào câu lệnh using Và tương tự khối câu lệnh using thực xong phương thức Dispose() font gọi 9/9 ... phương thức đánh dầu private Do khởi dựng public, nên tạo thể lớp 3/9 Sử dụng thành viên tĩnh (static member) Sử dụng thuộc tính tĩnh Một vấn đề đặt kiểm soát số thể lớp tạo thực chương trình Vì... làm công việc đếm số thể lớp Thông thường biến thành viên tĩnh dùng để đếm số thể được tạo lớp Cách sử dụng áp dụng minh họa sau: Sử dụng thuộc tính tĩnh để đếm số thể ... Ta thêm khởi dựng tĩnh cho lớp ThoiGian sau: 2/9 Sử dụng thành viên tĩnh (static member) static ThoiGian() { Ten = "Thoi gian"; } Ở thuộc tính truy cập public trước khởi dựng tĩnh Thuộc tính truy