package 메인 디렉터리.서브 디렉터리
class 클래스 {
}
프로그래밍을 하기 전 개념 설계를 하는 단계에서는 클래스의 이름과 클래스 안에 있음 직한 기능을 유추해서 메서드 이름으로 먼저 나열한다.
이때 명확한 코드는 설계 단계에서 메서드 블록 안에 직접 코드를 작성하는데, 그렇지 않은 경우에는 구현 단계에서 코드를 작성하도록 메서드의 이름만 작성한다.
이것을 추상화라고 하며 abstract 키워드를 사용해서 명시한다.
abstract class Design {
abstract fun drawText()
abstract fun draw()
fun showWindow() {
//코드
}
}
class Implements: Design() {
fun drawText() {
// 구현 코드
}
fun draw() {
// 구현 코드
}
}
상속받을 자식 클래스의 특징에 따라 코드가 결정될 가능성이 있다면 해당 기능도 모두 abstract 키워드를 추상화한다.
그리고 실제 구현 클래스는 이 추상 클래스를 상속받아서 아직 구현되지 않은 추상화되어 있는 기능을 모두 구현해준다.
abstract class Animal {
fun walk() {
Log.d("abstract", "걷습니다.")
}
abstract fun move()
}
class Bird: Animal() {
override fun move() {
Log.d("abstract", "날아서 이동합니다.")
}
}
Activity도 수많은 클래스를 상속받아 만들어진다.
이 Activity가 상속받는 클래스 중에 최상위에 Context라는 클래스가 있는데, 최상위 클래스인 Context가 바로 abstract로 설계되어 있다.
인터페이스는 추상화와 비교하면 가장 명확하게 이해할 수 있는데 실행 코드 없이 메서드 이름만 가진 추상 클래스라고 생각해도 무방할 것 같다.
즉, 누군가 설계해 놓은 개념 클래스 중에 실행 코드가 한 줄이라도 있으면 추상화, 코드 없이 메서드 이름만 나열되어 있으면 인터페이스다.
인터페이스는 상속 관계의 설계보다는 외부 모듈에서 내가 만든 모듈을 사용할 수 있도록 메서드의 이름을 나열해둔 일종의 명세서로 제공된다.
interface 목록 { // 명세서 역할
fun say()
fun walk()
fun eat()
}
class 내부 모듈 {
fun 처리(목록) {
}
}
class 외부 모듈 { // 내부 모듈 클래스의 목록 중에 있는 것을 요청
fun 처리() {
}
}
코틀린은 프로퍼티도 인터페이스 내부에 정의할 수 있다.
(대부분의 객체지향 언어에서는 지원하지 않는 코틀린만의 특별한 기능)
interface 인터페이스명 {
var 변수: String // abstract 키워드가 생략되어 있다.
fun 메서드1() // abstract 키워드가 생략되어 있다.
fun 메서드2() // abstract 키워드가 생략되어 있다.
}
인터페이스의 프로퍼티와 메서드 앞에는 abstract 키워드가 생략된 형태이다.
인터페이스를 클래스에서 구현할 때는 상속과는 다르게 생성자를 호출하지 않고 인터페이스 이름만 지정해주면 된다.
interface InterfaceKotlin {
var variable: String
fun get()
fun set()
}
class KotlinImpl: InterfaceKotlin { // InterfaceKotlin 뒤에 ()가 없다.
override var variable: String = "init value"
override fun get() {
// 코드 구현
}
override fun set() {
// 코드 구현
}
}
인터페이스를 클래스의 상속 형태가 아닌 소스 코드에서 직접 구현할 때도 있는데, object 키워드를 사용해서 구현해야 한다. 실제로 안드로이드 프로젝트를 시작하면 자주 사용하는 형태다.
var kotlinImpl = object: InterfaceKotlin { // 클래스에 상속하여 사용하는게 아니라 인터페이스를 변수에 직접 담아서 사용해준 모습
override var variable: String = "init"
override fun get() {
// 코드
}
override fun set() {
// 코드
}
}