Giải pháp của Paolo rất tốt (+1), nhưng anh ấy không giải thích được thông báo lỗi, vì vậy hãy để tôi thử điều đó. Vấn đề xuất phát từ thực tế là mọi phương thức đều cần kiểu trả về. Định nghĩa ban đầu của bạn là apply
và dual
trả về một đối tượng là class A
, do đó kiểu trả về ngầm của cả hai là A
. Điều đó ngụ ý rằng A
phải được hiển thị cho khách hàng - làm cách nào khác họ có thể gọi chức năng hoặc truy cập vào val
? Hơn nữa, như cả hai - và đối tượng cha mẹ của họ quá - là công khai, họ có thể nhìn thấy trên toàn cầu. Tuy nhiên, bạn khai báo A private
có nghĩa là nó không được hiển thị bên ngoài gói của nó. Vì vậy, có một xung đột mà không thể được giải quyết bởi trình biên dịch.
Quy tắc chung là tất cả thông số và kiểu trả về của hàm/thành viên phải có (ít nhất) phạm vi hiển thị giống như chính thành viên giới thiệu *. Do đó, một cách tầm thường để giải quyết vấn đề này là giảm mức độ hiển thị của apply
và dual
thành private
. Điều này sẽ thỏa mãn trình biên dịch, nhưng không phải bạn :-)
Giải pháp của bạn xung quanh vấn đề bằng cách thay đổi kiểu trả về tĩnh thành một đặc điểm public
, do đó có khả năng hiển thị giống như các thành viên đề cập đến nó. Loại động của đối tượng được trả về vẫn là class A
, tuy nhiên, điều này không cần hiển thị đối với khách hàng. Đây là một ví dụ kinh điển về nguyên tắc "program to interfaces, not implementations".
Lưu ý rằng để áp dụng nguyên tắc này để đầy đủ mức độ, người ta có thể biến class A
thành một lớp bên trong private
của object A
, do đó làm cho nó innaccessible ngay cả đối với các lớp khác trong cùng một gói:
trait A {
//...
}
object A {
def apply: A = dual
lazy val dual: A = new AImpl
private class AImpl extends A {
//some irrelevant logic...
}
}
* Để được pedantic, lớp kèm theo/đối tượng có thể làm giảm khả năng hiển thị của các thành viên của nó, giống như ở đây:
private class Holder {
def member = new Hidden
}
private class Hidden
nơi member
là public
nhưng lớp kèm theo của nó là private
, ẩn các thành viên của nó một cách hiệu quả khỏi thế giới bên ngoài. Vì vậy, trình biên dịch phát ra không có khiếu nại ở đây.
hehehe truy cập vào từng cá nhân khác –
@ AK4749, sau tất cả, đó là bạn đồng hành của chúng tôi mà chúng tôi đang nói đến. Nó không giống như lớp học chỉ là cho phép _anyone_ để truy cập vào tư nhân của cô ... Mặc dù khi _reflection _... –