2011-07-11 26 views
7

xem xét lớp này đơn giản Scala:Sự khác biệt khi ghi đè trường xây dựng kế thừa?

class A(val d: Int) 

Có một sự khác biệt trong Scala (hoặc trong hành vi hoặc bytecode tạo ra) giữa

class B(d: Int) extends A(d) 

class B(override val d: Int) extends A(d) 

hoặc cả hai đều tương đương? Nếu chúng khác nhau, chúng ta sẽ sử dụng cái gì cho mỗi người trong số chúng?

Sẽ khác nếu A được định nghĩa là class A(var d: Int)?

Trả lời

9

Đối với các trò chơi, không có sự khác biệt ngữ nghĩa. Tuy nhiên, có thể có sự khác biệt trong bytecode được tạo ra. Đặc biệt, nếu một phương thức được định nghĩa trong lớp dẫn xuất đề cập đến d, nó tham chiếu đến tham số hàm tạo d thay vì là val cùng tên. Điều này được thực hiện thông qua một trường riêng bổ sung được tạo ra cho lớp dẫn xuất.

Đối với vars, có a khác biệt về hành vi. Nếu không ghi đè, bất kỳ phương thức nào tham chiếu đến d từ bên trong lớp dẫn xuất sẽ tham chiếu đến tham số hàm tạo, trong khi người gọi tham chiếu d từ bên ngoài lớp sẽ nhận được trường. Trong trường hợp này, hai giá trị có thể khác nhau (nếu giá trị đã thay đổi kể từ khi xây dựng).

Dưới đây là một phiên thể hiện hành vi với một var:

scala> class A(var d: Int) 
defined class A 

scala> class B(d: Int) extends A(d) { override def toString = "d: " + d } 
defined class B 

scala> val b = new B(1) 
b: B = d: 1 

scala> b.d = 2 

scala> b.d 
res1: Int = 2 

scala> b 
res2: B = d: 1 

Câu hỏi này có liên quan: Idiomatic Scala way to deal with base vs derived class field names?.

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