当未明确给出返回类型时,为什么可以用返回字符串的方法覆盖返回单元的方法?


11

我正在阅读有关Scala Edition1中编程特性的章节中的代码示例, 网址为https://www.artima.com/pins1ed/traits.html

并由于我的错字而遇到奇怪的行为。尽管代码段下面的特征覆盖方法不会产生任何编译错误,但是覆盖方法的返回类型Unit与相对String。但是,在对象上调用该方法时,它返回Unit,但不打印任何内容。

trait Philosophical {
    def philosophize = println("I consume memory, therefore I am!")
}

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize = "It aint easy to be " + toString + "!"
}

val frog = new Frog
//frog: Frog = green

frog.philosophize
// no message printed on console

val f = frog.philosophize
//f: Unit = ()

但是,当我在重写的方法中给出显式的返回类型时,它会产生编译错误:

class Frog extends Philosophical {
  override def toString = "green"
  override def philosophize: String = "It aint easy to be " + toString + "!"
}
         override def philosophize: String = "It aint easy to be " + toString +
                      ^
On line 3: error: incompatible type in overriding
       def philosophize: Unit (defined in trait Philosophical);
        found   : => String
        required: => Unit

任何人都可以帮助解释为什么在第一种情况下没有编译错误。


编译器已打印出一个有效的提示,您可以尝试覆盖具有不同结果类型的方法。
安德里·普洛霍特努克

确实是的,但是我的问题是为什么它在第一种情况下通过了编译器
Shanil

1
经验法则,对于返回类型_(尤其是在公共API上)_总是要明确的。类型推断非常适合局部变量,仅此而已。
Luis MiguelMejíaSuárez'19

Answers:



6

我的问题是为什么它在第一种情况下通过了编译器

当您未明确指定返回类型时,它是通过其工作所需的类型推断出来的override

原来是Unit

由于可以将String值(组成函数主体的表达式的值)分配给Unit,因此编译器很高兴。


1
我现在想知道的是为什么显式返回类型String被拒绝。在Java中(我也认为在Scala中),您可以在覆盖时缩小返回类型。例如,当父方法返回时Number,您可以返回Integer。也许void/ Unit很特别。
Thilo

1
例如,这可以进行编译:trait Philosophical { def philosophize : Number = 1 } class Frog extends Philosophical { override def philosophize : Integer = 2 }
Thilo

2
您可以将返回类型缩小为子类型。但是您不能将其范围缩小到只能隐式转换为重写方法的返回类型的类型。即使不是完全一样,Stringto Unit也更像第二个。
阿列克谢·罗曼诺夫

2
在字节码水平没有缩小返回类型要么,实际上有两种方法Frogdef philosophize : Integerdef philosophize : Number。第二个方法实际上覆盖Philosophical的方法(并调用第一个方法)。当然,void其他任何事情都可以做,设计师只是决定不做。
阿列克谢·罗曼诺夫

2
1. Java也是如此。2.是的,您可以使用字节码。参见例如stackoverflow.com/questions/18655541/…stackoverflow.com/questions/58065680/…
阿列克谢·罗曼诺夫
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.