[Kotlin]추상클래스/인터페이스

dada·2021년 8월 27일
0

Kotlin

목록 보기
9/14
post-thumbnail

💬추상클래스

추상클래스/추상메소드 선언

  • 일반적인 규칙은 자바와 같음
  • 추상메소드를 가진 클래스는 추상클래스가 되어야함
  • 인스턴스 메소드에서 추상 메소드 호출 가능(진짜 호출은 추상 메소드가 구현후 발생하는 일이기 때문)
abstract class Player {
    abstract fun play()
    abstract fun stop()
    fun custom() {
        play()
    }
}

추상클래스 구현

  • extends안쓰고 : 사용(상속 시와 같음)
  • 다중상속 당연히 불가능
  • override키워드로 상속받아옴
  • 일부만 구현할땐 class가 여전히 abstract상태
abstract class Player {
    abstract fun play()
    abstract fun stop()
    fun custom() {
        play()
    }
}

abstract class Mp3 : Player() {
    override fun play() {}     //일부만 구현시 abstract클래스됨
}

class Mp4 : Player() {
    override fun play() {}
    override fun stop() {}
}

fun main(args: Array<String>) {
    //Player()  추상클래스 객체 생성 불가
    val myplay: Player = Mp4()  //추상클래스 타입 가능
    myplay.play()
}

💌인터페이스

인터페이스 선언

  • 인터페이스에서 선언할 수 있는것
    • 자바의 상수,static메소드&필드,default메소드에 대응하는
    • companion object{const val}, companion object{},fun 이름(){}
interface inter {
    companion object {
        const val CONST_VAL: String = "자기소개" 
              var filed: String = ""
              val filed2: Int = 5
            fun name() {
            println("static에서 바로 호출")
        }  //자바에서 처럼 static한 메서드도 선언 가능 이때 구현부{}있어야함
    }


    var variable: String       //코틀린은 인터페이스 내부에서 프로퍼티도 정의 가능
    val variable2: String      //코틀린은 인터페이스 내부에서 프로퍼티도 정의 가능
    fun bye()
    fun hi() {                 //default메서드는 구현부를 통해 바로 정의 가능
        println("default메서드는 바로 만들 수 있음")
    }
}

인터페이스 구현

  • interface 를 구현할 때는 [클래스: 인터페이스] 형식으로 구현

    • extends(확장)과 implements(구현) 둘 다 :(콜론) 으로 구현

    • 코틀린은 1개의 상속과 여러개의 인터페이스를 구현
      그리고 override 변경자를 사용해서 자바의 @Override 를 대신

//클래스 상속이나 구현은 : 으로 구분
class Button : Clickable, View { //Clickable은 interface, View 는 상속
    override fun click() { 
        //구현시 override 필수
    }
}

같은 함수 이름을 갖는 interface

  • 디폴트 함수 이름이 같은 이름인 인터페이스를 정의하면 컴파일 에러가 발생
interface Clickable {
    fun click()
    fun showOff() = println()
}

interface Focusable {
    fun click()
    fun showOff() = println()
}

class Button : Clickable, Focusable {  //컴파일 에러
    ...
}
  • 이를 해결하기 위해서는 하위 클래스에서 super() 를 호출
    showOff() 를 override 하고 블럭 안에서 super<...> 를 호출해서 상위 클래스의 메소드를 지정
class Button : Clickable, Focusable {

    //같은 이름의 메소드 override
    override fun showOff() {
        super<Clickable>.showOff()  // 상위 함수 호출시 super<..> 를 사용할 수 있다
        super<Focusable>.showOff()  //둘중 하나만 호출도 가능
    }

    override fun click() { //구현시 override 필수
        L.d("override click()")
    }
}

interface와 프로퍼티


interface Student {
    val nickName: String  //프로퍼티만 있는 경우 구현 필요
    val phone: Int     //인터페이스 프로퍼티에 커스텀get구현시 오버라이딩해서 구현해줄 필요 없음
        get():Int {
            return 10
        }
        
    //val age:Int=22 인터페이스에서는 초기화 불가
}

class StudentInfo : Student {
    override val nickName: String = ""
    //구현하면 get()이 자동생성됨, 프로퍼티만 있었기에 구현 필요
}

class StudentInfo2(val age: Int) : Student {
    override val nickName: String = "" //오버라이딩 하고 나서 get커스터마이징 가능
        get() {
            return field + "저의 나이는 $age 입니다"
        }
}

class StudentInfo3 : Student {
    override val nickName: String = ""  //반드시 구현
    //override val phone:Int=0    //구현 필요없음
}


fun main(args: Array<String>) {
    println(StudentInfo2(20).nickName) //반갑습니다저의 나이는 20 입니다

}

참고
https://zerogdev.blogspot.com/2019/06/kotlininterface.html

profile
'왜?'라는 물음을 해결하며 마지막 개념까지 공부합니다✍

0개의 댓글