2017-09-12 12 views
0
Javaでは

データクラスに単純継承を使用するには? Kotlinで

abstract class NumericValue{ 
    private String a; 
    private String b; 

    public String getA() { return a; } 

    public void setA(String a) { this.a = a; } 

    public String getB() { return b; } 

    public void setB(String b) { this.b = b; } 

    @Override 
    public boolean equals(Object o) { 
     if (this == o) return true; 
     if (o == null || getClass() != o.getClass()) return false; 

     NumericValue that = (NumericValue) o; 

     if (a != null ? !a.equals(that.a) : that.a != null) return false; 
     return b != null ? b.equals(that.b) : that.b == null; 
    } 

    @Override 
    public int hashCode() { 
     int result = a != null ? a.hashCode() : 0; 
     result = 31 * result + (b != null ? b.hashCode() : 0); 
     return result; 
    } 
} 

class Abc extends NumericValue{ 
    public static void main(String[] args) { 
     Abc abc = new Abc(); 
     abc.getA(); 
    } 
} 

、これはに要約:アプローチ2

sealed class NumericValueA{ 
    abstract var a: String 
    abstract var b: String 
} 

data class AbcA(
     override var a:String, 
     override var b:String 
):NumericValueA() 

open class NumericValueB(
     open var a:String, 
     open var b:String 
) 

data class AbcB(
     override var a:String, 
     override var b:String 
):NumericValueB(a,b) 

両方のアプローチは、大規模な複製する傾向

アプローチ1あなたが持っているので単に属性を継承するデータクラスがあるときあなたが指定したものすべてをもう一度書き留める - これは単に縮尺が変わっていて何らかの形で間違っていると感じます。

これは最新のJavaコードをkotlinに翻訳する最善の方法ですか?

+0

私はあなたが何をしようとしているのか分かりません。私は翻訳することをJavaの、のように、この(書式設定のための私の謝罪): '抽象クラスNumericValue { 抽象するvar A:文字列 抽象するvar B:文字列 } データクラスAbcの( オーバーライドするvar A:文字列、 オーバーライドするvar B:String)を :NumericValue() 楽しいメイン(可変引数引数:文字列){ ヴァル・ABC = Abcの( "A"、 "B") ヴァルA = abc.a } 'あなただけではないですASのオートトランスレーションに満足していますか? –

答えて

1

IntelliJ IdeaはJavaコードを次のように変換します。これはボイラープレートでは合理的であり、減少しています。だから、私は答えます、 "いいえ、あなたの前提は、コトルが最先端であるかどうかを正確に特徴づけるものではありません"。

internal abstract class NumericValue { 
    var a: String? = null 
    var b: String? = null 

    override fun equals(o: Any?): Boolean { 
     if (this === o) return true 
     if (o == null || javaClass != o.javaClass) return false 

     val that = o as NumericValue? 

     if (if (a != null) a != that!!.a else that!!.a != null) return false 
     return if (b != null) b == that.b else that.b == null 
    } 

    override fun hashCode(): Int { 
     var result = if (a != null) a!!.hashCode() else 0 
     result = 31 * result + if (b != null) b!!.hashCode() else 0 
     return result 
    } 
} 

internal class Abc : NumericValue() { 
    companion object { 
     @JvmStatic 
     fun main(args: Array<String>) { 
      val abc = Abc() 
      abc.a 
     } 
    } 
} 

あなたの質問は特に "データ"クラスを対象としています。データクラスは、私たちに「分解」と、分解のために自動的に生成されるいくつかの有用なメソッド(例えば、componentN)を与える、言語の素晴らしいコンポーネントです。したがって、上のコードを使用して(openをクラスに追加し、abの宣言を追加する)、ここでは派生クラスの実装例が少し異なります。その中で、合理的なようだ

internal data class AbcB (override var a: String?, override var b: String?) : NumericValue() { 
    companion object { 
     @JvmStatic 
     fun main(args: Array<String>) { 
      val abc = AbcB("a","b") 
      println("b = " + abc.component2()) 
      val n: NumericValue = abc 
      println("a = " + n.a) 
     } 
    } 
} 

は、あなたの開始の例では、データのクラスではなく、あなたの明白な欲求がKotlinデータクラスを利用することです。もう少し多くのコード・ベリファイを犠牲にして、必要な場合には望ましい機能を提供します。

sealedabとし、基数をabstractと宣言した場合、派生クラスは同じコードです。

したがって、データクラスの場合、です。派生クラスの「データ」として公開するベースクラスの一部を複製しています(すでに公開されています。以下の例に示すように、特別会員)。しかし、これは他のコンテキストでの上書きに似ています。考えただけで、次の派生クラスを考えてみましょう。

internal data class AbcCD (var c: String?, var d: String?) : NumericValue() { 
    companion object { 
     @JvmStatic 
     fun x() { 
      val abc = AbcCD("c","d") 
      abc.b = "B" 
      abc.a = "A" 
      println("d = " + abc.component2()) 
      abc.a 
     } 
    } 
} 

基本クラスのすべてのメンバーと、派生クラスの新しいデータメンバーを取得します。しかし、オーバーライドのメリットが必要な場合は、(派生データクラスと通常クラスの)文法的なバケットのコストがかかります。

最後の1つです。データクラスにはまだ継承やオーバーライドに関連する他の奇妙さがありますが、それでも解決する必要があるかもしれません。 toString,hashCodeおよびequalsは独自の特別な実装を得て、documentationは言う...スーパークラスのデータクラス体または最終実装のequals()、ハッシュコード()またはのtoString()の明示的な実装が存在する場合

、次にこれらの関数は生成されず、既存の実装が使用されています。

...私は読んで紛らわしいと思っています(私は、ドキュメントに頼るのではなく実験しています)。そして、toStringとデータクラス(例えば、this OP trying to create a DTO)の苦労を扱う他のSOの質問があります。

だからだから、これは最先端の技術だと思うし、それほど悪くない(IMO)。そして、データクラスの機能が必要な場合は、これまでと同じように変換できます。

+0

十分に単純ですが、私の質問は明示的にデータクラスを対象としています。それはどうやってこの説明に変換されますか? – Chris

+0

私の更新を見てください。 – Les

+0

詳細な説明をありがとう!その過程で私はデータクラスが必要ないかもしれないことに気がついたので、それを試してみましょう。 – Chris

関連する問題