对接口成员的访问

对接口方法的调用和采用索引指示器访问的规则与类中的情况也是相同的。如果底层成员的命名与继承而来的高层成员一致,那么底层成员将覆盖同名的高层成员。但由于接口支持多继承,在多继承中,如果两个父接口含有同名的成员,这就产生了二义性(这也正是C#中取消了类的多继承机制的原因之一),这时需要进行显式的声明。

程序清单15-2:

using System;
interface ISequence
{
int Count{get;set;}
}
interface IRing
{
void count(int i);
}
interface IRingSequence:ISequence,IRing{}
class C
{
void Test(IRingSequense rs){
  //rs.Count(1); 错误,Count有二义性
  //rs.Count=1; 错误,Count有二义性
  ((ISequence)rs).Count=1; //正确
  ((IRing)rs).Count(1); //正确调用IRing Count
 }
}

上面的例子中,前两条语句x.Count(1)和x.Count=1会产生二义性,从而导致编译时错误,因此必须显式地给X指派父接口类型,这种指派在运行时不会带来额外的开销。

再看下面的例子:

程序清单15-3:

using System;
interface IInteger
{
 void Add(int i);
}
interface IDouble
{
 void Add(double d);
}
interface INumber:IInteger,IDouble{}
class C
{
 void Test(INumber n){
   //n.Add(1);错误
   n.Add(1.0); //正确
  ((IInteger)n).Add(1); //正确
  ((IDouble)n).Add(1); //正确
 }
}

调用n.Add(1)会产生二义性,因为候选的重载方法的参数类型均适用。但是,调用n.Add(1.0)是允许的,因为1.0是浮点数,参数类型与方法IInteger.Add()的参数类型不一致,这时只有IDouble.Add才是适用的。不过只要加入了显式的指派,就决不会产生二义性。

接口的多重继承的问题也会带来成员访问上的问题。

interface IBase
{
 void F(int i);
}
interface ILeft:IBase
{
 new void F(int i);
}
interface IRight:IBase
{
 void G();
}
interface IDerived:ILeft,IRight{}
class A
{
 void Test(IDerived d){
   d.F(1);  //调用ILeft.F
   ((IBase)d).F(1); //调用IBase.F
   ((ILeft)d).F(1); //调用ILeft.F
   ((IRight)d).F(1); //调用IBase.F
 }
}

上例中,方法IBase.F在派生的接口ILeft中被ILeft的成员方法F覆盖了。所以对d.F(1)的调用实际上调用了。虽然从IBase----IRight---IDerived这条继承路径上来看,ILeft.F方法是没有被覆盖的。

我们只要记住这一点:一旦成员被覆盖以后,所有对其的访问都被覆盖以后的成员“拦截”了。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索方法
, count
, interface
, 调用接口参数问题
, 二义性
, 接口对接
, iring i
, 对接
, 成员
void
对象访问私有成员变量、不实现接口成员、子类访问父类私有成员、c 不实现接口成员、java接口成员变量,以便于您获取更多的相关知识。

时间: 2024-12-11 19:15:05

对接口成员的访问的相关文章

派生类与派生类对象对基类成员的访问

区分"派生类对象"和"派生类"对基类成员的访问权限.    "派生类对象"对基类成员的访问权限:      (1)对于公有继承,只有基类的公有成员可以被"派生类对象"访问,其他(保护和私有)成员不能被访问.      (2)对于私有继承和保护继承,基类中所有成员都不能被"派生类对象"访问.    "派生类"对基类中成员的访问权限:     (1)对于公有继承,基类中的公有成员和保护成

C#中对类的成员的访问

在编写程序时,我们可以对类的成员使用不同的访问修饰符,从而定义它们的访问级别. 公有成员 C#中的公有成员提供了类的外部界面,允许类的使用者从外部进行访问.公有成员的修饰符为public,这是限制最少的一种访问方式. 私有成员 C#中的私有成员仅限于类中的成员可以访问,从类的外部访问私有成员是不合法的.如果在声明中没有出现成员的访问修饰符,按照默认方式成员为私有的.私有成员的修饰符为private. 保护成员 为了方便派生类的访问,又希望成员对于外界是隐藏的,这时可以使用protected修饰符

2013级C++第12周(春)项目——成员的访问属性、多重继承

课程首页在:http://blog.csdn.net/sxhelijian/article/details/11890759,内有完整教学方案及资源链接 第一部分 程序阅读  1.阅读程序,分析类中成员的访问属性 #include <iostream> using namespace std; class A //A为基类 { public: void f1( ); int i; protected: void f2(); int j; private: int k; }; class B:

解析C++中派生的概念以及派生类成员的访问属性_C 语言

C++继承与派生的概念.什么是继承和派生 在C++中可重用性是通过继承(inheritance)这一机制来实现的.因此,继承是C++的一个重要组成部分. 前面介绍了类,一个类中包含了若干数据成员和成员函数.在不同的类中,数据成员和成员函数是不相同的.但有时两个类的内容基本相同或有一部分相同,例如巳声明了学生基本数据的类Student: class Student { public: void display( ) //对成员函数display的定义 { cout<<"num: &qu

Java中成员方法与成员变量访问权限详解_java

记得在一次面试的笔试题中,有的面试官会要求写出具体的像pullic这些访问限定符的作用域.其实,平常我都没去系统的考虑这些访问限定符的作用域,特别是包内包外的情况,OK,笔试不行了.  这是java基本的知识,也是公司看重的,那没办法啦,我的脑袋记不住东西,那我只能把这些东西写下来方便自己温故知新,不废话了,贴代码了. 代码如下: package com.jaovo; /** *_1_ 成员变量访问权限的求证 * public private protected default(默认的权限) *

Delphi XE中类成员的访问权限

Delphi XE中类成员的访问权限 共提供了6个关键词来用于限定访问权限: public.private.protected.published.automated strict private . strict protected其各自的含义为: 1. strict private: 此区定义的字段或方法只能用于当前的类中.即T1中此区定义的成员只能在T1中使用.2. strict protected: 此区定义的成员除能用于当前类中,还可用于当前类的任何子类中. 以上两种成员,同一个类的不

C语言中结构体偏移及结构体成员变量访问方式的问题讨论_C 语言

c语言结构体偏移 示例1 我们先来定义一下需求: 已知结构体类型定义如下: struct node_t{ char a; int b; int c; }; 且结构体1Byte对齐 #pragma pack(1) 求: 结构体struct node_t中成员变量c的偏移. 注:这里的偏移量指的是相对于结构体起始位置的偏移量. 看到这个问题的时候,我相信不同的人脑中浮现的解决方法可能会有所差异,下面我们分析以下几种可能的解法: 方法1 如果你对c语言的库函数比较熟悉的话,那么你第一个想到的肯定是of

Python 面向对象 成员的访问约束_python

在Python中是通过一套命名体系来识别成约的访问范围的 class MyObjec(object): username = "developerworks" # public _email = "developerworks#163#.com" #protected __tel = "1391119****" # private 从这段代码中可以看出一些巧妙的命名方法 在python中所有的以字母开头的成语名称被python命名体系自动识别为p

接口的成员

15.3.1 接口成员的定义 接口可以包含一个和多个成员,这些成员可以是方法.属性.索引指示器和事件,但不能是常量.域.操作符.构造函数或析构函数,而且不能包含任何静态成员.下面例子中接口IExample包含了索引指示器.事件E.方法F.属性P这些成员: interface IExample { string this[int index] {get;set;} event EventHandler E; void F(int value); string P{get;set;} } publi