Giao diện là hợp đồng. Nó nói "Tôi có thể làm những việc này." Điểm của ai đó giao cho bạn một bản sao của IInterface
trong đó bạn không thể sử dụng một số phương pháp trong hợp đồng đó vì chúng đã được đánh dấu là không công khai?
Đây là lý do thiết kế ngôn ngữ theo cách này. Thông số kỹ thuật cho điều này là trong §13.2 của đặc tả ngôn ngữ:
Mọi thành viên giao diện đều có quyền truy cập công cộng. Đó là một lỗi biên dịch thời gian cho các khai báo thành viên giao diện bao gồm bất kỳ công cụ sửa đổi nào. Cụ thể, không thể khai báo thành viên giao diện với các công cụ sửa đổi abstract
, public
, protected
, internal
, private,
virtual
, override
hoặc static
.
Đối với mã của bạn, đó là ví dụ về explicit interface implementation. Nó là hữu ích nhất khi một lớp hoặc cấu trúc triển khai thực hiện hai giao diện với mỗi thành viên có cùng một chữ ký. Ví dụ: cả hai số IEnumerable
và IEnumerable<T>
xác định phương thức GetEnumerator
không chấp nhận tham số.
public interface IEnumerable {
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable {
IEnumerator<T> GetEnumerator();
}
Lưu ý rằng bằng cách định nghĩa ở trên, bất kỳ lớp mà thực hiện IEnumerable<T>
cũng phải thực hiện IEnumerable
. Hãy nhớ rằng loại trả lại không phải là một phần của chữ ký và do đó chúng tôi có xung đột với IEnumerable.GetEnumerator
và IEnumerable<T>.GetEnumerator
. Đây là cách triển khai giao diện rõ ràng nhằm giải quyết:
class X<T> : IEnumerable<T> {
List<T> _list = new List<T>();
public IEnumerator<T> GetEnumerator() {
return _list.GetEnumerator();
}
IEnumerator GetEnumerator() {
return GetEnumerator(); // invokes IEnumerable<T>.GetEnumerator
}
}
Thành viên thực hiện giao diện rõ ràng chỉ hiển thị thông qua giao diện của giao diện. Như vậy:
X<int> x = new X<int>();
var e1 = x.GetEnumerator(); // invokes IEnumerable<int>.GetEnumerator
// IEnumerable.GetEnumerator is not visible
IEnumerable y = x;
var e2 = y.GetEnumerator(); // invokes IEnumerable.GetEnumerator
Như vậy, trong mã của bạn
X ob = new Y();
ob.add(1, 2); // X.add is visible through interface
Y y = new Y();
y.add(1, 2); // compile-time error, X.add is not visible
Cả hai phương pháp này không đòi hỏi phải bổ nhưng khi tôi không sử dụng giao diện, như X.add() ở trên, tôi cần phải thực hiện công khai. Tại sao?
OK, không rõ chính xác những gì bạn đang yêu cầu ở đây. Công cụ sửa đổi truy cập không được phép cho việc triển khai giao diện rõ ràng. Đây là 13,4:
Đó là một lỗi thời gian biên dịch cho một thực hiện thành viên giao diện rõ ràng bao gồm bổ truy cập, và nó là một lỗi thời gian biên dịch để bao gồm các bổ abstract
, virtual
, override
, hoặc static
.
Nếu triển khai giao diện không được đánh dấu là triển khai giao diện rõ ràng, thì phải có công cụ sửa đổi truy cập public
. Đây là 13.4.4 (Giao diện lập bản đồ):
Giao diện bản đồ cho một lớp học hoặc struct C
nằm một thực hiện cho mỗi thành viên của mỗi giao diện được quy định trong danh sách lớp cơ sở của C
. Việc thực hiện một thành viên giao diện cụ thể I.M
, trong đó I
là giao diện trong đó thành viên M
được khai báo, được xác định bằng cách kiểm tra từng lớp hoặc cấu trúc S
, bắt đầu bằng C
và lặp lại cho mỗi lớp cơ sở liên tiếp C
.
Nếu S
chứa một tuyên bố của một thực hiện thành viên giao diện rõ ràng phù hợp với I
và M
, sau đó thành viên này là việc thực hiện I.M
Nếu không, nếu S
chứa tuyên bố của thành viên công cộng không tĩnh khớp với M
thì thành viên này sẽ triển khai I.M
.
Lỗi biên dịch xảy ra nếu không thể định vị cho tất cả thành viên của tất cả các giao diện được chỉ định trong danh sách lớp cơ sở C
.
Vì vậy, trong ngắn hạn, trình biên dịch đầu tiên tìm kiếm triển khai giao diện rõ ràng. Nếu nó không thể tìm thấy một thì nó tìm kiếm không tĩnh, công khai thành viên có chữ ký giống như phương pháp M
đang được triển khai. Nếu nó không thể tìm thấy một lỗi biên dịch thời gian xảy ra. Vì vậy, các quy tắc là điều này.Để thực hiện một thành viên giao diện I.M
:
Nếu bạn thực hiện một cách rõ ràng I.M
thì cú pháp là
return-type I.M(parameter-list)
Nếu không, cú pháp là
public return-type M(parameter-list)
Như vậy, với
Chúng tôi có thể thực hiện một cách rõ ràng:
class Explicit : IAdd {
int IAdd.Add(int x, int y) { return x + y; }
}
hay không:
class NotExplicit : IAdd {
public int Add(int x, int y) { return x + y; }
}
Sự khác biệt là sau đó rằng Explicit.Add
là không hiển thị trừ trường hợp của Explicit
đang gõ như IAdd
:
IAdd explicitInterface = new Explicit();
explicitInterface.Add(2, 2);
Explicit explicit = new Explicit();
explicit.Add(2, 2); // compile-time error
trong khi
IAdd notExplicitInterface = new NotExplicit();
notExplicitInterface.Add(2, 2);
NotExplicit notExplicit = new NotExplicit();
notExplicit.Add(2, 2); // okay, NOT a compile-time error as above
Điều đó giúp đỡ?
có thể trùng lặp của http://stackoverflow.com/questions/1652123/is-there-a-reason-you-can-not-define-the-access-modifier-on-a-method-or-in- an-int –