Tải bản đầy đủ (.pdf) (5 trang)

Giáo trình hướng dẫn truy cập phương thức gán đối tượng cho một giao diện đối lập trừu tượng p7 pot

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (446.78 KB, 5 trang )

Ngôn Ngữ Lập Trình C#
// biến thành viên lưu giá trị thuộc tính Status
private int status;
}
public class Tester
{
static void Main()
{
// tạo một đối tượng myStruct
myStruct theStruct = new myStruct();
theStruct.Status = -1; // khởi tạo
Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status);
// thay đổi giá trị
theStruct.Status = 2;
Console.WriteLine(“Changed object”);
Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status);
// gán cho giao diện
// boxing ngầm định
IStorable isTemp = (IStorable) theStruct;
// thiết lập giá trị thông qua tham chiếu giao diện
isTemp.Status = 4;
Console.WriteLine(“Changed interface”);
Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”,
theStruct.Status, isTemp.Status);
// thay đổi giá trị một lần nữa
theStruct.Status = 6;
Console.WriteLine(“Changed object.”);
Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”,
theStruct.Status, isTemp.Status);
}
}



 Kết quả:
theStruct.Status: -1
Changed object.
theStruct.Status: 2
Changed interface
theStruct.Status: 2, isTemp: 4
Changed object
Thực Thi Giao Diện
203
Ngôn Ngữ Lập Trình C#
theStruct.Status: 6, isTemp: 4

Trong ví dụ 8.6, giao diện IStorable có một phương thức Read() và môt thuộc tính là Status.
Giao diện này được thực thi bởi một cấu trúc tên là myStruct:
public struct myStruct : IStorable
Đoạn mã nguồn thú vị bên trong Tester. Chúng ta bắt đầu bằng việc tạo một thể hiện của cấu
trúc và khởi tạo thuộc tính là –1, sau đó giá trị của status được in ra:0
myStruct theStruct = new myStruct();
theStruct.Status = -1; // khởi tạo
Console.WriteLine(“theStruct.Status: {0}”, theStruct.status);
Kết quả là giá trị của status được thiết lập:
theStruct.Status = -1;
Kế tiếp chúng ta truy cập thuộc tính để thay đổi status, một lần nữa thông qua đối tượng giá
trị:
// thay đổi giá trị
theStruct.Status = 2;
Console.WriteLine(“Changed object”);
Console.WriteLine(“theStruct.Status: {0}”, theStruct.Status);
kết quả chỉ ra sự thay đổi:

Changed object
theStruct.Status: 2
Tại điểm này, chúng ta tạo ra một tham chiếu đến giao diện IStorable, một đối tượng giá
trị theStruct được boxing ngầm và gán lại cho tham chiếu giao diện. Sau đó chúng ta dùng
giao diện để thay đổi giá trị của status bằng 4:
// gán cho một giao diện
// boxing ngầm định
IStorable isTemp = (IStorable) theStruct;
// thiết lập giá trị thông qua tham chiếu giao diện
isTemp.Status = 4;
Console.WriteLine(“Changed interface”);
Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”,
theStruct.Status, isTemp.Status);
như chúng ta đã thấy kết quả thực hiện có một điểm khác biệt:
Changed interface
theStruct.Status: 2, isTemp: 4
Điều xảy ra là: đối tượng được giao diện tham chiếu đến thay đổi giá trị status bằng 4, nhưng
đối tượng giá trị cấu trúc không thay đổi.Thậm chí có nhiều thú vị hơn khi chúng ta truy cập
phương thức thông qua bản thân đối tượng:
Thực Thi Giao Diện
204
Ngôn Ngữ Lập Trình C#
// than đổi giá trị lần nữa
theStruct.Status = 6;
Console.WriteLine(“Changed object”);
Console.WriteLine(“theStruct.Status: {0}, isTemp: {1}”,
theStruct.Status, isTemp.Status);
kết quả đối tượng giá trị thay đổi nhưng đối tượng được boxing và được giao diện tham chịếu
không thay đổi:
Changed object

theStruct.Status: 6, isTemp: 4
Ta thử xem đoạn mã IL để hiểu tham về cách thực hiện trên:
 Ví dụ 8.7: MSIL phát sinh từ ví dụ 8.6.

method private hidebysig static void Main() il managed
{
.entrypoint
// Code size 206 (0xce)
.maxstack 4
.local ([0] value class myStruct theStruct,
[1] class IStorable isTemp,
[2] int32 V_2)
IL_0000: ldloca.s theStruct
IL_0002: iniobj myStruct
IL_0008: ldloca.s theStruct
IL_000a: ldc.i4.ml
IL_000b: call instance void myStruct::set_status(int32)
IL_0010: ldstr “theStruct.Status: {0}”
IL_0015: ldloca.s theStruct
IL_0017: call instance int32 myStruct::get_status()
IL_001c: stloc.2
IL_001d: ldloca.s V_2
IL_001f: box [mscorlib]System.Int32
IL_0024: call void [mscorlib] System.Console::WriteLine
(class System.String, class System.Object)
IL_0029: ldloca.s theStruct
IL_002b: ldc.i4.2
IL_002c: call instance void myStruct::set_status(int32)
Thực Thi Giao Diện
205

Ngôn Ngữ Lập Trình C#
IL_0031: ldstr “Changed object”
IL_0036: call void [mscorlib]System.Console::WriteLine
(class System.String)
IL_003b: ldstr “theStruct.Status: {0}”
IL_0040: ldloca.s theStruct
IL_0042: call instance int32 myStruct::get_status()
IL_0047: stloc.2
IL_0048: ldloca.s V_2
IL_004a: box [mscorlib]System.Int32
IL_004f: call void [mscorlib]System.Console::WriteLine
(class System.String, class System.Object)
IL_0054: ldloca.s theStruct
IL_0056: box myStruct
IL_005b: stloc.1
IL_005c: ldloc.1
IL_005d: ldc.i4.4
IL_005e: callvirt instance void IStorable::set_status(int32)
IL_0063: ldstr “Changed interface”
IL_0068: call void [mscorlib]System.Console::WriteLine
(class System.String)
IL_006d: ldstr “theStruct.Status: {0}, isTemp: {1}”
IL_0072: ldloca.s theStruct
IL_0074: call instance int32 mySystem::get_status()
IL_0079: stloc.2
IL_007a: ldloca.s V_2
IL_007c: box [mscorlib]System.Int32
IL_0081: ldloc.1
IL_0082: callvirt instance int32 IStorable::get_status()
IL_0087: stloc.2

IL_0088: ldloca.s V_2
IL_008a: box [mscorlib]System.Int32
IL_008f: call void [mscorlib]System.Console::WriteLine
(class System.String, class System.Object, class System.Object)
IL_0094: ldloca.s theStruct
IL_0096: ldc.i4.6
IL_0097: call instance void myStruct::set_status(int32)
IL_009c: ldstr “Changed object”
IL_00a1: call void [mscorlib]System.Console::WriteLine
Thực Thi Giao Diện
206
Ngôn Ngữ Lập Trình C#
(class System.String)
IL_00a6: ldstr “theStruct.Status: {0}, isTemp: {1}”
IL_00ab: ldloca.s theStruct
IL_00ad: call instance int32 myStruct::get_status()
IL_00b2: stloc.2
IL_00b3: ldloca.s V_2
IL_00b5: box [mscorlib]System.Int32
IL_00ba: ldloc.1
IL_00bb: callvirt instance int32 IStorable::get_status()
IL_00c0: stloc.2
IL_00c1: ldloca.s V_2
IL_00c3: box [mscorlib]System.Int32
IL_00c8: call void [mscorlib]System.Console::WriteLine
(class System.String, class System.Object, class System.Object)
IL_00cd: ret
} // end fo method Tester::Main

Trong dòng lệnh IL_00b, giá trị của status được thiết lập thông qua việc gọi đối tượng giá trị.

Tiếp theo chúng ta thấy lệnh gọi thứ hai ở dòng IL_0017. Lưu ý rằng việc gọi WriteLine() dẫn
đến việc boxing một giá trị nguyên để phương thức GetString của lớp object được gọi.
Điều muốn nhấn mạnh là ở dòng lệnh IL_0056 khi một cấu trúc myStruct đã được boxing.
Việc boxing này tạo ra một kiểu dữ lịêu tham chiếu cho tham chiếu giao diện. Và điều quan
trọng là ở dòng IL_005e lúc này IStorable::set_status được gọi chứ không phải là
myStruct::setStatus.
Điều quan trọng muốn trình bày ở đây là khi chúng ta thực thi một giao diện với một kiểu giá
trị, phải chắc chắn rằng truy cập các thành viên của giao diện thông qua đối tượng hơn là
thông qua một tham chiếu giao diện.
Câu hỏi và trả lời
Câu hỏi 1: So sánh giữa lớp và giao diện?
Trả lời 1: Giao diện khác với lớp ở một số điểm sau: giao diện không cung cấp bất cứ sự
thực thi mã nguồn nào cả. Điều này sẽ được thực hiện tại các lớp thực thi giao diện. Một
giao diện đưa ra chỉ để nói rằng có cung cấp một số sự xác nhận hướng dẫn cho những điều
gì đó xảy ra và không đi vào chi tiết. Một điều khác nữa là tất cả các thành viên của giao
diện được giả sử là public ngầm định. Nếu chúng ta cố thay đổi thuộc tính truy cập của
thành viên trong giao diện thì sẽ nhận được lỗi.
Giao diện chỉ chứa những phương thức, thuộc tính, sự kiện, chỉ mục. Và không chứa dữ liệu
thành viên, bộ khởi dựng, và bộ hủy. Chúng cũng không chứa bất cứ thành viên static nào cả.
Thực Thi Giao Diện
207

×