THỰC THI GIAO DIỆN phần 2

Chia sẻ: Tuan Bui Nghia | Ngày: | Loại File: PDF | Số trang:18

0
59
lượt xem
10
download

THỰC THI GIAO DIỆN phần 2

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Bổ sung thêm phần khai báo giao diện ICompressible và định nghĩa các phương thức của giao diện bên trong lớp Document. Sau khi tạo thể hiện lớp Document và gọi các phương thức từ giao diện ta có kết quả tương tự như sau: Creating document with: Test Document Implementing the Read Method for IStorable Implementing

Chủ đề:
Lưu

Nội dung Text: THỰC THI GIAO DIỆN phần 2

  1. Do đó Document cũng phải thực thi những phương thức được xác nhận trong giao diện ICompressible: public void Compress() { Console.WriteLine(“Implementing the Compress Method”); } public void Decompress() { Console.WriteLine(“Implementing the Decompress Method”); } Bổ sung thêm phần khai báo giao diện ICompressible và định nghĩa các phương thức của giao diện bên trong lớp Document. Sau khi tạo thể hiện lớp Document và gọi các phương thức từ giao diện ta có kết quả tương tự như sau: Creating document with: Test Document Implementing the Read Method for IStorable Implementing Compress Mở rộng giao diện C# cung cấp chức năng cho chúng ta mở rộng một giao diện đã có bằng cách thêm các phương thức và các thành viên hay bổ sung cách làm việc cho các thành viên. Ví dụ, chúng ta có thể mở rộng giao diện ICompressible với một giao diện mới là ILoggedCompressible. Giao diện mới này mở rộng giao diện cũ bằng cách thêm phương thức ghi log các dữ liệu đã lưu: interface ILoggedCompressible : ICompressible { void LogSavedBytes(); } Các lớp khác có thể thực thi tự do giao diện ICompressible hay ILoggedCompressible tùy thuộc vào mục đích có cần thêm chức năng hay không. Nếu một lớp thực thi giao diện ILoggedCompressible, thì lớp này phải thực thi tất cả các phương thức của cả hai giao diện ICompressible và giao diện ILoggedCompressible. Những đối tượng của lớp thực thi giao diện ILoggedCompressible có thể được gán cho cả hai giao diện ILoggedCompressible và ICompressible. Kết hợp các giao diện Một cách tương tự, chúng ta có thể tạo giao diện mới bằng cách kết hợp các giao diện
  2. cũ và ta có thể thêm các phương thức hay các thuộc tính cho giao diện mới. Ví dụ, chúng ta quyết định tạo một giao diện IStorableCompressible. Giao diện mới này sẽ kết hợp những phương thức của cả hai giao diện và cũng thêm vào một phương thức mới để lưu trữ kích thước nguyên thuỷ của các dữ liệu trước khi nén: interface IStorableCompressible : IStoreable, ILoggedCompressible { void LogOriginalSize(); } Ví dụ 8.2: Minh họa việc mở rộng và kết hợp các giao diện. ----------------------------------------------------------------------------- using System; interface IStorable { void Read(); void Write(object obj); int Status { get; set;} } // giao diện mới interface ICompressible { void Compress(); void Decompress(); } // mở rộng giao diện interface ILoggedCompressible : ICompressible { void LogSavedBytes(); } // kết hợp giao diện interface IStorableCompressible : IStorable, ILoggedCompressible { void LogOriginalSize(); } interface IEncryptable { void Encrypt(); void Decrypt(); } publi
  3. c class Document : IStorableCompressible, IEncryptable {
  4. // bộ khởi tạo lớp Document lấy một tham số public Document( string s) { Console.WriteLine(“Creating document with: {0}”, s); } // thực thi giao diện IStorable public void Read() { Console.WriteLine(“Implementing the Read Method for IStorable”); } public void Write( object o) { Console.WriteLine(“Implementing the Write Method for IStorable”); } public int Status { get { return status; } set { status = value; } } // thực thi ICompressible public void Compress() { Console.WriteLine(“Implementing Compress”); } public void Decompress() { Console.WriteLine(“Implementing Decompress”); } // thực thi giao diện ILoggedCompressible public void LogSavedBytes() {
  5. Console.WriteLine(“Implementing LogSavedBytes”);
  6. } // thực thi giao diện IStorableCompressible public void LogOriginalSize() { Console.WriteLine(“Implementing LogOriginalSize”); } // thực thi giao diện public void Encrypt() { Console.WriteLine(“Implementing Encrypt”); } public void Decrypt() { Console.WriteLine(“Implementing Decrypt”); } // biến thành viên lưu dữ liệu cho thuộc tính private int status = 0; } public class Tester { public static void Main() { // tạo đối tượng document Document doc = new Document(“Test Document”); // gán đối tượng cho giao diện IStorable isDoc = doc as IStorable; if ( isDoc != null) { isDoc.Read(); } else { Console.WriteLine(“IStorable not supported”); } ICompressible icDoc = doc as ICompressible; if ( icDoc != null )
  7. { icDoc.Compress() ;
  8. } else { Console.WriteLine(“Compressible not supported”); } ILoggedCompressible ilcDoc = doc as ILoggedCompressible; if ( ilcDoc != null ) { ilcDoc.LogSavedBytes(); ilcDoc.Compress(); // ilcDoc.Read(); // không thể gọi được } else { Console.WriteLine(“LoggedCompressible not supported”); } IStorableCompressible isc = doc as IStorableCompressible; if ( isc != null ) { isc.LogOriginalSize(); // IStorableCompressible isc.LogSavedBytes(); // ILoggedCompressible isc.Compress(); // ICompress isc.Read(); // IStorable } else { Console.WriteLine(“StorableCompressible not supported”); } IEncryptable ie = doc as IEncryptable; if ( ie != null ) { ie.Encrypt(); } else { Console.WriteLine(“Encryptable not } supported”); }
  9. } ----------------------------------------------------------------------------- Kết quả: Creating document with: Test Document Implementing the Read Method for IStorable Implementing Compress Implementing LogSavedBytes Implementing Compress Implementing LogOriginalSize Implementing LogSaveBytes Implementing Compress Implementing the Read Method for IStorable Implementing Encrypt ----------------------------------------------------------------------------- Ví dụ 8.2 bắt đầu bằng việc thực thi giao diện IStorable và giao diện ICompressible. Sau đó là phần mở rộng đến giao diện ILoggedCompressible rồi sau đó kết hợp cả hai vào giao diện IStorableCompressible. Và giao diện cuối cùng trong ví dụ là IEncrypt. Chương trình Tester tạo đối tượng Document mới và sau đó gán lần lượt vào các giao diện khác nhau. Khi một đối tượng được gán cho giao diện ILoggedCompressible, chúng ta có thể dùng giao diện này để gọi các phương thức của giao diện ICompressible bởi vì ILogged- Compressible mở rộng và thừa kế các phương thức từ giao diện cơ sở: ILoggedCompressible ilcDoc = doc as ILoggedCompressible; if ( ilcDoc != null ) { ilcDoc.LogSavedBytes(); ilcDoc.Compress(); // ilcDoc.Read(); // không thể gọi được } Tuy nhiên, ở đây chúng ta không thể gọi phương thức Read() bởi vì phương thức này của giao diện IStorable, không liên quan đến giao diện này. Nếu chúng ta thêm lệnh này vào thì chương trình sẽ biên dịch lỗi. Nếu chúng ta gán vào giao diện IStorableCompressible, do giao diện này kết hợp hai giao diện IStorable và giao diện ICompressible, chúng ta có thể gọi tất cả những phương thức của IStorableCompressible, ICompressible, và IStorable:
  10. IStorableCompressible isc = doc as IStorableCompressible; if ( isc != null ) { isc.LogOriginalSize(); // IStorableCompressible
  11. isc.LogSaveBytes(); // ILoggedCompressible isc.Compress(); // ICompress isc.Read(); // IStorable } Truy cập phương thức giao diện Chúng ta có thể truy cập những thành viên của giao diện IStorable như thể là các thành viên của lớp Document: Document doc = new Document(“Test Document”); doc.status = -1; doc.Read(); hay là ta có thể tạo thể hiện của giao diện bằng cách gán đối tượng Document cho một kiểu dữ liệu giao diện, và sau đó sử dụng giao diện này để truy cập các phương thức: IStorable isDoc = (IStorable) doc; isDoc.status = 0; isDoc.Read(); Ghi chú: Cũng như đã nói trước đây, chúng ta không thể tạo thể hiện của giao diện một cách trực tiếp.Do đó chúng ta không thể thực hiện như sau: IStorable isDoc = new IStorable(); Tuy nhiên chúng ta có thể tạo thể hiện của lớp thực thi như sau: Document doc = new Document(“Test Document”); Sau đó chúng ta có thể tạo thể hiện của giao diện bằng cách gán đối tượng thực thi đến kiểu dữ liệu giao diện, trong trường hợp này là IStorable: IStorable isDoc = (IStorable) doc; Chúng ta có thể kết hợp những bước trên như sau: IStorable isDoc = (IStorable) new Document(“Test Document”); Nói chung, cách thiết kế tốt nhất là quyết định truy cập những phương thức của giao diện thông qua tham chiếu của giao diện. Do vậy cách tốt nhất là sử dụng isDoc.Read(), hơn là sử dụng doc.Read() trong ví dụ trước. Truy cập thông qua giao diện cho phép chúng ta đối xử giao diện một cách đa hình. Nói cách khác, chúng ta tạo hai hay nhiều hơn những lớp thực thi giao diện, và sau đó bằng cách truy cập lớp này chỉ thông qua giao diện. Gán đối tượng cho một giao diện Trong nhiều trường hợp, chúng ta không biết trước một đối tượng có hỗ trợ một giao diện đưa ra. Ví dụ, giả sử chúng ta có một tập hợp những đối tượng
  12. Document, một vài đối tượng đã được lưu trữ và số còn lại thì chưa. Và giả sử chúng ta đã thêm giao diện giao diện thứ hai, ICompressible cho những đối tượng để nén dữ liệu và truyền qua mail nhanh chóng: interface ICompressible {
  13. void Compress(); void Decompress(); } Nếu đưa ra một kiểu Document, và ta cũng không biết là lớp này có hỗ trợ giao diện IStorable hay ICompressible hoặc cả hai. Ta có thể có đoạn chương trình sau: Document doc = new Document(“Test Document”); IStorable isDoc = (IStorable) doc; isDoc.Read(); ICompressible icDoc = (ICompressible) doc; icDoc.Compress(); Nếu Document chỉ thực thi giao diện IStorable: public class Document : IStorable phép gán cho ICompressible vẫn được biên dịch bởi vì ICompressible là một giao diện hợp lệ. Tuy nhiên, do phép gán không hợp lệ nên khi chương trình chạy thì sẽ tạo ra một ngoại lệ (exception): A exception of type System.InvalidCastException was thrown. Phần ngoại lệ sẽ được trình bày trong Chương 11. Toán tử is Chúng ta muốn kiểm tra một đối tượng xem nó có hỗ trợ giao diện, để sau đó thực hiện các phương thức tương ứng. Trong ngôn ngữ C# có hai cách để thực hiện điều này. Phương pháp đầu tiên là sử dụng toán tử is. Cú pháp của toán tử is là: is Toán tử is trả về giá trị true nếu biểu thức thường là kiểu tham chiếu có thể được gán an toàn đến kiểu dữ liệu cần kiểm tra mà không phát sinh ra bất cứ ngoại lệ nào. Ví dụ 8.3 minh họa việc sử dụng toán tử is để kiểm tra Document có thực thi giao diện IStorable hay ICompressible. Ví dụ 8.3: Sử dụng toán tử is. ----------------------------------------------------------------------------- using System; interface IStorable { void Read(); void Write(object obj);
  14. int Status { get; set; } } // giao diện mới
  15. interface ICompressible { void Compress(); void Decompress(); } // Document thực thi IStorable public class Document : IStorable { public Document( string s) { Console.WriteLine(“Creating document with: {0}”, s); } // IStorable public void Read() { Console.WriteLine(“Implementing the Read Method for IStorable”); } // IStorable.WriteLine() public void Write( object o) { Console.WriteLine(“Implementing the Write Method for IStorable”); } // IStorable.Status public int Status { get { return status; } set { status = value; } } // bien thanh vien luu gia tri cua thuoc tinh Status private int status = 0; }
  16. public class Tester
  17. { static void Main() { Document doc = new Document(“Test Document”); // chỉ gán khi an toàn if ( doc is IStorable ) { IStorable isDoc = (IStorable) doc; isDoc.Read(); } // việc kiểm tra này sẽ sai if ( doc is ICompressible ) { ICompressible icDoc = (ICompressible) doc; icDoc.Compress(); } } } ----------------------------------------------------------------------------- Trong ví dụ 8.3, hàm Main() lúc này sẽ thực hiện việc gán với interface khi được kiểm tra hợp lệ. Việc kiểm tra này được thực hiện bởi câu lệnh if: if ( doc is IStorable )
Đồng bộ tài khoản