Ngôn Ngữ Lập Trình C#
public void Read()
{ }
public void Write( object o)
{ }
//
}
Thực thi phủ quyết giao diện
Khi thực thi một lớp chúng ta có thể tự do đánh dấu bất kỳ hay tất cả các phương thức
thực thi giao diện như là một phương thức ảo. Ví dụ, lớp Document thực thi giao diện
IStorable và có thể đánh dấu các phương thức Read() và Write() như là phương thức ảo. Lớp
Document có thể đọc và viết nội dung của nó vào một kiểu dữ liệu File. Những người phát
triển sau có thể dẫn xuất một kiểu dữ liệu mới từ lớp Document, có thể là lớp Note hay lớp
EmailMessage, và những người này mong muốn lớp Note đọc và viết vào cơ sở dữ liệu hơn
là vào một tập tin.
Ví dụ 8.4 mở rộng từ ví dụ 8.3 và minh họa việc phủ quyết một thực thi giao diện. Phương
thức Read() được đánh dấu như phương thức ảo và thực thi bởi Document.Read() và cuối
cùng là được phủ quyết trong kiểu dữ liệu Note được dẫn xuất từ Document.
Ví dụ 8.4: Phủ quyết thực thi giao diện.
using System;
interface IStorable
{
void Read();
void Write();
}
// lớp Document đơn giản thực thi giao diện IStorable
public class Document : IStorable
{
// bộ khởi dựng
public Document( string s)
}
// thực thi một phương thức Write riêng của lớp
public void Write()
{
Console.WriteLine(“Implementing the Write method for Note!”);
}
}
public class Tester
{
static void Main()
{
// tạo một đối tượng Document
Document theNote = new Note(“Test Note”);
IStorable isNote = theNote as IStorable;
if ( isNote != null)
{
isNote.Read();
isNote.Write();
}
Console.WriteLine(“\n”);
Thực Thi Giao Diện
194
.
.
Ngôn Ngữ Lập Trình C#
// trực tiếp gọi phương thức
theNote.Read();
theNote.Write();
Console.WriteLine(“\n”);
// tạo đối tượng Note
Thực Thi Giao Diện
195
.
.
Ngôn Ngữ Lập Trình C#
{
void Read();
void Write();
}
Người thiết kế của lớp Document thực thi phương thức Read() là phương thức ảo nhưng
không tạo phương thức Write() tương tự như vậy:
public virtual void Read()
Trong ứng dụng thế giới thực, chúng ta cũng đánh dấu cả hai phương thức này là phương thức
ảo. Tuy nhiên trong ví dụ này chúng ta minh họa việc người phát triển có thể tùy ý chọn các
phương thức ảo của giao diện mà lớp thực thi.
Một lớp mới Note dẫn xuất từ Document:
public class Note : Document
Việc phủ quyết phương thức Read() trong lớp Note là không cần thiết, nhưng ở đây ta tự do
làm điều này:
public override void Read()
Trong lớp Tester, phương thức Read() và Write() được gọi theo bốn cách sau:
Thông qua lớp cơ sở tham chiếu đến đối tượng của lớp dẫn xuất
Thông qua một giao diện tạo từ lớp cơ sở tham chiếu đến đối tượng dẫn xuất
Thông qua một đối tượng dẫn xuất
Thông qua giao diện tạo từ đối tượng dẫn xuất
Thực hiện cách gọi thứ nhất, một tham chiếu Document được tạo ra, và địa chỉ của một đối
tượng mới là lớp dẫn xuất Note được tạo trên heap và gán trở lại cho đối tượng Document:
Document theNote = new Note(“Test Note”);
Môt tham chiếu giao diện được tạo ra và toán tử as được sử dụng để gán Document cho tham
chiếu giao diện IStorable:
Overriding the Read method for Note!
Implementing the Write method dor Note!
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ực Thi Giao Diện
197
.
.