[kotlin]Data Class

2018. 6. 18. 00:28kotlin-이론

Data Class


Data Class

데이터 클래스란 클래스가 data를 보유하면서 아무것도 하지 않는 클래스이다. 



사용법

data class User(var name:String, var age:Int)


하지만 

데이터 클래스는 데이터를 조금 더 편하게 사용하라고 컴파일러가 컴파일 할 때 


  • equals()
  • hashCode()
  • copy()
  • toString()
  • componentsN() 

등의 함수를 제공해주고 있다. 명시적으로 제공해주는 경우에는 컴파일러가 자동으로 생성해주지 않는다. 


좋은 데이터 클래스의 조건

  • 기본 생성자에 1개 이상의 파라메터 
  • 기본 생성자의 파라미터가 var, val로 생성 
  • Data Class는 abstract, open, sealed, Inner를 사용하지 못함 

코틀린 1.1버전 이후에 바뀐 data class 

1. interface 구현 가능 
2. sealed 클래스 상속 가능 



data class User(var name:String = "", var age:Int = 0 )
class Use(var name:String, var age:Int)

fun main(args: Array) {     var exam = User()
    var exam1 = User("후니쓰")
    var exam2 = User(age = 22)
    var exam3 = User("후니쓰", 22)
    var test = Use("후니쓰", 24)
    
    println("User 사용 "+exam3)
    println("Use 사용 "+test)
}


일반 클래스와 데이터 클래스를 비교해보면  데이터 클래스는 입력한 정보가 나오지만 일반 클래스는 주소값이 나온다. 따라서 데이터를 다루어야할 때는 데이터 클래스가 많이 유용할 것 이다. 



이제 데이터 클래스가 갖고 있는 함수에 대해 얘기 해보겠다. 아래에는 위의 User라는 클래스를 디컴파일 했을 때의 자바소스코드이다. 


public final class User {
   @NotNull
   private String name;
   private int age;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final void setName(@NotNull String var1) {
      Intrinsics.checkParameterIsNotNull(var1, "");
      this.name = var1;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public User(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
      this.age = age;
   }

   // $FF: synthetic method
   public User(String var1, int var2, int var3, DefaultConstructorMarker var4) {
      if ((var3 & 1) != 0) {
         var1 = "";
      }

      if ((var3 & 2) != 0) {
         var2 = 0;
      }

      this(var1, var2);
   }

   public User() {
      this((String)null, 0, 3, (DefaultConstructorMarker)null);
   }

   @NotNull
   public final String component1() {
      return this.name;
   }

   public final int component2() {
      return this.age;
   }

   @NotNull
   public final User copy(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      return new User(name, age);
   }

   // $FF: synthetic method
   // $FF: bridge method
   @NotNull
   public static User copy$default(User var0, String var1, int var2, int var3, Object var4) {
      if ((var3 & 1) != 0) {
         var1 = var0.name;
      }

      if ((var3 & 2) != 0) {
         var2 = var0.age;
      }

      return var0.copy(var1, var2);
   }

   public String toString() {
      return "User(name=" + this.name + ", age=" + this.age + ")";
   }

   public int hashCode() {
      return (this.name != null ? this.name.hashCode() : 0) * 31 + this.age;
   }

   public boolean equals(Object var1) {
      if (this != var1) {
         if (var1 instanceof User) {
            User var2 = (User)var1;
            if (Intrinsics.areEqual(this.name, var2.name) && this.age == var2.age) {
               return true;
            }
         }

         return false;
      } else {
         return true;
      }
   }
}
  • 49번째, 53번째 줄 componentN을 보면 단순히 클래스의 데이터를 반환하는 함수이다.
  • 58번째 줄 원래의 객체에 조금만 데이터를 변형시키고 싶을 때 copy를 사용해서 복사할 수 있다. 
  • 78번째 줄 toString은 아까의 main에서 단순히 호출 시켰을 때와 결과가 같이 나온다. 이것을 보고 객체를 출력하면 toString이 생략되어 나온 다는 것을 알 수 있다. 
  • 82번째 줄 hashCode 함수로 각 데이터들의 hash 값을 구할 수 있다. 
  • 86번째 줄 equals는 주소 값의 비교가 아닌 값이 똑같은지 비교한다. 

toString


fun main(args: Array<String>) {

var exam = User()

var exam1 = User("후니쓰") var exam2 = User(age = 22) var exam3 = User("후니쓰", 22) var test = Use("후니쓰", 24) println("toString 사용 "+exam3.toString()) println("toString 사용X"+exam3) }



copy


package DataClass


data class User(var name:String = "", var age:Int = 0 )
class Use(var name:String, var age:Int)

fun main(args: Array) {
    var exam3 = User("후니쓰", 22)
    var copyExam3 = exam3.copy(age = 24)
    println("copy 사용X "+exam3)
    println("copy 사용 "+copyExam3)
}



그리고 편리하게 각각의 데이터를 쉽게 구분시킬 수 도 있다.

package DataClass

data class User(var name:String = "", var age:Int = 0 )
class Use(var name:String, var age:Int)

fun main(args: Array) {
    var exam3 = User("후니쓰", 22)
    var (name, age) = exam3
    println("이름은 $name 나이는 $age")
}


standard data Class


코틀린에서는 우리와 같이 dataClass를 직접만들 수 도 있지만 직접 제공해주는 Pair와 Triple이라는 클래스가 있다. 이러한 클래스를 쓰면 간편하겠지만 각각의 클래스 이름이나 변수들이 의미가 있으면 코드를 볼때 훨씬 알아보기 쉽기 때문에 정말 간단한 프로그램이 아닌 이상 위와 같은 두개는 안쓰도록 한다. 


fun main(args: Array) {
    var exam3 = User("후니쓰", 22)
    var pair = Pair("hey hey you go girl","데레데레데레데레뎃뎃")
    println(exam3)
    println(pair)
}


위의 결과와 같이 pair를 써주면 각각의 인자가 무슨 의미를 갖고 있는지 알기 힘들기 때문에 우리는 직접 만들어서 사용하자 그리고 3개의 인자를 저장하고 싶으면 Triple을 사용하면 된다. 


'kotlin-이론' 카테고리의 다른 글

[kotlin]Object Expression  (0) 2018.06.18
[kotlin] Nested Class And Inner Class  (0) 2018.06.18
[kotlin] kotlin 강의 properties2  (0) 2018.06.17
[kotlin] kotlin 강의 properties1  (0) 2018.06.16
[kotlin] Class 상속  (0) 2018.06.15