我有一个接口说 IMyInterface ,它是由类 MyClass 实现的,我如何使用覆盖而不是屏蔽其中的getter和setter来声明属性接口
例如,对于界面:
public interface IMyInterface
{
String MyProperty {get;}
}
如果我这样做,我隐藏了接口属性
public class MyClass : IMyInterface
{
public String MyProperty
{
get
{
return "Whatever";
}
}
}
但如果我这样做,我会收到一条错误消息,指出 MyProperty 无法公开:
public class MyClass : IMyInterface
{
public String IMyInterface.MyProperty
{
get
{
return "Whatever";
}
}
}
答案 0 :(得分:5)
由于接口没有实现,覆盖是一个不适用于接口的概念。因此,界面成员不需要virtual
。
使用类继承时覆盖。您需要在基类中创建它们virtual
,并在子类中使用override
关键字:
interface IFoo
{
string Bar { get; }
}
class FooBase : IFoo
{
public virtual string Bar { get; protected set; }
}
class Foo : FooBase
{
public override string Bar { get; protected set; }
}
如果显式实现接口,则不需要public
修饰符,因为只有当使用者使用接口类型时才能看到该成员:
class FooExplicit : IFoo
{
// IFoo f = new FooExplicit(); <- Bar is visible
// FooExplicit fe = new FooExplicit(); <- there is no Bar
string IFoo.Bar { get; private set; }
}
由于IFoo.Bar
仍然只与接口绑定,它仍然隐含public
。在Java中,如果您愿意,可以添加public
修饰符(当然是可选的)。 C#对比禁止这个。
答案 1 :(得分:1)
class A
{
public virtual int P1
{
get { return 42; }
set { }
}
}
class B : A
{
public override int P1
{
get { return 18; }
}
}
答案 2 :(得分:1)
他们是否隐含公开?
接口memebers是implicity public
,您可以在接口中使用任何访问说明符和接口成员。
接口成员自动公开,不能包含任何内容 访问修饰符。
评论:
我在谈论它抱怨我的实施课程 在我的IMyInterface.MyProperty
声明中使用public修饰符
由于您正在执行Explicit interface implementation,因此只能针对接口对象调用该方法,不能针对类对象调用该方法。由于接口的所有成员都是隐式public
,因此这将是多余的,这就是为什么不允许的原因。
请参阅此文章:Explicit interface implementation – to hide interface member in implementing type
要明确实现接口,请删除公共访问权限 说明符(所有接口成员都是公共的),并谓词方法 带有接口名称和点的名称
答案 3 :(得分:1)
隐藏什么是什么意思?您的第一个示例是接口属性的正常,隐式实现。你没有隐藏它,你正在实施它。
你的第二个例子是明确的界面实现 - 它不能公开设计。只有当您的变量类型为IMyInterface
时,您才能调用它。
你当然可以在实现类中将你的属性标记为virtual
,以允许它在iheritting类中被覆盖,但这是另一个故事。
答案 4 :(得分:0)
这可能有助于Interface Properties (C# Programming Guide)
interface IEmployee{
string Name
{
get;
set;
}
int Counter
{
get;
}}
public class Employee : IEmployee
{
public static int numberOfEmployees;
private string name;
public string Name // read-write instance property
{
get
{
return name;
}
set
{
name = value;
}
}
private int counter;
public int Counter // read-only instance property
{
get
{
return counter;
}
}
public Employee() // constructor
{
counter = ++counter + numberOfEmployees;
}
}
答案 5 :(得分:0)
在接口中声明属性实际上并不提供接口上属性的实现。
即。通过陈述
public interface IMyInterface
...
String MyProperty {get;}
您实际上只是要求接口的实现必须提供具有getter的属性MyProperty
。但我同意语法很容易与automatic properties混淆,但在接口的情况下,没有后备字段。
更新
显式接口实现用于区分多个接口需要相同属性名称的情况。可能以下内容澄清了这一点?
public interface IMyInterface
{
String MyProperty { get; }
}
public interface IMyInterface2
{
String MyProperty { get; }
}
// Implement BOTH interfaces explicitly
public class MyClass : IMyInterface, IMyInterface2
{
string IMyInterface.MyProperty
{
get { return "I am Interface1.MyProperty"; }
}
string IMyInterface2.MyProperty
{
get { return "I am Interface2.MyProperty"; }
}
// Same Property Name on the class itself
public String MyProperty
{
get { return "I am a brand new Property!"; }
}
}
// Which can be used like so:
var myClass = new MyClass();
Console.WriteLine(((IMyInterface)myClass).MyProperty);
Console.WriteLine(((IMyInterface2)myClass).MyProperty);
Console.WriteLine(myClass.MyProperty);
'I am Interface1.MyProperty'
'I am Interface2.MyProperty'
'I am a brand new Property!'
// Implement BOTH interfaces - just the one explicitly
public class MyClass : IMyInterface, IMyInterface2
{
public string MyProperty
{
get { return "I am Interface1.MyProperty, exposed publicly"; }
}
string IMyInterface2.MyProperty
{
get { return "I am Interface2.MyProperty"; }
}
}