Trước 2.8, bạn phải chọn giữa các gói và đối tượng. Vấn đề với các gói là chúng không thể chứa các phương thức hoặc các vals. Vì vậy, bạn phải đặt tất cả những người bên trong một đối tượng khác, mà có thể nhận được vụng về. Quan sát:
object Encrypt {
private val magicConstant = 0x12345678
def encryptInt(i: Int) = i^magicConstant
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = encryptInt(ii.next)
}
}
Bây giờ bạn có thể import Encrypt._
và truy cập vào các phương pháp encryptInt
cũng như lớp EncryptIterator
. Tiện dụng!
Ngược lại,
package encrypt {
object Encrypt {
private[encrypt] val magicConstant = 0x12345678
def encryptInt(i: Int) = i^magicConstant
}
class EncryptIterator(ii: Iterator[Int]) extends Iterator[Int] {
def hasNext = ii.hasNext
def next = Encrypt.encryptInt(ii.next)
}
}
Nó không phải là một sự khác biệt rất lớn , nhưng nó làm cho việc nhập khẩu sử dụng cả hai encrypt._
và encrypt.Encrypt._
hoặc phải tiếp tục viết Encrypt.encryptInt
hơn và hơn. Tại sao không chỉ sử dụng một đối tượng thay vào đó, như trong mẫu đầu tiên? (Thực sự không có hình phạt hiệu suất nào, vì các lớp lồng nhau không thực sự là các lớp bên trong Java dưới mui xe; chúng chỉ là các lớp thông thường theo như JVM biết, nhưng với các tên lạ mắt cho bạn biết chúng được lồng nhau.)
Trong 2.8, bạn có thể ăn bánh của bạn và ăn nó: gọi vật là vật thể gói và trình biên dịch sẽ viết lại mã cho bạn để nó trông giống như ví dụ thứ hai dưới mui xe (ngoại trừ đối tượng Encrypt
thực sự được gọi là package
nội bộ) , nhưng hoạt động giống như ví dụ đầu tiên về không gian tên - các vals và defs ngay tại đó mà không cần nhập thêm.
Vì vậy, các dự án đã bắt đầu trước 2,8 thường sử dụng các đối tượng để gửi kèm nhiều thứ như thể chúng là một gói. Post-2.8, một trong những động cơ chính đã bị loại bỏ. (Nhưng chỉ để được rõ ràng, sử dụng một đối tượng vẫn không bị tổn thương, nó là nhiều hơn mà nó là khái niệm gây hiểu nhầm hơn là nó có một tác động tiêu cực đến hiệu suất hoặc whatnot.)
(PS Xin vui lòng, không cố gắng để thực sự mã hóa bất cứ điều gì theo cách ngoại trừ ví dụ hoặc một trò đùa!)
Nguồn
2011-01-13 16:09:49
Lớp lồng trong một đối tượng có giống hệt với lớp bên trong tĩnh của Java không? Nếu tôi đặt 100 lớp bên trong, hoặc 100 đối tượng bên trong trong một đối tượng đồng hành, trình biên dịch sẽ xử lý chúng như thế nào? Tuyệt đối không có hình phạt về hiệu suất? – Sawyer
Một lớp lồng nhau 'Bar' bên trong một lớp hoặc đối tượng' Foo' được thực hiện không phải là một lớp bên trong mà là một lớp _outer_ với tên 'Foo $ Bar', và chỉ khi nó thực sự cần sử dụng lớp cha của nó thì nó sẽ có (trường sắp xếp ẩn) trỏ đến phụ huynh. Trình biên dịch thay vì JVM thi hành rằng bạn sử dụng đúng cách này và trong trường hợp của một đối tượng, nó biết chỉ có một đối tượng để nó không cần phải bận tâm lưu trữ trường đó. –