Programmingバックエンド開発者

Kotlinにおけるデータクラス、通常のクラス、および継承クラスの違いを説明してください。データクラスを使用すべき状況は何ですか?コンパイラが課す制約は何ですか?

Hintsage AIアシスタントで面接を突破

回答

Kotlinのdata classはデータを格納するために設計されています。コンパイラは自動的にequals()hashCode()toString()メソッド、さらにはcopy()およびcomponentN()関数を生成し、これによりそのようなオブジェクトとの作業が大幅に簡単になります:

data class User(val name: String, val age: Int) val u1 = User("Ivan", 30) val u2 = u1.copy(age = 31)

通常のクラスにはそのような自動生成されたメソッドがなく、すべてを手動で記述する必要があります。データクラスはDTO、モデル、およびデータ構造に使用するのが最適です。

データクラスに関する制約:

  • プライマリコンストラクターは、少なくとも1つのパラメーターを含む必要があります。
  • すべてのコンストラクタパラメーターはvalまたはvarとしてマークする必要があります。
  • データクラスはabstractopensealedまたはinnerにはできません。
  • ビジネスロジックや継承関係のあるクラスにデータクラスを使用することは推奨されません。

逆質問

"データクラスが別のデータクラスから継承されることはできますか?その理由(または理由ないか)何ですか?"

いいえ、データクラスは直接他のデータクラスから継承することはできません。データクラスはインターフェースまたは通常のクラス(データクラスではない)からのみ継承できます。これは、自動生成されたメソッドに関する混乱を避けるために設計されています(例:継承されたプロパティのコピーは明らかではありません)。

data class Base(val id: Int) data class Child(val name: String) : Base(1) // コンパイルエラー: 不許可

このテーマの詳細を知らないことによる実際のエラーの例


物語

銀行プロジェクトでは、ビジネスロジックと継承を伴うデータクラスが使用されていました。新しいフィールドを追加した後、オブジェクトを正しくコピーすることができなくなり、一部のビジネスロジックが失われ(メソッドが継承されなかった)、手数料の計算にエラーが発生しました。


物語

eコマースプラットフォームでは、ユーザーのカートの状態を保持するためにデータクラスが使用されていました。copy()で状態を更新した後、内部リストが深くコピーされないことを忘れてしまいました。その結果、ユーザーセッション間でデータが「漏れ」ました。


物語

外部APIとの統合プロジェクトでは、データクラスをJSONにシリアライズすると、プライベート可視性のフィールドが出現し、API契約が破られ、クライアント側でエラーが発生しました。