2015-10-20 16 views
5

Tôi rất bối rối bởi Scala Constructors. Ví dụ, tôi có các lớp sau đại diện cho một cây với các toán tử như là Thêm và các nút lá trên cây là các số.Scala Constructor Confusion - vui lòng làm rõ

abstract class Node(symbol: String) {} 

abstract class Operator(symbol: String, 
     binaryOp: (Double, Double) => Double) extends Node(symbol) { 
} 

class Add(a: Number, b: Number) extends 
     Operator("+", (a: Double, b: Double) => a+b) { 
} 

class Number(symbol: String) extends Node(symbol) { 
    val value = symbol.toDouble 
    def this(num: Double) { 
     this(num.toString) 
    } 
} 

Tôi đọc trong một trang web rằng những gì diễn ra trong một constructor Scala là tự động thay đổi (val), nhưng anh chàng này trên Stack Overflow nói "The input parameters for the constructor are not vals unless you say they are." Vì vậy, đó là một mâu thuẫn.

Ngoài ra, tôi dường như có thể hoặc không cần phải thêm "val" và "ghi đè" vào các nhà thầu vì một lý do nào đó? Tôi có nghĩa là tôi muốn mọi thứ được công khai và không thay đổi và cho Thêm để có một biểu tượng bằng "+", một binaryOp bằng chức năng bổ sung, và cũng có hai số a và b. Ai đó có thể vui lòng giải thích làm thế nào để có được các nhà thầu để làm việc như mong đợi trong Scala một cách không tiết?

Tôi muốn để có thể làm điều gì đó như thế này:

addition = Add(Number(1), Number(2)) 
addition.binaryOp(addition.a.value, addition.b.value) 
+0

REPL gọi các tham số lớp. 'class C (x: Int) {def mod (y: Int): Unit = x = y}' tạo 'lỗi: gán lại cho val'. – jwvh

Trả lời

6

Bạn đang ở gần đó: Mỗi đối số cho các nhà xây dựng của một lớp Scala được vứt bỏ sau khi xây dựng các lớp học, trừ một phương pháp của lớp sử dụng nó. Trong trường hợp này, nó được tạo thành private[this] val.

Tuy nhiên, bạn chỉ có thể thêm từ khóa val/var trước tham số constructor của bạn và nó sẽ được thực hiện một công val/var:

abstract class Node(val symbol: String) {} 

Thông thường, đây không phải lặp đi lặp lại trong constructor cho lớp con nếu lĩnh vực này đã được xác định trong các lớp cha:

abstract class Operator(symbol: String, // no val here, only pass to super class 
     val binaryOp: (Double, Double) => Double) extends Node(symbol) { 
} 

class Add(val a: Number, val b: Number) extends 
    Operator("+", (a: Double, b: Double) => a+b) { 
} 

Bây giờ bạn có thể truy cập vào các lĩnh vực từ bên ngoài lớp:

addition = Add(Number(1), Number(2)) 
addition.binaryOp(addition.a.value, addition.b.value) 
+4

Nó cũng có thể đáng nói đến là các trường hợp có phần khác nhau (các tham số là 'vals' công khai theo mặc định), vì đó có thể là một nguồn gây nhầm lẫn khác. –

Các vấn đề liên quan