我正在尝试编写一个部分实现接口的抽象类。我还想为未实现的值设置默认值。似乎F#可能不支持这一点,但同样可能的是我不能使语法正确。任何帮助,将不胜感激。这就是我到目前为止所处的位置:
type IDrawable =
abstract member Position : Vector2
abstract member ShortSymbol : int
abstract member ForeColor : string
abstract member BackColor : string
abstract member Symbol : char
abstract member Description : string
[<AbstractClass>]
type DrawableBase(position, shortSymbol, foreColor, backColor) =
let position : Vector2 = position
let shortSymbol : int = shortSymbol
let foreColor : string = foreColor
let backColor : string = backColor
interface IDrawable with
member this.Position = position
member this.ShortSymbol = shortSymbol
member this.ForeColor = foreColor
member this.BackColor = backColor
default this.Symbol = char this.ShortSymbol
default this.Description = ""
new(oldBase: DrawableBase, newPosition) = DrawableBase(newPosition, oldBase.ShortSymbol, oldBase.ForeColor, oldBase.BackColor)
这是一个学习项目,因此大部分内容并不重要 - 我也可能在这里做其他一些错误 - 随意批评。
答案 0 :(得分:1)
我没有听说过部分接口实现,即使我在F#中使用类型继承和接口完成了一些OOP工作。您可以在基类的虚拟成员中获得相同的结果:
type IDrawable =
abstract member Position : Vector2
abstract member ShortSymbol : int
abstract member ForeColor : string
abstract member BackColor : string
abstract member Symbol : char
abstract member Description : string
[<AbstractClass>]
type DrawableBase(position, shortSymbol, foreColor, backColor) =
let position : Vector2 = position
let shortSymbol : int = shortSymbol
let foreColor : string = foreColor
let backColor : string = backColor
abstract member Symbol : char
default this.Symbol = char shortSymbol
abstract member Description : string
default this.Description = ""
interface IDrawable with
member this.Position = position
member this.ShortSymbol = shortSymbol
member this.ForeColor = foreColor
member this.BackColor = backColor
member this.Symbol = this.Symbol
member this.Description = this.Description
因为F#中的接口是显式的,所以我更喜欢将所有接口成员实现为对相应类型成员的调用。例如。在前面的例子中,构造函数抱怨oldBase没有我添加的两个虚拟成员之外的成员:
new(oldBase: DrawableBase, newPosition) = DrawableBase(newPosition, oldBase.ShortSymbol, oldBase.ForeColor, oldBase.BackColor)
一种解决方案是将oldBase
的类型更改为IDrawable
:
new(oldBase: IDrawable, newPosition) = DrawableBase(newPosition, oldBase.ShortSymbol, oldBase.ForeColor, oldBase.BackColor)
另一种解决方案是将所有方法添加到类型本身。这样更方便,因为它允许避免在许多地方进行显式转换,并以C#方式使用类(其中接口是隐式实现的),而不需要在需要调用接口成员的每个地方烦恼:>
:
[<AbstractClass>]
type DrawableBase(position, shortSymbol, foreColor, backColor) =
let position : Vector2 = position
let shortSymbol : int = shortSymbol
let foreColor : string = foreColor
let backColor : string = backColor
member this.Position = position
member this.ShortSymbol = shortSymbol
member this.ForeColor = foreColor
member this.BackColor = backColor
abstract member Symbol : char
default this.Symbol = char shortSymbol
abstract member Description : string
default this.Description = ""
interface IDrawable with
member this.Position = this.Position
member this.ShortSymbol = this.ShortSymbol
member this.ForeColor = this.ForeColor
member this.BackColor = this.BackColor
member this.Symbol = this.Symbol
member this.Description = this.Description
new(oldBase: DrawableBase, newPosition) = DrawableBase(newPosition, oldBase.ShortSymbol, oldBase.ForeColor, oldBase.BackColor)
请注意,在极少数情况下,您希望实现接口而不是对类型成员的调用,而是直接作为对字段或私有方法的调用(即复制某些代码并将其作为member this.Position = position
内部接口,如类型成员)。这是因为对于类型层次结构,JIT级别的内联虚拟方法和接口并不总是像简单类一样工作,因此调用member this.Position = this.Position
会产生额外的虚拟调用开销。但这仅在您需要 nano 优化时才重要,例如将性能从100 Mops增加到150 Mops的简单方法。
答案 1 :(得分:0)
在MSDN上查看F#接口的页面https://msdn.microsoft.com/en-us/library/dd233207.aspx
default
永远不会对类中的接口实现有效。
然而,再次来自文档
但是,您可以通过包括a来提供默认实现 单独定义成员作为一种方法与 默认关键字