2011-01-31 8 views
12

次のJavaコードをScalaに変換するにはどうすればよいですか?Scalaインスタンス変数のベストプラクティス

class ClassA { 
    private int field1; 
    private int field2; 

    public ClassA() { 
     field1 = 1; 
     field2 = 2; 
    } 
} 

私は2つのオプションを見ることができます:推奨される何

class ClassA(val field1: Int, val field2: Int) { 
    .... 
} 

それとも

class ClassA { 
    val field1: Int = 1 
    val field2: Int = 2 
} 

を、なぜ?

+0

いずれのバージョンも同等です。両方のフィールドがJavaバージョンではプライベートで、表示されているScalaの代替ではpublicであるためです。おそらく、あなたが達成したいことについてより具体的に関心を持つでしょうか? –

答えて

4

プライベートフィールドを使用する場合は、プライベートフィールドをプライベートに宣言してください。

class ClassA { 
    private val field1: Int = 1 
    private val field2: Int = 2 
} 
5

最も大きな違いは、クラスパラメータ1をコンストラクタとして使用できることです。 Javaの例のようにコンストラクタにパラメータを持たせたくない場合は、2番目のものを使用し、@Debilskiの示唆するようにprivate修飾子を追加する必要があります。

もう1つのオプションは、コンストラクタでデフォルトのパラメータを使用することです。

class ClassA (private val field1: Int = 1, private val field2: Int = 2) 

// Using defaults 
val a = new ClassA 

// Setting new values 
val b = new ClassA(3, 4) 
+0

これは良い解決策ですが、OPのJavaコードと同等ではありません。 – Raphael

+0

@ラファエルそれは本当です。しかし、Javaの例はあまり意味がないように思えるので、いくつかのオプションが面白いかもしれないと思ったかもしれません:) – eivindw

1

あなた常には、そのフィールド1とフィールド2は、クラスAのインスタンスごとに同じ値を持って、私はコンパニオンモジュールでそれらを置くことをお勧めしたい場合:必要に応じてフィールドを変更することができること方法:

その後、
object A { 
    private val field1 = 1 
    private val field2 = 2 
} 

、クラスAにそれらを使用する:

class A { 
    def complexInternalComputation = 2*A.a 
} 

またはこのよう:

class A { 
    import A._ 
    def complexInternalComputation = 2*a 
} 
+0

これは動作しません。 'A.a'はクラスAのインスタンスからプライベートなのでアクセスできません。 – Raphael

+0

スカラーの仕様§5.2から:•プライベート・モデレーターは、テンプレート内の任意の宣言または宣言とともに使用することができます。そのようなメンバには、直接的に囲むテンプレートとそのコンパニオンモジュールまたはコンパニオンクラス(§5.4)内からのみアクセスできます。 – Nicolas

+0

しかし、REPLでは失敗しますが、ファイル内で動作します。 – Nicolas

16

JavaからScalaのへの簡単な変換は、それは文脈に依存して、存在しません:

  • は、Javaで変更可能な変数はありますか?はいの場合(そうでない場合は、Javaで最後になるはずです):Scalaで不変にすることは理にかなっていますか?
  • コンストラクタはScalaに公開されますか?ファクトリー(例: の適用メソッド)がもっと適切でしょうか?
  • なぜはプライベート変数ですか?彼らはゲッターやセッターを持っていますか?
  • 変数が必要なときは、怠け者にするのが理にかなっていますか?
  • 値が不変で公開されている場合、それらはパターンマッチングに役立つでしょうか?ケースクラスは正しい選択でしょうか?
  • APIとアクセスを簡略化するために、変数をグループ化することができますか(タプルなど)?

あなたには、非常に多くの考慮事項があります。私はScalaの可能性について学び、さまざまなアプローチで遊ぶことをお勧めします。そうでなければ、必要以上に長い "Scala as better Java"トラップに悩まされます。

class ClassA{ 
    private var field1 = 1 
    private var field2 = 2 
} 

var代わりのvalの利用:

8

これはScalaの最も直接的な翻訳があります。 valは不変フィールドで、Javaのpublic finalに対応します。したがって、後で変更することはできず、そのようなフィールドを特定のインスタンスの正しい値に初期化する方法を提供することが重要です。

あなたが使用したいものを決めるためには、Landeiの答えに記載されている質問をしてください。

+0

Javaのプライベート変数はプライベートではなくプライベートクラスなので、[this]を削除する必要があります。 – Submonoid

+0

@Submonoidありがとうございました。私はいつもそれを間違ってしまったようです。 :) – ziggystar