我是OOP的新手并且有一些问题.
为什么接口中声明的方法不能具有修饰符(public,private等).
在这段代码中:
class Program
{
static void Main(string[] args)
{
X ob = new Y();
ob.add(4, 5);
Z ob1 = new Y();
ob1.mull(2, 3);
Console.Read();
}
}
public interface X
{
void add(int x, int y);
}
public interface Z
{
void mull(int x, int y);
}
class Y : X, Z
{
void X.add(int x, int y)//here we are not decalring it as public ,why?
{
Console.WriteLine("sum of X and y is " + (x + y));
}
void Z.mull(int x, int y)
{
Console.WriteLine("product of X and Y is" + (x * y));
}
}
Run Code Online (Sandbox Code Playgroud)
这两种方法都不需要修饰符,但是当我不使用接口时,X.add()如上所述,我需要公开实现.为什么?
jas*_*son 34
接口是合同.它说"我可以做这些事情." 有人向你递交了一个实例,IInterface其中你不能使用该合同中的某些方法,因为它们已被标记为不公开?
这是以这种方式设计语言的基本原理.对此的规范在语言规范的第13.2节中:
所有接口成员都隐式具有公共访问权限.接口成员声明包含任何修饰符是编译时错误.特别是,接口成员不能随修饰声明
abstract,public,protected,internal,private,virtual,override,或static.
至于您的代码,这是显式接口实现的一个示例.当一个类或结构体实现两个接口,每个接口具有相同签名的成员时,它是最有用的.例如,既IEnumerable和IEnumerable<T>定义一个方法GetEnumerator接受没有参数.
public interface IEnumerable {
IEnumerator GetEnumerator();
}
public interface IEnumerable<T> : IEnumerable {
IEnumerator<T> GetEnumerator();
}
Run Code Online (Sandbox Code Playgroud)
请注意,通过上述定义,任何实现的类也IEnumerable<T>必须实现IEnumerable.请记住,返回类型不是签名的一部分,因此我们与IEnumerable.GetEnumerator和冲突IEnumerable<T>.GetEnumerator.这是显式接口实现要解决的问题:
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
}
}
Run Code Online (Sandbox Code Playgroud)
显式接口实现的成员只能通过接口实例看到.从而:
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
Run Code Online (Sandbox Code Playgroud)
因此,在您的代码中
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
Run Code Online (Sandbox Code Playgroud)
这两种方法都不需要修饰符,但是当我不使用接口时,比如上面的X.add(),我需要公开实现.为什么?
好的,目前还不清楚你在这里问的确切内容.显式接口实现不允许访问修饰符.这是13.4:
这是一个显式接口成员实现,包括访问修饰符编译时错误,它是一个编译时错误,包括修饰语
abstract,virtual,override,或static.
如果接口实现未标记为显式接口实现,则它必须具有访问修饰符public.这是13.4.4(接口映射):
类或结构的接口映射
C定位了基类列表中指定的每个接口的每个成员的实现C.特定接口成员的实现I.M,其中I是M声明成员的接口,通过检查每个类或结构来确定S,从C每个连续的基类开始并重复C,直到找到匹配为止
如果
S包含匹配的显式接口成员实现的声明I和M,那么这个成员就是执行I.M否则,如果
S包含一个匹配的非静态公共成员的声明M,那么这个成员就是执行I.M.如果无法为基类列表中指定的所有接口的所有成员定位实现,则会发生编译时错误
C.
因此,简而言之,编译器首先寻找显式接口实现.如果找不到,那么它会查找与正在实现的方法具有相同签名的非静态公共成员M.如果找不到一个发生编译时错误.所以规则是这样的.要实现接口成员I.M:
如果你I.M明确实现,那么语法是
return-type I.M(parameter-list)
否则,语法是
public return-type M(parameter-list)
因此,与
interface IAdd {
int Add(int x, int y)
}
Run Code Online (Sandbox Code Playgroud)
我们可以明确地实施:
class Explicit : IAdd {
int IAdd.Add(int x, int y) { return x + y; }
}
Run Code Online (Sandbox Code Playgroud)
或不:
class NotExplicit : IAdd {
public int Add(int x, int y) { return x + y; }
}
Run Code Online (Sandbox Code Playgroud)
然后区别是Explicit.Add不可见的,除非Explicit输入的实例为IAdd:
IAdd explicitInterface = new Explicit();
explicitInterface.Add(2, 2);
Explicit explicit = new Explicit();
explicit.Add(2, 2); // compile-time error
Run Code Online (Sandbox Code Playgroud)
而
IAdd notExplicitInterface = new NotExplicit();
notExplicitInterface.Add(2, 2);
NotExplicit notExplicit = new NotExplicit();
notExplicit.Add(2, 2); // okay, NOT a compile-time error as above
Run Code Online (Sandbox Code Playgroud)
这有帮助吗?
| 归档时间: |
|
| 查看次数: |
788 次 |
| 最近记录: |