2012-10-09 25 views
17

Xin lỗi vì tiêu đề hấp dẫn. ;-)Tôi có thể không có lớp học riêng tư ở Scala?

Tôi muốn tạo ra một lớp gói tin với một phương pháp gói tin trong Scala, vì vậy lớp học của tôi trông hơi như thế này:

package net.java.truevfs.ext.pace 

import ... 

private[pace] abstract class AspectController(controller: FsController) 
extends FsDecoratingController(controller) { 

    private[pace] def apply[V](operation: => V): V 

    ... // lots of other stuff 
} 

Tuy nhiên, nếu tôi sử dụng javap để kiểm tra những gì Scala biên dịch một cách hiệu quả tạo ra, tôi nhận được một cái gì đó như thế này:

$ javap -classpath target/classes net.java.truevfs.ext.pace.AspectController 
Compiled from "AspectController.scala" 
public abstract class net.java.truevfs.ext.pace.AspectController extends net.java.truevfs.kernel.spec.FsDecoratingController implements scala.ScalaObject{ 
    public abstract java.lang.Object apply(scala.Function0); 
    ... 
} 

điều này có nghĩa rằng mặc dù các trình biên dịch Scala có thể tôn trọng hạn chế truy cập, tôi vẫn có thể gọi lớp này từ bất kỳ mã Java, đó là một sự vi phạm đóng gói rõ ràng.

Tôi có thiếu gì đó không? Có cách nào để thực hiện công việc này như dự định không?

+2

+1 cho tiêu đề hài hước –

Trả lời

15

Ngoài @ Régis' câu trả lời, lý do Scala trình biên dịch không làm cho lớp gói tin là bởi vì Scala cai trị nó thể được truy cập từ các gói khác: cụ thể là, các gói con của net.java.truevfs.ext.pace. Ví dụ.

package net.java.truevfs.ext.pace.subpackage 
import net.java.truevfs.ext.pace.AspectController 

class Subclass extends AspectController { ... } 

là hợp pháp ở Scala, nhưng trong Java các lớp học từ net.java.truevfs.ext.pace.subpackage không thể truy cập các lớp học gói-tư nhân từ net.java.truevfs.ext.pace.

+0

+1. Tôi đã thực sự đi đến điểm giống nhau. –

+0

Điểm tốt - Tôi không biết điều này. –

+0

Vâng, điều này thực sự có nghĩa là khái niệm về một gói riêng tư không tồn tại trong Scala. Quá tệ, bởi vì đối với tôi nó đã là một yếu tố chính của công cụ Java của tôi được thiết lập để thúc đẩy đóng gói (tôi hiểu rằng việc bảo vệ này chỉ hoạt động ở cấp độ ngôn ngữ anyway). –

9

Bạn không thiếu gì cả. Nhiều hạn chế truy cập trong scala không tương đương với java hay cấp jvm. Các thông tin bổ sung rõ ràng là ngay trong tệp .class, nhưng là có chú thích tùy chỉnh mà chỉ trình biên dịch scala sẽ giải thích. Mô hình đối tượng scala chỉ có thể được kết hợp một phần với mô hình đối tượng jvm và trình biên dịch java sẽ chỉ thấy mô hình một phần này. Tôi muốn nói rằng trận đấu là khá gần và trình biên dịch scala làm một công việc rất tốt tại khả năng tương tác java, nhưng nothings hoàn hảo.

+0

Tôi đã nghĩ như vậy và nhận ra chú thích @ scala.reflect.ScalaSignature trên lớp học. Điều lo lắng cho tôi mặc dù đây là một sự vi phạm rõ ràng về đóng gói và làm cho việc sử dụng các công cụ sửa đổi truy cập hoàn toàn vô nghĩa miễn là bạn có thể gọi bất cứ thứ gì từ mã Java. –

+3

Vâng, "vô nghĩa" với cùng mức độ truy cập các công cụ sửa đổi nói chung là vô nghĩa, vì bạn luôn có thể bỏ qua chúng thông qua sự phản chiếu/con trỏ. – themel

+0

Tôi sẽ không đi xa như nói rằng bạn có thể gọi "bất cứ điều gì" từ java. Nếu bạn làm cho 'apply' plain private (trái ngược với private thành' speed') thì bạn sẽ thấy rằng phương thức này thực sự được đánh dấu là private trong tệp .class. Điều này là do khái niệm về một phương thức riêng trong scala và trong java là chính xác như nhau, do đó trình biên dịch có thể đánh dấu nó là riêng tư. Mặt khác, khái niệm về một phương thức riêng tư cho một gói đơn giản là không tồn tại trong java/jvm. –

1

Không thực sự là một câu trả lời đúng 100% ...

Bạn có thể làm cho một đối tượng gói nếu tôi muốn làm một số công cụ ưa thích trong đó với một lớp riêng. Đối tượng gói được truy cập giống như bất kỳ gói nào khác. Lớp MyClass là gói riêng tư đối với đối tượng gói đó. Tuy nhiên, gói này không phải là gói riêng tư.

package object com.jasongoodwin.foo { 
    private class MyClass 

    class AnotherClass { 
    val myClass = new MyClass 
    } 
} 
Các vấn đề liên quan