2.8より前では、パッケージとオブジェクトのどちらかを選択する必要がありました。パッケージの問題は、独自のメソッドやvalを含むことができないことです。だからあなたはそれらをすべて別のオブジェクトの中に入れなければなりません。お守り:
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)
}
}
今import Encrypt._
できるとクラスEncryptIterator
と同様の方法encryptInt
へのアクセスを得ます。ハンディ!これとは対照的に
、
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)
}
}
それは巨大違いはありませんが、それは、ユーザーのインポートencrypt._
とencrypt.Encrypt._
または両方が、何度もEncrypt.encryptInt
を書いて維持する必要があります。最初のパターンのように、代わりにオブジェクトを使用するのはなぜですか?ネストされたクラスは実際にはJava内部クラスではなく、JVMが知っている限り普通のクラスですが、入れ子になっているという派手な名前が付いています)
In 2。8、あなたはあなたのケーキを持って、それも食べることができます:パッケージオブジェクトを呼び出すと、コンパイラはあなたのコードを書き直すので実際にはフードの下の2番目の例のように見えます(Encrypt
は実際にはpackage
と呼ばれます)名前空間に関して最初の例のように動作します。余分なインポートを必要とせずに、valとdefがすぐそこにあります。
したがって、2.8より前に開始されたプロジェクトでは、多くのものをパッケージのように囲むためにオブジェクトを使用することがよくあります。ポスト2.8、主な動機の1つが削除されました。 (ただし、オブジェクトを使用しても傷つくことはありませんが、パフォーマンスやその他のものに悪影響を与えるよりも、概念的に誤解を招く可能性があります)。
そのようなことを例や冗談以外の方法で暗号化してください!)
オブジェクトのネストされたクラスは、Javaの静的内部クラスとまったく同じですか?コンパニオンオブジェクトに100の内部クラスまたは100の内部オブジェクトを置くと、コンパイラはそれらをどのように扱いますか?パフォーマンスのペナルティはありませんか? – Sawyer
クラスまたはオブジェクト 'Foo'内のネストされたクラス' Bar'は、内部クラスではなく、 'Foo $ Bar'という名前の_outer_クラスとして実装され、実際にその親クラスを使用する必要がある場合にのみ、親を指し示す(sort-of-hidden)フィールド。 JVMではなくコンパイラがこれを適切に使用するように強制します。オブジェクトの場合は、そのフィールドが1つしかないので、そのフィールドの格納に気をつける必要はありません。 –