Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confuse about scala private field variable

Tags:

scala

I am on my third day of scala study. Using book "begin scala".

Te author uses an example to show the diff between variable define with val var And without var val:

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

And in the console:

scala> val book = new Book("Beginning Scala")
book: Book = Book@ea05be
scala> book.printTitle(new Book("Beginning Erlang"))
Beginning Erlang

Here what confused me is not with/without val var, but the private modifier:

I am not sure if I understand private right, but if scala want title as private field, then why it allows others to access it from outside, I thought the prinTitle should not be able to access new Book("Beginning Erlang")'s title field

like image 754
Kuan Avatar asked Dec 20 '22 01:12

Kuan


2 Answers

The value title is private to the class, not to the instance, Since the method printTitle is a member of the class, it can access private values of other instances.

If you wanted title to be private to the instance, you would use the private[this] modifier instead.

Further, the private[package] modifier, where package is the name of the package the definition occurs in, can share the private member with the package. For example

package com.sample.foo

class Book(private[foo] title: String)

would be accessible to all code in package com.sample.foo

like image 115
Arne Claassen Avatar answered Jan 03 '23 03:01

Arne Claassen


title is a private field for class Book.

In Java you write this like:

class Book {
    private final String title;

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

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

I think the function printTitle may be somewhat confusing because in both java and scala it would usually not be implemented as an instance method. I would write something like that as a static method in java. And in scala I would put it into a companion object (to throw yet another alien concept at a confused scala newby ;)):

class Book(private val title: String)

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

So Book has access to any private field of any instance of Book.

If you want to restrict the access of title to an instance of Book you would write something like:

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

   def printTitle() {
       println(title)
   }
}
like image 44
Sascha Kolberg Avatar answered Jan 03 '23 01:01

Sascha Kolberg