프로그램의 구조를 객체 간 상호작용으로 표현하는 프로그래밍 방식
물리적인 메모리 영역에서 실행되고 있는 클래스의 실체
fun add(x: Int, y:Int): Int {
// 정수형 2 개의 매개변수를 더한다
}
fun add(x:Double, y:Double):Double {
// 실수 자료형 매개변수를 2개 더한다
}
fun add(x:Int, y:Int, z:Int):Int {
// 정수 자료형 3개의 매개변수를 더한다
}
fun main() {
println(add(3,2))
println(add(3,2,1));
println(add(3,3,1,3));
}
open
키워드, 자식 클래스는 override
키워드를 사용open class Bird {
fun fly() {}
open class sing(){}
}
class Lark {
fun fly() {} // ERROR open 키워드 없이 오버라이딩 불가
override class sing(){} // 구현부를 새롭게 정의 가능
}
open class Lark() : Bird {
final override fun fly() { } // 하위 클래스에서 재정의 금지
}
open class Base {
open val x:Int = 1
open fun f() = println("Base Class f()")
}
class Child : Base() {
override val x: Int = super.x + 1
override fun f() = println("Child Class f()")
inner class Inside {
fun f() = println("Inside Class f()")
fun test() {
f() // 현재 이너 클래스의 f() 호출
Child().f() //바로 바깥 클래스의 f() 호출
super@Child.f() // child의 상위 클래스인 Base 클래스의 f() 호출
println("[Inside] super@Child.x : ${super@Child.x}") // base의 x접근
}
}
}
// 앵클 브라캣을 이용한 이름 중복 해결
open class A {
open fun f() = println("A class f()")
fun a() = println("A class a()")
}
interface B {
fun f() = println("B interface f()") // 인터페이스 기본적으로 open 임
fun b() = println("B interface b()")
}
class C: A(), B { // 콤마를 사용하여 클래스와 인터페이스를 지정
// 컴파일되기 위해서 f()를 오버라이딩
override fun f() {
println("C class f()")
}
fun test() {
f() // 현재 클래스의 f()
b() // 인터페이스의 B의 b()
super<A>.f() // A클래스의 f()
super<B>.f() // B클래스의 f()
}
}
var 프로퍼티이름[: 프로퍼티자료형] [= 프로퍼티 초기화]
[get() { 게터 본문 } ]
[set(value) {세터 본문}]
val 프로퍼티이름[: 프로퍼티자료형] [= 프로퍼티 초기화]
[get() { 게터 본문 } ]