Inheritance Crystal:如何在child中用一个方法实现多个抽象方法?

Inheritance Crystal:如何在child中用一个方法实现多个抽象方法?,inheritance,abstract,crystal-lang,Inheritance,Abstract,Crystal Lang,假设我有一个抽象结构,它需要对两种类型的输入进行操作(如需了解更多上下文,请参阅) 如果我的实现可以互换使用self和Num,那么将它们放在一起似乎是合理的: struct Term < Numberlike alias Num = (Int32 | Float64) getter coeff : Num getter sym : Symbol def initialize(@coeff, @sym); end def -(other : self | Num)

假设我有一个抽象结构,它需要对两种类型的输入进行操作(如需了解更多上下文,请参阅)

如果我的实现可以互换使用
self
Num
,那么将它们放在一起似乎是合理的:

struct Term < Numberlike
  alias Num = (Int32 | Float64)
  getter coeff : Num
  getter sym : Symbol

  def initialize(@coeff, @sym); end

  def -(other : self | Num)
    self.class.new(coeff - other, sym)
  end

  def -
    self.class.new(-coeff, sym)
  end
end

这是一个非常简单的解决方案,但可能没有将这两种方法分开那么简单。您只需要将抽象方法更改为一个元组,而不是两个单独的方法。

我能想到的最好办法是在抽象类中定义联接方法,这有点类似于Samual所说的。如果采用这种方式,则实现结构可以单独或组合定义每个结构

abstract struct Addable
  abstract def +(other : self)
  abstract def +(other : Int32)
  def +(other : self | Int32)
    if other.is_a?(Int32) ? self + other : self + other
  end
end
其工作方式是,如果它们是由您单独定义的,那么组合方法将用于类型安全,但不会使用。如果将它们一起定义,则覆盖第三个方法,但其他两个方法不会给您带来麻烦,因为满足第三个条件的程序满足前两个条件


这里有一个演示:

不幸的是,这不起作用,我确实希望实现类处理这两种类型。如果它们的内部要求它们单独这样做,我不希望我的摘要阻止这一点。我的子类将使用两个实现,但现在它不能。好的,我想我已经找到了实现的方法。在抽象类中定义
#-(other:self | Num)
,该抽象类使用
#-(other:self)
#-(other:Num)
。除非定义了这两个方法,否则不应该编译它。如果你想同时定义两者,只需在子类中定义
#-(other:self | Num)
。我喜欢这个想法,但它假设我们提前知道如何将两者结合起来。对于减法,由于需要一个加法和求反运算符,这实际上是一件合理的事情。谢谢你指出!但它不能解决核心问题,也就是说,这对加法不起作用,一般来说,我们不能期望Num和self都能明确地共享逻辑。对吗?还是我遗漏了什么?
struct Term < Numberlike
  alias Num = (Int32 | Float64)
  getter coeff : Num
  getter sym : Symbol

  def initialize(@coeff, @sym); end

  def -(other : self)
    self.class.new(coeff - other, sym)
  end

  def -(other : Num)
    self.class.new(coeff - other, sym)
  end

  def -
    self.class.new(-coeff, sym)
  end
end
abstract struct Addable
  abstract def +(other : self)
  abstract def +(other : Int32)
  def +(other : self | Int32)
    if other.is_a?(Int32) ? self + other : self + other
  end
end