2015-08-12 2 views
4

Я нахожусь на третьем дне изучения scala. Использование книги «начать scala».Confuse about scala private field variable

Te автор использует пример, чтобы показать различия между переменным определить с валями варом и без вар Валу:

class Book(private val title: String) { 
    def printTitle(b: Book) { 
     println(b.title) 
    } 
} 

И в консоли:

scala> val book = new Book("Beginning Scala") 
book: Book = [email protected] 
scala> book.printTitle(new Book("Beginning Erlang")) 
Beginning Erlang 

Вот, что меня смутили не с/без val var, но частный модификатор:

Я не уверен, если я понимаю частное право, но если scala хочет титул как личное поле, то почему он позволяет другим получить к нему доступ из-за пределов, я думал, что prinTitle не должен быть в состоянии получить доступ к новой книге («Начало Эрланга») 'ы название поля

ответ

8

Значение title является частным к класс, а не экземпляр. Поскольку метод printTitle является членом класса, он может обращаться к приватным значениям других экземпляров.

Если вы хотите, чтобы title был закрыт для экземпляра, вместо этого вы должны использовать модификатор private[this].

Далее, модификатор private[package], где package - название пакета, в котором содержится определение, может совместно использовать частный элемент с пакетом. Например

package com.sample.foo 

class Book(private[foo] title: String) 

будет доступен для всего кода в пакете com.sample.foo

+0

Спасибо. Наверное, мне может понадобиться немного времени, чтобы понять все это. Чтобы убедиться, что я правильно понимаю, что вы имеете в виду: будет ли это «Заголовок значения приватным классу, а не экземпляру», понимать как «Заголовок значения является приватным для другого типа класса, а не экземпляру, сгенерированному из этого класса» ? – Kuan

+0

@ Kuan Исправить. Цель состоит в том, что экземпляры уже знают внутренности друг друга, поскольку они имеют один и тот же вид и поэтому получают доступ к ним.Но так как иногда вы действительно хотите жестко контролировать внутренности, существует частный [этот] модификатор, ограничивающий доступ только к экземпляру. –

+0

Я снова прочитал эту часть в книге, чтобы убедиться, что я понимаю, как класс работает правильно: могу ли я понять, что все поля класса Scala доступны через функцию getter и setter, а не напрямую обращаться к этой переменной? Таким образом, PRIVATE ограничивает доступ к функции set getter set (я не уверен, разрешает ли он только метод memeber или полностью удалять getter setter), чтобы заставить мир снаружи не иметь доступа к этой переменной? – Kuan

3

title является частным полем для класса Book.

В Java вы пишете это как:

class Book { 
    private final String title; 

    Book(String title) { 
     this.title = title; 
    } 

    public void printTitle(b: Book) { 
     System.out.println(b.title) 
    } 
} 

Я думаю, что функция printTitle может быть несколько запутанным, потому что в обоих Java и Scala было бы обычно не быть реализован как метод экземпляра. Я бы написал что-то вроде статического метода в java. И в Скале я бы поставил его в объект компаньона (бросить еще один инопланетную концепцию в запутанной лестнице Newby;)):

class Book(private val title: String) 

object Book { 
    def printTitle(b: Book) { 
     println(b.title) 
    } 
} 

Так Книга имеет доступ к любому частных поля любого экземпляра Книга.

Если вы хотите ограничить доступ заголовка к экземпляру книги можно было бы написать что-то вроде:

class Book(private[this] val title: String) { 
    // no longer compiles 
    // def printTitle(b: Book) { 
    // println(b.title) 
    //} 

    def printTitle() { 
     println(title) 
    } 
} 
+0

Черты. Прочитав это, я чувствую, что концепция PRIVATE отличается от JAVA и Scala (и здесь она более сложная и гибкая) – Kuan

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