Chương 8 Giao diện
8.2 Truy xuất phương thức của giao diện
Chúng ta có thể truy xuất thành viên của giao diện IStorable như chúng là thành viên của lớp Document:
Document doc = new Document("Test Document"); doc.status = -1;
doc.Read( );
hoặc ta có thể tạo một thể diện của giao diện bằng việc phân phối tài liệu về kiểu của giao diện và sau đó sử dụng giao diện để truy cập những phương thức:
IStorable isDoc = (IStorable) doc; isDoc.status = 0;
isDoc.Read( );
In this case, in Main( ) you know that Document is in fact an IStorable, so you can take advantage of that knowledge. As stated earlier, you cannot instantiate an interface directly. That is, you cannot say:
IStorable isDoc = new IStorable( );
Mặc dù vậy, chúng ta có thể tạo một thể hiện của lớp thi công như sau:
Document doc = new Document("Test Document");
Sau đấy ta có thể tạo một thể hiện của giao diện bằng việc phân bổ những đối tượng thi công đến những kiểu giao diện, trong trường hợp này là IStorable:
IStorable isDoc = (IStorable) doc;
Chúng ta kết hợp những bước đã mô tả trên bằng đoạn mã dưới đây:
IStorable isDoc = (IStorable) new Document("Test Document"); 8.2.1 Ép kiểu thành giao diện
Trong nhiều trường hợp, chúng ta không biết đối tượng ấy hỗ trợ những giao diện loại gì. Giả sử như chúng ta có một tập các giao diện của Documents, một số trong chúng có thể lưu trữ còn một số khác thì không thể, chúng ta sẽ thêm vào một giao diện thứ hai ICompressable cho những đối tượng thuộc loại này để chúng có thể nén lại cho công việc chuyển đổi có liên quan đến email nhanh hơn.
interface ICompressible {
void Compress( ); void Decompress( ); }
Với kiểu của Document, chúng ta có thể không biết rằng chúng được hỗ trợ bởi giao diện IStorable hoặc giao diện ICompressable hoặc cả hai. Chúng ta có thể giải quyết
điều này bằng cách phân bổ những giao diện lại:
Document doc = new Document("Test Document"); IStorable isDoc = (IStorable) doc;
isDoc.Read( );
ICompressible icDoc = (ICompressible) doc; icDoc.Compress( );
Giao diện Gvhd: Nguyễn Tấn Trần Minh Khang
public class Document : IStorable
Việc phân bổ ICompressable phải đến khi biên dịch mới biết được bởi vì ICompressable là một giao diện hợp lệ. Mặc dù vậy, nếu sự phân bổ tồi thì có thể sẽ
xảy ra lỗi, và lúc ấy thì một exception sẽđược quăng ra để cảnh báo:
An exception of type System.InvalidCastException was thrown.
Chi tiết về exception sẽđược đề cập trong những chương sau: 8.2.2 Toán tử “is “
Khi chúng ta muốn một đối tượng có khả năng hỗ trợ giao diện, theo nguyên tắc là chúng ta phải gọi phương thức tương ứng lên. Trong C# có 2 phương thức hỗ trợ
công việc này. Cú pháp như sau:
expression is type hay
if (doc is IStorable)
Chắc lớp giao diện IStorable chắc bạn vẫn còn nhớ, ởđây câu lệnh if sẽ kiểm tra xem đối tượng doc có hỗ trợ giao diện IStorable không mà thôi.
Thật không may mắn cho chúng ta, tuy rát dễ hiểu với cách viết như thế nhưng chúng lại không hiệu quả cho lắm. Để hiểu vấn đề là tại sao lại như thế thì chúng ta cần phải nhúng chúng vào trong mã MSIL và sau đó phát sinh. Và sau đây là một số kết quả (thể hiện bằng số Hexa)
IL_0023: isinst ICompressible
IL_0028: brfalse.s IL_0039 IL_002a: ldloc.0
IL_002b: castclass ICompressible
IL_0030: stloc.2 IL_0031: ldloc.2
IL_0032: callvirt instance void ICompressible::Compress( ) IL_0037: br.s IL_0043
IL_0039: ldstr "Compressible not supported"
Có một số vấn đề là chúng ta phải chú ý là trong phần kiểm tra ICompressable trong dòng 23. Từ khóa isinst là mã MSIL của tác tử is. Như ta thấy trong phần kiểm tra
đối tượng doc ở phía bên phải và ở dòng 2b thì việc kiểm tra thành công khi castclass được gọi.