Shell示例如下。基本上,我希望客户和员工从IPerson实施SSN属性。但是,我希望客户得到并设置(这不是问题),但我希望员工只得到。
Public Interface IPerson
Property SSN As String
End Interface
Public Class Client
Implements IPerson
Public Property SSN As String Implements AELName.IPerson.SSN
Get
Return _SSN
End Get
Set(value As String)
_SSN = value
End Set
End Property
End Class
Public Class Employee
Implements IPerson
Public Readonly Property SSN As String Implements AELName.IPerson.SSN
Get
Return _SSN
End Get
End Property
End Class
员工生成错误“'SSN'无法实现'SSN',因为接口'IPerson'上没有匹配的属性”。是否有一种简单的方法来覆盖Employee的SSN实现?
答案 0 :(得分:5)
您可以实现一个空Set
- 一个不更新任何内容的文件。
Public Class Employee
Implements IPerson
Public Readonly Property SSN As String Implements AELName.IPerson.SSN
Get
Return _SSN
End Get
Set
' Make read only for Employee
End Set
End Property
End Class
答案 1 :(得分:2)
我建议将界面拆分为IReadablePerson和IReadWritePerson,后者继承前者。请注意,前一个接口不是IImmutablePerson
,因为后一个名称意味着该类的消费者不应期望其任何属性发生变化;一个实现IReadWritePerson
的对象不会遵循这样的期望,但会遵守这个人应该可读的期望。
分割界面的一个小麻烦是IReadWritePerson
必须在其读/写属性的声明中包含修饰符Shadows
,以及IReadWritePerson
的实现者必须提供IReadablePerson
的只读实现和IReadWritePerson
的读写实现。在C#中,读写属性的公共实现可以自动生成任何类似命名的只读,只写或读写属性的实现,这些属性是类实现的任何接口的一部分,但是在明确声明哪个接口时正在实现,接口的样式(只读,只写,读写)必须精确匹配实现的样式。烦。
由于人们不能简单地使用只读属性声明IReadableFoo
,使用只写属性声明IWriteOnlyFoo
并让IReadWriteFoo
简单地继承这两者,这会让烦恼更加严重。如果一个接口实现了一个只读属性和一个具有相同名称的只写属性,那么这两个属性都不可用,因为编译器会在somevariable = object.someProperty
或someObject.someProperty = someVariable
这样的语句中宣布它是“模糊的”要使用哪种实现方式。不是我可以看到任何歧义 - 我看不出第一个如何使用除吸气剂之外的任何东西,或后者除了一个setter之外的任何东西,但编译器无法解决它。
答案 2 :(得分:0)
回答标题问题“我可以覆盖接口属性”......绝对可以。以下是如何操作的示例。您只需将可覆盖关键字添加到基础具体实现中。我知道这并不能解决将属性更改为ReadOnly的问题,但我想我会指出覆盖基类的具体实现是可能的。
Module Module1
Sub Main()
Dim iEntity As IEntity = New MyEntity
iEntity.SetMessage(iEntity)
Console.WriteLine(iEntity.Message)
Console.ReadKey()
End Sub
End Module
Public Interface IEntity
Property Message As String
Sub SetMessage(entity As IEntity)
End Interface
Public Class MyEntity
Inherits BaseEntity
Public Overrides Property Message As String
Get
Return String.Format("{0}.. and overroad.", MyBase.Message)
End Get
Set(value As String)
MyBase.Message = value
End Set
End Property
Public Overrides Sub SetMessage(entity As IEntity)
Me.Message = "I was set from MyEntity."
End Sub
End Class
Public Class BaseEntity
Implements IEntity
Public Overridable Property Message As String Implements IEntity.Message
Public Overridable Sub SetMessage(entity As IEntity) Implements IEntity.SetMessage
Me.Message = "I was set from BaseEntity."
End Sub
End Class