2013-11-13 2 views
4

Я запутался следующее:Перекрытие вал в Скале

class A(val s: String) { 
def supershow { 
    println(s) 
} 
} 


class B(override val s: String) extends A("why don't I see this?"){ 
    def show { 
    println(s) 
    } 
    def showSuper { 
    super.supershow 
    } 
} 

object A extends App { 
    val b = new B("mystring") 
    b.show 
    b.showSuper 
} 

я ожидал:

mystring 
why don't I see this? 

Но я получаю:

mystring 
mystring 

В Java, если переопределить, или «тень» переменной в суперклассе, суперкласс имеет свои собственные переменные. Но здесь, хотя я думаю, что я явно инициализирую родителя с другой строкой, родитель получает то же значение, что и подкласс?

ответ

9

В scalaval аналогичен методу геттера в java. Вы можете даже переопределить def с val.

Если вам нужно что-то похожее на поле от java вы должны использовать private[this] val:

class A(private[this] val s: String) { 
    def superShow() = println(s) 
} 
class B(private[this] val s: String) extends A("why don't I see this?") { 
    def show() = println(s) 
} 

val b = new B("message") 
b.show 
// message 
b.superShow() 
// why don't I see this? 
+0

Спасибо. Это полезно, хотя я теперь полностью смущен насчет val и var и переопределяет. Знаете ли вы о четком описании того, как все они работают, и о философии? На данный момент это все большая путаница в моей голове - это похоже на множество специальных правил для разных ситуаций, подобных этому из кулинарной книги scala. Как показано в примере, поля признака могут быть объявлены как var или val. do необходимо использовать ключевое слово override для переопределения поля var в подклассе (или признаке), но вы должны использовать его для переопределения поля val. «Я не могу найти базовую согласованность. Благодаря! – Bruce

+0

@Bruce: Я уверен, что есть такой ответ на SO. 'def' - метод. 'val' -« стабильный »метод (getter), инициализированный в конструкторе. 'var varName: T' - пара методов' def varName: T' и 'def vatName _ = (T): Unit'. 'lazy val' -« стабильный »метод, реализованный как двойной контроль блокировки. Вы можете переопределить 'def' с любыми {' def', 'val',' var', 'lazy val'}, вы также можете переопределить' lazy val' с 'val'. – senia

+0

Спасибо. Я читал несколько книг scala и еще не видел val, описанный как метод или даже как метод. Тем не менее, способ, которым вы его описываете, кажется, что это хороший способ взглянуть на вещи, и может помочь мне понять это. Спасибо за вашу помощь! – Bruce

Смежные вопросы