如何在C#中重写属性?
我有一个接口,比如说IMyInterface,它是由一个类MyClass实现的。我如何用getter和setter声明属性,这些getter和setter覆盖而不是屏蔽接口中的属性 例如,对于接口:如何在C#中重写属性?,c#,inheritance,C#,Inheritance,我有一个接口,比如说IMyInterface,它是由一个类MyClass实现的。我如何用getter和setter声明属性,这些getter和setter覆盖而不是屏蔽接口中的属性 例如,对于接口: public interface IMyInterface { String MyProperty {get;} } 如果我这样做,我就隐藏了接口属性 public class MyClass : IMyInterface { public String MyProperty
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";
}
}
}
由于接口没有实现,重写是一个不适用于接口的概念。因此,接口成员不需要是虚拟的 使用类继承时可以重写。您需要在基类中使它们
虚拟
,并在子类中使用覆盖
关键字:
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; }
}
如果显式实现接口,则不需要公共
修饰符,因为该成员仅在使用者使用接口类型时可见:
class FooExplicit : IFoo
{
// IFoo f = new FooExplicit(); <- Bar is visible
// FooExplicit fe = new FooExplicit(); <- there is no Bar
string IFoo.Bar { get; private set; }
}
类foopexplicit:IFoo
{
//IFoo f=new foopexplicit();这可能会有所帮助
在接口中声明属性实际上并不提供接口上属性的实现 i、 e.声明
public interface IMyInterface
...
String MyProperty {get;}
事实上,您只是要求接口的实现必须提供一个属性MyProperty
,该属性有一个getter。不过,我同意语法很容易混淆,但在接口的情况下,没有支持字段
更新
显式接口实现用于区分多个接口需要相同属性名的情况
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"; }
}
}
那么,它们是否隐式公开 接口成员是隐式
公共的
,您可以对接口中的接口成员使用任何访问说明符
接口成员自动公开,并且不能包含任何
访问修饰符
请评论:
我说的是实施类,它抱怨我
在IMyInterface.MyProperty的声明中使用公共修饰符
因为您正在这样做,所以只能对接口对象调用该方法,而不能对类对象调用该方法。因为接口的所有成员都是隐式的public
,所以它是多余的,这就是为什么不允许的原因
见本文:
要显式实现接口,可以删除公共访问权限
说明符(所有接口成员都是公共的),并谓词该方法
使用接口名称和点命名
隐藏是什么意思?您的第一个示例是接口属性的普通隐式实现。您不是隐藏它,而是实现它 第二个示例是explicite接口实现-它不能通过设计公开。只有当变量类型为
IMyInterface
时,才能调用它
当然,你可以在实现类中将你的属性标记为
virtual
,以允许它在iHerting类中被重写,但那是另一回事。当显式实现接口成员时,你不使用可访问性修饰符。我不确定你的意思,我想这是接口应该做的,然后它们隐式地tly public?接口成员对于接口是公共的。当您显式实现它们时,它们只能通过接口访问。请参阅规范。@OmarKooheji我想这应该可以帮助您解决它们在接口中不是隐式虚拟的吗?我不是在创建抽象类。实际上,您不能重写接口成员,而只能基类成员。你实现接口,你覆盖基类的实现。我知道。但是实现类不必声明它们为公共的吗?对不起,如果这听起来有点迟钝,我经常在Java和C之间跳来跳去。在Java世界中,你不在接口上放置和访问修饰符,而在实现类上放置和访问修饰符hod(Java中没有属性)在隐式实现中-就像您的第一个示例一样-您需要将此属性标记为public。在显式实现中-否,您不能将它们标记为public,它们只能通过类型为IMyInterface
public interface IMyInterface
...
String MyProperty {get;}
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"; }
}
}