2016-04-28 5 views
8

я следующий код:разница между защитой и защитой [это]

class Base{ 
    protected val alpha ="Alpha"; 
    protected def sayHello = "Hello"; 
} 
class Derived extends Base{ 
     val base = new Base; 
     def hello = println(this.alpha +" "+this.sayHello) ; 
     // def hello = println(base.alpha +" "+base.sayHello) ; // don't compile 
    } 

    object MyObj extends App{ 
      val x=new Derived; 
      x.hello; 
     } 

В классе Base, если я маркировать protected с this, код работает, как ожидалось; если я не назову его this, все работает так же, как ожидалось.

Действительно ли protected и protected[this] эквивалент в Scala? Если да, то почему Scala обеспечит оба? Если нет, то как они отличаются?

ответ

9

Scala protected и его братьев и сестер protected[this], protected[pkg] несколько подавляющим, однако я нашел легко запомнить решение, используя Java философию protected. первого Как защищенный член виден в Java

  1. Они видимы для подкласса (подкласс может быть в одном пакете или другой упаковке)
  2. Они видимы для любого класса, который находится в том же пакете, класс, который указывает защищенный член.

Очевидно, что они видны самому классу.

Но у Scala есть некоторые ограничения на то, как они видны подклассу. По умолчанию они видны только для подкласса. Они не видны для пакета, в котором объявлен класс. Однако существует два случая, как они видны в подклассе.

если защищенный член не имеет права (обычная защита), то она видна с других экземплярами объявляя класса в объявлении класса, а также с this в классе и подкласс, например

class Base{ 
    protected val alpha ="Alpha"; 
    protected def sayHello = "Hello"; 
} 
class Derived extends Base{ 
     def hello = println((new Derived()).sayHello) ; 
     def hello2 = println(this.sayHello); 

} 

если защищенный член имеет квалификацию this. Доступ только с помощью this в классе и подклассе. Доступ к другим экземплярам объявления класса или подкласса невозможен

class Base{ 
    protected val alpha ="Alpha"; 
    protected[this] def sayHello = "Hello"; 
    def foo = Console println(new Base().sayHello) // won't compile 
    def bar = Console println(this.sayHello) 
} 
class Derived extends Base{ 
     def hello = println(this.sayHello) ; 
     //def hello2 = println((new Derived() .sayHello) // won't compile 
} 

Поскольку Scala не поддерживает доступ уровня пакета защищаемого элемента по умолчанию .А если вы хотите, чтобы сделать его доступным на уровне пакета, то вам необходимо указать пакет явно, например, protected[pkg]. Теперь этот защищенный член виден с объявлением экземпляров класса/подкласса, если они доступны в классах, объявленных в pkg или ниже.

например.

package com.test.alpha{ 
class Base{ 
    protected val alpha ="Alpha"; 
    protected[test] def sayHello = "Hello"; // if you remove [test] it won't compile 
} 

class Derived extends Base{ 
    val base = new Base 
     def hello = println(base.sayHello) ; 
}} 

Это, как можно вспомнить Scala protected

0

Разница заключается в том, что с protected[this] подкласс экземпляра может получить доступ только свои собственные поля (this.x), в то время как с protected подкласс может получить доступ к полям во всех случаях (не только в this):

class Base{ 
    protected val alpha ="Alpha"; 
    protected[this] def sayHello = "Hello"; 
} 

class Derived extends Base{ 
    def hello = println(this.alpha +" "+this.sayHello) ; 
    def hello2 = println(
    new Derived().alpha +" " 
    +new Derived().sayHello) ; // error on "sayHello" 
} 

В этот код, вы можете получить доступ к this.sayHello, но не other.sayHello. У protected alpha нет таких ограничений.

+0

, что вы имеете в виду, что я могу получить доступ к '' base.alpha' в Derived' – optional

+0

Но это также показывает ошибку, я попробовал – optional

+0

я попробовал его в качестве вы спросили, но тот же результат, я использую Scala 2.11.7 – optional

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

  • Нет связанных вопросов^_^