[Kotlin] OOP 1

sundays·2022년 9월 3일
0

kotlin

목록 보기
6/19

프로그램의 구조를 객체 간 상호작용으로 표현하는 프로그래밍 방식

객체

물리적인 메모리 영역에서 실행되고 있는 클래스의 실체

Polymorphism

  • 다형성
  • 같은 이름을 사용하지만 구현 내용이 다르거나 매개변수가 달라서 하나의 이름으로 다양한 기능을 수행할 수 있는 개념

Static Polymorphism

  • 컴파일 타임에 결정되는 다형성
  • 메서드 오버로딩

Dynamic Polymorphism

  • 런타임 다형성
  • 동적 오버라이딩

Overriding

  • 기능을 완전히 다르게 바꾸어 재 설계
  • 누르다 > 행위 > push()
  • push()는 확인 또는 취소 용도로 다르게 수행될 수 있음

예시

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));
}

Overwriting

  • 상위 클래스의 메서드 내용을 완전히 새로 만들어 다른 기능을 하도록 정의
  • 오버라이딩 하기 위해서는 부모 클래스는 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() { } // 하위 클래스에서 재정의 금지
}

super

  • 바깥 클래스 호출할때 엣(@) 기호 이용
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()
    }
}

캡슐화

가시성 지시자

  • private: 이 지시자가 붙은 요소는 외부에서 접근할 수 없다.
  • public: 이 요소는 어디서든 접근이 가능하다. (기본값)
  • protected: 외부에서 접근할 수 없으나 하위 상속 요소에서는 가능하다.
  • internal: 같은 정의의 모듈 내부에서는 접근이 가능하다.

프로퍼티 접근

  • 코틀린의 프로퍼티는 변수 선언과 기본적인 접근 메서드를 모두 가지고 있음
  • 따로 접근 메서드를 만들지 않아도 내부적으로 생성하게 됨
  • 직접 정의해서 사용하는 경우
    • value: 세터의 매개변수로 외부로부터 값을 가져옴
    • field: 프로퍼티를 참조하는 변수 보조 필드(backing field)
      • 만일 게터와 세터 안에서 field 대신에 get() = age와 같이 사용하면 프로퍼티의 get()이 다시 호출되는 것과 같으므로 무한 재귀 호출에 빠져 스택 오버플로 오류가 발생할 수 있습니다.
var 프로퍼티이름[: 프로퍼티자료형] [= 프로퍼티 초기화]
    [get() { 게터 본문 } ]
    [set(value) {세터 본문}]
val 프로퍼티이름[: 프로퍼티자료형] [= 프로퍼티 초기화]
    [get() { 게터 본문 } ]
profile
develop life

0개의 댓글