[앱프정리] 3주차

Jingu_Jeon·2024년 11월 2일

앱프 스터디

목록 보기
4/5

코틀린 클래스 상속

클래스 내부에 클래스를 내포하는 두가지 방법

내부클래스



이 코드는 Kotlin에서 Rect 클래스와 그 내부에 정의된 Point 클래스, InnerPoint 클래스 등을 사용하여 사각형의 좌표와 크기를 설정하고 계산하는 예제를 보여줍니다. 각 코드 블록의 기능을 설명드리겠습니다.

Rect 클래스 정의

class Rect {
    var w = 0
    var h = 0
    var size = 0

    lateinit var point1: Point
    lateinit var point2: Point

Rect 클래스는 사각형을 나타내며, w(너비), h(높이), size(크기) 변수를 가지고 있습니다.
point1과 point2는 사각형의 좌표를 나타내는 Point 타입의 변수로, lateinit 키워드를 통해 나중에 초기화됩니다.

Point 클래스 (중첩 클래스)

class Point(var x: Int, var y: Int) {
    fun move(dx: Int, dy: Int) {
        x += dx
        y += dy
    }
}

Rect 클래스 내부에 중첩된 Point 클래스는 x와 y 좌표를 가지며, 사각형의 각 꼭짓점을 나타냅니다.
move 함수는 dx, dy 값을 받아 x와 y 좌표를 이동시킵니다.

setLocation 함수 (좌표 설정)

fun setLocation(x1: Int, y1: Int, x2: Int, y2: Int) {
    point1 = Point(x1, y1)
    point2 = Point(x2, y2)
    w = Math.abs(x2 - x1)
    h = Math.abs(y2 - y1)
    size = w * h
}

setLocation 함수는 사각형의 두 점을 받아 point1과 point2에 각각 설정하고, w, h, size 값을 계산합니다.
w는 두 점의 x 좌표 차이의 절댓값, h는 y 좌표 차이의 절댓값이며, size는 w * h로 사각형의 면적을 나타냅니다.

함수 오버로딩: setLocation

fun setLocation(p1: Point, p2: Point) {
    point1 = p1
    point2 = p2
    w = Math.abs(p2.x - p1.x)
    h = Math.abs(p2.y - p1.y)
    size = w * h
}

동일한 이름을 가진 setLocation 함수가 오버로딩되어, 두 개의 Point 객체를 인자로 받아 사각형의 크기를 설정할 수도 있습니다.

InnerPoint 클래스 (내부 클래스)

inner class InnerPoint(var x1: Int, var y1: Int, var x2: Int, var y2: Int) {
    init {
        point1 = Point(x1, y1)
        point2 = Point(x2, y2)
        w = Math.abs(x2 - x1)
        h = Math.abs(y2 - y1)
        size = w * h
    }
}

InnerPoint는 Rect 클래스의 내부 클래스이며, 사각형을 정의하는 두 점의 좌표를 받아 초기화합니다.
초기화 블록 init에서 point1과 point2를 설정하고, w, h, size 값을 계산합니다.

main 함수 (예제 실행)

fun main() {
    val p1 = Rect.Point(x = 1, y = 2)
    var p3 = Rect.Point(x = 7, y = 7)

    val r = Rect()
    r.setLocation(x1 = 1, y1 = 2, x2 = 7, y2 = 11)
    println("size = ${r.size}")

    r.setLocation(p1, p3)

    val r2 = Rect()
    r2.InnerPoint(x1 = 2, y1 = 5, x2 = 4, y2 = 13)
    println("size = ${r2.size}")
}

main 함수는 Rect와 Point 객체를 생성하고, 다양한 방법으로 사각형의 크기를 설정하여 size를 출력합니다.
r.setLocation(x1 = 1, y1 = 2, x2 = 7, y2 = 11) 호출로 사각형의 크기를 설정하고 size를 출력합니다.
r.setLocation(p1, p3)를 통해 Point 객체를 이용해 사각형의 크기를 설정합니다.
r2.InnerPoint(x1 = 2, y1 = 5, x2 = 4, y2 = 13)을 통해 내부 클래스 InnerPoint를 사용해 Rect 객체의 크기를 설정하고, size를 출력합니다.

이 코드는 Rect 클래스 내에서 중첩 클래스와 내부 클래스, 함수 오버로딩을 사용하여 다양한 방법으로 사각형의 좌표와 크기를 설정하는 방법을 보여줍니다.


클래스 상속

추상클래스의 상속

이 코드는 Kotlin에서 상속과 메서드 오버라이딩, 속성 오버라이딩을 보여주는 예제입니다. Book 클래스와 이를 상속받는 Workbook 클래스가 있으며, 메서드와 속성을 재정의하여 기능을 확장하는 방법을 설명합니다.

Book 클래스

open class Book(val label: String) {
    open var pageNo: Int = 0

    fun addPage(page: Int) {
        pageNo += page
    }

    open fun writeOnPage(text: String) {
        println("$label : [$pageNo] $text")
    }
}

open class Book : Book 클래스는 open 키워드를 사용하여 상속이 가능하게 만들어졌습니다.
속성
val label: String : 책의 제목을 나타내는 label 속성입니다.
open var pageNo: Int : 페이지 번호를 나타내는 속성으로, 하위 클래스에서 오버라이딩할 수 있도록 open으로 선언되었습니다.
함수
fun addPage(page: Int) : pageNo에 페이지 수를 더하는 메서드입니다.
open fun writeOnPage(text: String) : label과 pageNo, text를 출력하는 함수로, open으로 선언하여 하위 클래스에서 오버라이딩이 가능하게 했습니다.

Workbook 클래스

class Workbook(label: String, private var author: String) : Book(label) {
    override var pageNo: Int
        set(value) {}
        get() = super.pageNo

    override fun writeOnPage(text: String) {
        super.writeOnPage(text)
        println("Author : $author")
    }

    fun changeAuthor(author: String) {
        this.author = author
    }
}

Workbook 클래스는 Book 클래스를 상속받으며, author라는 추가 속성을 가집니다.

속성 오버라이딩

override var pageNo: Int : pageNo 속성을 오버라이딩하여 set과 get 메서드를 정의합니다.
get()은 super.pageNo를 반환하도록 하고, set은 빈 블록으로 정의되어 있어 외부에서 pageNo 값을 직접 변경할 수 없게 제한합니다.

메서드 오버라이딩

override fun writeOnPage(text: String) : writeOnPage 메서드를 오버라이딩하여 super.writeOnPage(text)를 호출하고, author 정보를 추가로 출력합니다.

추가 메서드

fun changeAuthor(author: String) : author 속성의 값을 변경할 수 있는 메서드입니다.

main 함수

fun main() {
    val wbook = Workbook(label = "Diary", author = "Peter")
    wbook.addPage(page = 10)
    wbook.writeOnPage(text = "Hello")
    wbook.pageNo = 20
    wbook.writeOnPage(text = "World")

    val book: Book = wbook
    book.writeOnPage(text = "Kotlin")

    if (book is Workbook) {
        book.changeAuthor(author = "James")
    }
    book.writeOnPage(text = "Java")
}

객체 생성 및 메서드 호출

wbook.addPage(page = 10) : 페이지 수를 10으로 설정합니다.
wbook.writeOnPage(text = "Hello") : 현재 페이지 번호(10)와 텍스트 "Hello"가 출력되고, 저자 정보("Author : Peter")도 함께 출력됩니다.
wbook.pageNo = 20 : pageNo를 20으로 변경합니다.
wbook.writeOnPage(text = "World") : 페이지 번호(20)와 텍스트 "World"가 출력되고, 저자 정보("Author : Peter")도 출력됩니다.

업캐스팅과 다운캐스팅

val book: Book = wbook : Workbook 객체 wbook을 Book 타입으로 업캐스팅합니다.
if (book is Workbook) : book이 Workbook 타입인지 확인한 후, changeAuthor 메서드를 호출하여 저자를 "James"로 변경합니다.
book.writeOnPage(text = "Java") : writeOnPage가 호출되어 페이지 번호와 "Java"가 출력되고, 변경된 저자("Author : James")도 출력됩니다.

출력 예시

프로그램 실행 시 예상 출력은 다음과 같습니다:

Diary : [10] Hello
Author : Peter
Diary : [20] World
Author : Peter
Diary : [20] Kotlin
Author : Peter
Diary : [20] Java
Author : James

이 예제는 Kotlin에서 상속, 속성과 메서드 오버라이딩, 업캐스팅과 다운캐스팅을 사용하는 방법을 잘 보여줍니다. 상위 클래스의 기능을 확장하고, 특정 조건에서 하위 클래스의 고유 메서드를 사용할 수 있는 객체 지향 프로그래밍의 개념을 이해하는 데 도움이 됩니다.

profile
Back-end Developer를 목표로 하고 있는 전진구입니다.

0개의 댓글