Thực thi giao diện tường minh
Trong việc thực thi giao diện cho tới giờ, những lớp thực thi (trong trường hợp
này là Document) tạo ra các phương thức thành viên cùng ký hiệu và kiểu trả về như
là phương thức được mô tả trong giao diên. Chúng ta không cần thiết khai báo tường
minh rằng đây là một thực thi của một giao diện, việc này được hiểu ngầm bởi trình
biên dịch.
Tuy nhiên, có vấn đề xảy ra khi một lớp thự
c thi hai giao diện và cả hai giao diện này có
các phương thức cùng một ký hiệu. Ví dụ 8.5 tạo ra hai giao diện: IStorable và ITalk. Sau
đó thực thi phương thức Read() trong giao diện ITalk để đọc ra tiếng nội dung của một
cuốn sách. Không may là phương thức này sẽ tranh chấp với phương thức Read()
của IStorable mà Document phải thực thi.
Bởi vì cả hai phương thức IStorable và ITalk có cùng phương thức Read(),việc thực
thi lớp Document phải sử dụng thực thi tường minh cho mỗi phươ
ng thức. Với việc
thực thi tường minh, lớp thực thi Document sẽ khai báo tường minh cho mỗi phương
thức:
void ITalk.Read();
Điều này sẽ giải quyết việc tranh chấp, nhưng nó sẽ tạo ra hàng loạt các hiệu ứng thú vị.
Đầu tiên, không cần thiết sử dụng thực thi tường minh với những phương thức khác của
Talk:
public void Talk();
vì không có sự tranh chấp cho nên ta khai báo như thông thường.
Điều quan trọng là các phương thứ
c thực thi tường minh không có bổ sung truy cập:
void ITalk.Read();
Phương thức này được hiểu ngầm là public.
Thật vậy, một phương thức được khai báo tường minh thì sẽ không được khai báo với
các từ khóa bổ sung truy cập: abstract, virtual, override, và new.
Một địều quan trọng khác là chúng ta không thể truy cập phương thức thực thi tường
minh thông qua chính đối tượng. Khi chúng ta viết:
theDoc.Read();
Trình biên dịch chỉ hiểu rằng chúng ta thực thi phương thức giao di
ện ngầm
định cho IStorable. Chỉ một cách duy nhất truy cập các phương thức thực thi tường
minh là thông qua việc gán cho giao diện để thực thi:
ITalk itDoc = theDoc as ITalk;
if ( itDoc != null )
{
itDoc.Read();
}
Sử dụng thực thi tường minh được áp dụng trong ví dụ 8.5
Ví dụ 8.5: Thực thi tường minh.
-----------------------------------------------------------------------------
using System;
interface IStorable
{
void Read();
void Write();
}
interface ITalk
{
void Talk();
void Read();
}
// lớp Document thực thi hai giao diện
public class Document : IStorable,
ITalk
{
// bộ khởi dựng
public Document( string s)
{
Console.WriteLine(“Creating document with: {0}”,s);
}
// tạo phương thức ảo
public virtual void
Read()
{
Console.WriteLine(“Implementing IStorable.Read”);
}
// thực thi bình thường
public void Write()
{
Console.WriteLine(“Implementing IStorable.Write”);
}
// thực thi tường minh
void ITalk.Read()
{
Console.WriteLine(“Implementing ITalk.Read”);
}
public void Talk()
{
Console.WriteLine(“Implementing ITalk.Talk”);
}
}
public class Tester
{
static void Main()
{
// tạo đối tượng Document
Document theDoc = new Document(“Test
Document”); IStorable isDoc = theDoc as IStorable;
if ( isDoc != null )
{
isDoc.Read();
}
ITalk itDoc = theDoc as ITalk;
if ( itDoc != null )
{
itDoc.Read();
}
theDoc.Read();
theDoc.Talk();
}
}
-------------------------------------------------------------------------
----
Kết quả:
Creating document with: Test Document
Implementing IStorable.Read
Implementing ITalk.Read
Implementing IStorable.Read
Implementing ITalk.Talk
-----------------------------------------------------------------------------
Lựa chọn việc thể hiện phương thức giao diện
Những người thiết kế lớp có thể thu được lợi khi một giao diện được thực thi thông qua
thực
thi tường minh và không cho phép các thành phần client của lớp truy cập trừ phi sử
dụng thông qua việc gán cho giao diện.
Giả sử nghĩa của đối tượng Document chỉ
ra rằng nó thực thi giao diện
IStorable, nhưng không muốn phương thức Read() và Write() là phần giao diện
public của lớp Document. Chúng ta có thể sử dụng thực thi tường minh để chắc
chắn chỉ có thể truy cập thông qua việc gán cho giao diện. Điều này cho phép
chúng ta lưu trữ ngữ nghĩa của lớp Document trong khi vẫn có thể thực thi được
giao diện IStorable. Nếu thành phần client muốn đối tượng thực thi giao diện
IStorable, nó có thể thực hiệ
n gán tường minh cho giao diện để gọi các phương thức
thực thi giao diện. Nhưng khi sử dụng đối tượng Document thì nghĩa là không có
phương thức Read() và Write().
Thật vậy, chúng ta có thể lựa chọn thể hiện những phương thức thông qua
thực thi tường minh, do đó chúng ta có thể trưng bày một vài phương thức thực thi
như là một phần của lớp Document và một số phương thức khác thì không.
Trong ví dụ 8.5, đối tượng Document tr
ưng bày phương thức Talk() như là
phương thức của lớp Document, nhưng phương thức Talk.Read() chỉ được thể
hiện thông qua gán cho giao diện. Thậm chí nếu IStorable không có phương thức
Read(), chúng ta cũng có thể chọn thực thi tường minh phương thức Read() để
phương thức không được thể hiện ra bên ngoài như các phương thức của Document.
Chúng ta lưu ý rằng vì thực thi giao diện tường minh ngăn ngừa việc sử dụng
từ
khóa virtual, một lớp dẫn xuất có thể được hỗ trợ để thực thi lại phương thức.
Do đó, nếu Note dẫn xuất từ Document, nó có thể được thực thi lại phương thức
Talk.Read() bởi vì lớp Document thực thi phương thức Talk.Read() không phải ảo.
Ẩ n thành viên
Ngôn ngữ C# cho phép ẩn các thành viên của giao diện. Ví dụ, chúng ta có một giao