В чем разница между различными переопределенными методами в Scala?

Scala позволяет переопределить метод двумя законными способами:

Данный супер класс:

class A {
  def a = "A"
}

Мы можем переопределить метод & quot; a & quot; от:

class B extends A {
  override def a = "B"
}

а также

class B extends A {
  override def a() = "B"
}

оба, похоже, переопределяют метод "a" правильно. Какое дизайнерское решение стоит за этим? Зачем использовать & quot; a () & quot; в B, чтобы переопределить "a" в?

 oldrinb01 сент. 2012 г., 23:30
a() а такжеa оба метода названыa которые не принимают аргументов, т. е. имеют нулевую арность, то есть они идентичны. Почему бы им этого не позволить?

Ответы на вопрос(1)

Решение Вопроса

Это не всегда имело место (из журнала измененийспецификация языка):

Scala version 2.0 also relaxes the rules of overriding with respect to empty parameter lists. The revised definition of matching members (§5.1.3) makes it now possible to override a method with an explicit, but empty parameter list () with a parameterless method, and vice versa.

Вы правы, что это кажется странным дизайнерским решением, учитывая, что наблюдаются различия между методами без параметров и с пустыми списками параметров. Например, предположим, у вас есть следующее:

class A { def a = "A" }
class B extends A { override def a = "B" }
class C extends A { override def a() = "C" }

Теперь мы можем написать следующее, как и ожидалось:

scala> (new B).a
res0: java.lang.String = B

scala> (new C).a
res1: java.lang.String = C

И это:

scala> (new C).a()
res2: java.lang.String = C

Но не это

scala> (new B).a()
<console>:10: error: not enough arguments for method apply: (index: Int)Char in class StringOps.
Unspecified value parameter index.
              (new B).a()

Таким образом, Scala делает различие между ними, что, очевидно, должно быть отражено в байт-коде. Предположим, мы скомпилировали следующее:

class A { def a = "A" }
class B extends A { override def a = "B" }

А затем запустите:

javap -verbose B > noArgList.txt

Затем измените код на это:

class A { def a = "A" }
class B extends A { override def a() = "B" }

Перекомпилируйте и запустите:

javap -verbose B > emptyArgList.txt

И, наконец, проверьте различия:

<   MD5 checksum 88aeebf57b645fce2b2fcd2f81acdbbd
---
>   MD5 checksum 3733b3e4181b4b2f4993503d4c05770e
32c32
<   #18 = Utf8               }1A!
                                 \t\t!ICaT-9uszaE\r)\"a\tI!!\"1Q!Dg
jiz\"a\tAQ!BY\t!Y                                                  G.Y11bU2bY|%M[3di\")C%1A(
                 /A$H3)!dGYtwMCQM^1\nyI\"AB*ue&tw\r
---
>   #18 = Utf8               }1A!
                                 \t\t!ICaT-9uszaE\r)\"a\tI!!\"1Q!Dg
jiz\"a\tAQ!BY\t!                                                   G.Y11bU2bY|%M[3di\")C%1A(
                /A$H3)!dGYtwMCQM^1\nyI\"AB*ue&tw\r

Таким образом, существует различие - две версии имеют разные значения дляScalaSignature аннотаций.

Относительноwhy изменение было сделано в Scala 2.0: спецификация отмечает, что это позволяет:

class C {
    override def toString: String = ...
}

Я предполагаю, что разработчики языка просто не видели причины требовать от пользователей запоминать, какой подход используется в переопределенных методах, используемых в подобных случаях.

 platypus02 сент. 2012 г., 07:51
Поскольку я только начинаю изучать Scala, не могли бы вы рассказать, для чего используется аннотация ScalaSignature?
 02 сент. 2012 г., 13:12
Это довольно низкоуровневая деталь реализации, о которой вам не нужно долго беспокоиться,if ever, Его роль - позволить компилятору Scala проводить подобные различия.

Ваш ответ на вопрос