[Kotlin] Kotlin OOP (1) - Class, Interface

yuseon Lim·2021년 4월 19일
0

Kotlin

목록 보기
6/11
post-thumbnail
post-custom-banner

Class

Class 생성

  • 코틀린에서 클래스는 class 키워드로 정의
  • 클래스는 클래스 이름, header(type parameters, constructor,,), body로 이루어지는데, body가 없을 경우 bracket 생략 가능
class Invoice {/*...*/}
class Empty
  • 자바와는 다르게
    • 코틀린은 기본적으로 public class (내부 필드는 기본적으로 private으로 생성)
    • 객체 생성시에 new 키워드 쓰지 않음
    • 속성 접근 메소드 getter/setter 을 자동으로 만들어 줌
    • 커스텀 접근 메소드 만들 수도 있음 (get(){..} , set(){..})
  • class Person을 정의할 때, Java와 Kotlin의 차이. 둘은 같은 클래스를 생성한 것이다.
// JAVA
class Person {
    private String name;

    // 생성자
    public Person(String name) {
        this.name = name;
    }

    // getter
    public String getName() {
        return this.name
    }
    
    // setter
    public void setName(String name) {
        this.name = name;
    }
}
// KOTLIN
class Person (var name: String)

보다시피, java는 이 간단한 클래스를 구현하는 데에 18줄이나 코드를 작성해야했지만 코틀린은 한줄로 가능하다. 클래스가 잘 생성되었는지 확인해보면?

val person = Person("홍길동")
println("이름: ${person.name}") // 이름: 홍길동

person.name = "김철수"
println("이름: ${person.name}") // 이름: 김철수

getter / setter 구현을 하지 않아도 내부적으로 자동 생성해주는것을 확인 할 수 있다.

생성자는 두가지 방법으로 가능한데,

Constructor

Primary constructors

  • primary constructor는 클레스 헤더에 위치
class Person constructor(name: String) { /*...*/ }
  • primary constructor가 어노테이션이나 접근 제한자를 갖고 있지 않다면 constructor 키워드 생략
class Person(name: String) { /*...*/ }
  • 실행문을 함께 포함 할 수 없기때문에 초기화하는 코드를 넣고싶을경우 init 블럭 사용
class Person (var name: String) {
    init {
        println("init과 함께 사용")
    }
}

val person = Person("홍길동")
println("이름: ${person.name}") 

// init과 함께 사용
// 이름: 홍길동

Secondary constructors

  • secondary constructor로 생성자 만들 수 있음
  • 키워드 constructor 사용, 생략 불가
class Person {
    var children: MutableList<Person> = mutableListOf<Person>();
    constructor(parent: Person) {
        parent.children.add(this)
    }
}
  • primary constructor를 가지고 있을 경우 secondary constructor는 this() 생성자를 이용해 직간접적으로 primary constructor에 위임
class Person(val name: String) {
    var age: Int = 26
    constructor(name: String, age: Int) : this(name) {
        this.age = age
    }
}

🙋‍♀️primary constructor, secondary constructor, init블럭이 모두 있을때

  • init 블럭은 primary constructor의 일부
  • primary constructor는 secondary constructor의 첫 번째 실행문으로 실행
  • 따라서 init블럭의 코드는 항상 secondary constructor의 body보다 먼저 실행

중첩(Nested) 클래스

  • 코틀린에서 중첩 클래스는 자바에서 정적(static) 중첩 클래스와 같음
  • 자바에서처러 내부 클래스를 만들려면 중첩 클래스 앞에 inner키워드 사용
  • 그렇기때문에 중첩클래스와 내부클래스는 다르다.
// nested class 중첩 클래스
class Outer {
    private val bar: Int = 1
    class Nested {
        fun foo() = 2
    }
}

val demo = Outer.Nested().foo() // == 2

중첩 클래스에서는 외부 클래스를 참조하지 않기때문에 Outer.Nested().foo()의 값이 2가 된다.

// inner class 내부 클래스
class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}

val demo = Outer().Inner().foo() // == 1

내부클래스에서는 외부 클래스를 항상 참조하기 때문에 Outer().Inner().foo()의 값이 1이된다.

봉인(sealed) 클래스

  • 특정 클래스를 상속하는 클래스를 제한 할 수 있다.
  • sealed 키워드 사용
sealed class Person {/*...*/}

상속, 오버라이드 금지

  • class 는 기본적으로 상속, 메소드 오버라이드 금지
    • 상속이나 오버라이드가 가능하게 하려면 open키워드 사용
    • open class Test()
  • 메소드 오버라이드 접근 변경
    • final: 오버라이드 금지, 기본적으로 fianl임
    • open: 오버라이드 가능, 명시적으로 open을 붙여야 오버라이드 가능
    • abstract: 반드시 오버라이드 해야 함, abstract class 내에서만 사용 가능
    • override: 오버라이드 가능

Data Class

  • class 정의 앞에 data 키워드 추가
data class User(val name: String, val age: Int)
  • data 클래스는 컴파일러가 자동적으로 primary constructor에 정의해주는 것들이 있음.
    • equals() , hashCode()
    • toString() , ""User(name = John, age = 42)
    • componentN()
    • copy()

Interface

  • 자바의 인터페이스와 비슷
  • 인터페이스 구현 클래스의 메소드 구현에서 override를 반드시 써야 함
    • 클래스를 상속 받을 때에도, 메소드 오버라이드 할 때 override를 씀(자바의 @override)
interface Named {
    val name: String
}

interface Person : Named {
    val firstName: String
    val lastName: String

    override val name: String get() = "$firstName $lastName"
}

data class Employee(
    // implementing 'name' is not required
    override val firstName: String,
    override val lastName: String,
    val position: Position
) : Person

참고자료

profile
🔥https://devyuseon.github.io/ 로 이사중 입니다!!!!!🔥
post-custom-banner

0개의 댓글