Lesson 3: Classes and objects

HanbinΒ·2021λ…„ 8μ›” 4일
0

Teach Android Development

λͺ©λ‘ 보기
3/13
post-thumbnail

πŸ’‘ Teach Android Development

κ΅¬κΈ€μ—μ„œ μ œκ³΅ν•˜λŠ” ꡐ윑자료λ₯Ό μ •λ¦¬ν•˜κΈ° μœ„ν•œ ν¬μŠ€νŠΈμž…λ‹ˆλ‹€.

Android Development Resources for Educators

Classes

  • ν΄λž˜μŠ€λŠ” 객체의 청사진 μž…λ‹ˆλ‹€.
  • ν΄λž˜μŠ€λŠ” 객체 instances μ—μ„œ μž‘λ™ν•˜λŠ” methodsκ°€ μ •μ˜λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.

Define and use a class

클래슀λ₯Ό μ •μ˜ν•˜κ³  객체의 μƒˆλ‘œμš΄ instanceλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

class House {
  val color: String = "white"
  val numberOfWindows: Int = 2
  val isForSale: Boolean = false

  fun updateColor(newColor: String){...}
  ...
}

val myHouse = House()
println(myHouse)

Constructors

μƒμ„±μžκ°€ 클래슀 해더에 μ •μ˜λ  경우 νŒŒλΌλ―Έν„°λ₯Ό 포함할 수 μžˆμŠ΅λ‹ˆλ‹€.

  • νŒŒλΌλ―Έν„° μ—†μŒ
    class A
  • νŒŒλΌλ―Έν„° 쑴재
    - var, val 선언이 μ—†μœΌλ©΄ μƒμ„±μž λ²”μœ„ μ•ˆμ—μ„œλ§Œ μ‚¬μš© κ°€λŠ₯ν•©λ‹ˆλ‹€.
    class B(x: Int)
    - var, val 선언이 있으면 클래슀의 λͺ¨λ“  instancesμ—μ„œ μ ‘κ·Ό κ°€λŠ₯ν•©λ‹ˆλ‹€.

Constructor examples

class A

val aa = A()

class B(x: Int)

val bb = B(12) 
println(bb.x) // compiler error unresolved reference

class C(val y: Int)

val cc = C(42)
println(cc.y) // 42

Default parameters

클래슀 instancesλŠ” 기본값을 κ°€μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • 기본값을 μ‚¬μš©ν•˜μ—¬ ν•„μš”ν•œ μƒμ„±μž 수λ₯Ό μ€„μž…λ‹ˆλ‹€.
  • κΈ°λ³Έ, ν•„μˆ˜ λ§€κ°œλ³€μˆ˜λ₯Ό ν˜Όμš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λŸ¬ μƒμ„±μžκ°€ ν•„μš”ν•˜μ§€ μ•Šμ•„ 더 κ°„κ²°ν•©λ‹ˆλ‹€.
class Box(val length: Int, val width:Int = 20, val height:Int = 40)
val box1 = Box(100, 20, 40)
val box2 = Box(length = 100)
val box3 = Box(length = 100, width = 20, height = 40)

Primary constructor

클래슀 ν•΄λ”μ•ˆμ— κΈ°λ³Έ μƒμ„±μžλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

class Circle(i: Int) {	
   init {
        ... 
   }
}

μœ„μ˜ 방법과 λ™μΌν•œ κΈ°λŠ₯을 ν•©λ‹ˆλ‹€.

class Circle {
    constructor(i: Int) {
        ...
    }
}

Initializer block

  • μ΄ˆκΈ°ν™”κ°€ ν•„μš”ν•œ μ½”λ“œλŠ” init λΈ”λ‘μ—μ„œ μ²˜λ¦¬ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ—¬λŸ¬κ°œμ˜ init 블둝도 ν—ˆμš©λ©λ‹ˆλ‹€.
  • init블둝은 κΈ°λ³Έ μƒμ„±μžμ˜ bodyκ°€ λ©λ‹ˆλ‹€.

Initializer block example

class Square(val side: Int) {
    init {
        println(side * 2)
    }
}

val s = Square(10) // 20

Multiple constructors

  • constructor ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ secondary constructors μ •μ˜ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • Secondary constructorsλŠ” this ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ„œ κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜ κΈ°λ³Έ μƒμ„±μžλ₯Ό ν˜ΈμΆœν•˜λŠ” 또 λ‹€λ₯Έ Secondary constructorsλ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • Secondary constructors의 bodyλŠ” ν•„μˆ˜κ°€ μ•„λ‹™λ‹ˆλ‹€.

Multiple constructors example

class Circle(val radius:Double) {
    constructor(name:String) : this(1.0)
    constructor(diameter:Int) : this(diameter / 2.0) {
        println("in diameter constructor")
    }
    init {
        println("Area: ${Math.PI * radius * radius}")
    }
}
val c = Circle(3)

Properties

  • val, varλ₯Ό μ‚¬μš©ν•˜μ—¬ 클래슀의 Properties을 μ •μ˜ν•©λ‹ˆλ‹€.
  • . 을 μ‚¬μš©ν•˜μ—¬ Properties에 μ ‘κ·Όν•©λ‹ˆλ‹€.
  • var둜 μ„ μ–Έλœ PropertiesλŠ” .둜 μ ‘κ·Όν•˜μ—¬ 값을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Person class with name property

class Person(var name: String)
fun main() {
    val person = Person("Alex")
    println(person.name)                 Access with .<property name>
    person.name = "Joey"                 Set with .<property name>
    println(person.name)	
}

Custom getters and setters

κΈ°λ³Έ get/set μ‚¬μš©μ„ μ›ν•˜μ§€ μ•Šμ„ 경우 μ‚¬μš© ν•©λ‹ˆλ‹€.

var propertyName: DataType = initialValue
        get() = ...
        set(value) { 
           ...
        } 

Custom getter

class Person(val firstName: String, val lastName:String) {
    val fullName:String
        get() {
            return "$firstName $lastName"
        }
}

val person = Person("John", "Doe")
println(person.fullName) // John Doe

Custom setter

var fullName:String = ""
    get() = "$firstName $lastName"
    set(value) {
        val components = value.split(" ")
        firstName = components[0]
        lastName = components[1]
        field = value
    }

person.fullName = "Jane Smith"

Inheritance

  • 단일 λΆ€λͺ¨ 클래슀λ₯Ό 상속할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • 각 ν΄λž˜μŠ€μ—λŠ” superclass라고 ν•˜λŠ” ν•˜λ‚˜μ˜ λΆ€λͺ¨ ν΄λž˜μŠ€κ°€ μžˆμŠ΅λ‹ˆλ‹€.
  • 각 ν•˜μœ„ ν΄λž˜μŠ€λŠ” superclassκ°€ μƒμ†ν•œ ν•­λͺ©μ„ ν¬ν•¨ν•˜κ³  superclass의 λͺ¨λ“  membersλ₯Ό μƒμ†ν•©λ‹ˆλ‹€.
  • ν•˜λ‚˜μ˜ 클래슀만 상속받을 수 μžˆμœΌλ―€λ‘œ, μ›ν•˜λŠ” 만큼 implement ν•  수 μžˆλŠ”interfaceλ₯Ό μ •μ˜ν•  수 μžˆλ‹€.

Interfaces

  • κ΅¬ν˜„ν•œ λͺ¨λ“  ν΄λž˜μŠ€κ°€ μ€€μˆ˜ν•΄μ•Ό ν•˜λŠ” κ·œμ•½μ„ μ œκ³΅ν•©λ‹ˆλ‹€.
  • λ§€μ†Œλ“œλͺ…κ³Ό 속성 이름을 포함할 수 μžˆμŠ΅λ‹ˆλ‹€.
  • λ‹€λ₯Έ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ νŒŒμƒλ  수 μžˆμŠ΅λ‹ˆλ‹€.

Interface example

interface Shape {
    fun computeArea() : Double
}
class Circle(val radius:Double) : Shape {
    override fun computeArea() = Math.PI * radius * radius
}

val c = Circle(3.0)
println(c.computeArea()) // 28.274333882308138

Extending classes

  • κΈ°μ‘΄ 클래슀λ₯Ό ν•΅μ‹¬μœΌλ‘œ μ‚¬μš©ν•˜λŠ” μƒˆλ‘œμš΄ 클래슀λ₯Ό λ§Œλ“­λ‹ˆλ‹€.(subclass)
  • μƒˆλ‘œμš΄ 클래슀λ₯Ό λ§Œλ“€μ§€ μ•Šκ³  ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μΆ”κ°€ν•©λ‹ˆλ‹€.(extension functions)

Creating a new class

  • ν΄λž˜μŠ€λŠ” 기본적으둜 λ‹€λ₯Έ κ³³μ—μ„œμ˜ 상속을 ν—ˆμš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 상속을 ν—ˆμš©ν•  경우 open ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  • Properties, functions은 override ν‚€μ›Œλ“œλ₯Ό 톡해 μž¬μ •μ˜ν•©λ‹ˆλ‹€.
Classes are final by default
class A

class B : A

Error: A is final and cannot be inherited from
Use open keyword
open class C

class D : C()
Overriding
  • μž¬μ •μ˜ν•  수 μžˆλŠ” properties와 methods에 λŒ€ν•΄ open을 μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.(그렇지 μ•Šμ„ 경우 컴파일 였λ₯˜ λ°œμƒ)
  • properties와 methodsλ₯Ό μž¬μ •μ˜ ν• λ•Œ override ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • override둜 ν‘œμ‹œλœ 것은 ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λ  수 μžˆμŠ΅λ‹ˆλ‹€.(기본적으둜 open, ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λ₯Ό 막고 μ‹ΆμœΌλ©΄ final μΆ”κ°€)

Abstract classes

  • ν΄λž˜μŠ€κ°€ abstract둜 ν‘œμ‹œλ˜μ•Ό ν•©λ‹ˆλ‹€.
  • μΈμŠ€ν„΄μŠ€ν™”ν•  수 μ—†μœΌλ©° μ„œλΈŒν΄λž˜μŠ€λ§Œ κ°€λŠ₯ν•©λ‹ˆλ‹€.
  • μΈν„°νŽ˜μ΄μŠ€μ™€ μœ μ‚¬ν•˜μ§€λ§Œ μƒνƒœμ €μž₯ κΈ°λŠ₯이 μΆ”κ°€μ μœΌλ‘œ μžˆμŠ΅λ‹ˆλ‹€.
  • abstract둜 ν‘œμ‹œλœ properties와 methodsλŠ” μž¬μ •μ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.
  • abstract둜 ν‘œμ‹œλ˜μ§€ μ•Šμ€ properties와 methodsλ₯Ό 포함할 수 μžˆλ‹€.
Example abstract classes
abstract class Food {
    abstract val kcal : Int
    abstract val name : String
    fun consume() = println("I'm eating ${name}")
}
class Pizza() : Food() {
    override val kcal = 600
    override val name = "Pizza"
}
fun main() {
    Pizza().consume()    // "I'm eating Pizza"
}

When to use each

  • κ΄‘λ²”μœ„ν•œ ν–‰λ™μ΄λ‚˜ μœ ν˜•μ„ μ •μ˜ν• λ• μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ³ λ €ν•©λ‹ˆλ‹€.
  • λ™μž‘μ΄ ν•΄λ‹Ή μœ ν˜•μ—λ§Œ 해당될땐 클래슀λ₯Ό κ³ λ €ν•©λ‹ˆλ‹€.
  • μ—¬λŸ¬ ν΄λž˜μŠ€μ—μ„œ 상속해야할 경우 λ¦¬νŒ©νŠΈλ§μ„ κ³ λ €ν•˜μ—¬ 일뢀 λ™μž‘μ„ μΈν„°νŽ˜μ΄μŠ€λ‘œ 뢄리할 수
    μžˆλŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€.
  • 일뢀 properties와 methodsλ₯Ό ν•˜μœ„ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜λ˜λ„λ‘ ν•˜κ³  싢을 경우 좔상화 클래슀λ₯Ό κ³ λ €ν•©λ‹ˆλ‹€.
  • ν•˜λ‚˜μ˜ 클래슀만 extendν•  수 μžˆμ§€λ§Œ μ—¬λŸ¬ μΈν„°νŽ˜μ΄μŠ€λ₯Ό implementν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Extension functions

직접 μˆ˜μ •ν•  수 μ—†λŠ” κΈ°μ‘΄ ν΄λž˜μŠ€μ— ν•¨μˆ˜λ₯Ό μΆ”κ°€ν•©λ‹ˆλ‹€.

  • κ΅¬ν˜„μžκ°€ μΆ”κ°€ν•œ κ²ƒμ²˜λŸΌ λ³΄μž…λ‹ˆλ‹€.
  • κΈ°μ‘΄ 클래슀λ₯Ό μ‹€μ œλ‘œ μˆ˜μ •ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • private μΈμŠ€ν„΄μŠ€ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†μŠ΅λ‹ˆλ‹€.

Why use extension functions?

  • openλ˜μ§€ μ•Šμ€ ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ†Œμœ ν•˜μ§€ μ•Šμ€ ν΄λž˜μŠ€μ— κΈ°λŠ₯을 μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • μ†Œμœ ν•œ 클래슀의 헬퍼 λ©”μ†Œλ“œμ—μ„œ 핡심 APIλ₯Ό 뢄리할 수 μžˆμŠ΅λ‹ˆλ‹€.

    note: ν΄λž˜μŠ€μ™€ 같은 νŒŒμΌμ΄λ‚˜ 잘 μ •μ˜λœ ν•¨μˆ˜μ™€ 같이 μ‰½κ²Œ 검색할 수 μžˆλŠ” μœ„μΉ˜μ— ν™•μž₯ν•¨μˆ˜λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

Extension function example

fun Int.isOdd(): Boolean { return this % 2 == 1 }

3.isOdd() // true

Special classes

Data class

  • 데이터λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
  • ν΄λž˜μŠ€μ— data ν‚€μ›Œλ“œλ‘œ ν‘œμ‹œν•©λ‹ˆλ‹€.
  • 각 속성에 λŒ€ν•΄ getter 및 setter(var일 경우)λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.
  • toString(), equals(), hashCode(), copy() λ©”μ„œλ“œ 및 λ‹€μ–‘ν•œ μ—°μ‚°μžλ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.

Data class example

data class Player(val name: String, val score: Int)

val firstPlayer = Player("Lauren", 10)
println(firstPlayer) // Player(name=Lauren, score=10)

Pair and Triple

  • 2κ°œλ‚˜ 3개의 데이터λ₯Ό μ €μž₯ν•˜λŠ” 사전 μ •μ˜λœ 데이터 ν΄λž˜μŠ€μž…λ‹ˆλ‹€.
  • .first, .second, .thirdλ₯Ό μ‚¬μš©ν•˜μ—¬ λ³€μˆ˜μ— μ ‘κ·Όν•©λ‹ˆλ‹€.

Pair and Triple examples

val bookAuthor = Pair("Harry Potter", "J.K. Rowling")
println(bookAuthor) // (Harry Potter, J.K. Rowling)

val bookAuthorYear = Triple("Harry Potter", "J.K. Rowling", 1997)
println(bookAuthorYear) // (Harry Potter, J.K. Rowling, 1997)
println(bookAuthorYear.third) // 1997

Pair to

toλ₯Ό μ‚¬μš©ν•˜λ©΄ κ΄„ν˜Έμ™€ λ§ˆμΉ¨ν‘œλ₯Ό μƒλž΅ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

val bookAuth1 = "Harry Potter".to("J. K. Rowling")
val bookAuth2 = "Harry Potter" to "J. K. Rowling"

Map 및 HashMapκ³Ό 같은 μ»¬λ ‰μ…˜μ—μ„œλ„ μ‚¬μš©λ©λ‹ˆλ‹€.

val map = mapOf(1 to "x", 2 to "y", 3 to "zz")

Enum class

μ§€μ •λœ κ°’ μ§‘ν•©μœΌλ‘œ μ‚¬μš©μž μ •μ˜ 데이터 νƒ€μž…μž…λ‹ˆλ‹€.

  • μΈμŠ€ν„΄μŠ€κ°€ μ—¬λŸ¬ μƒμˆ˜ 값쀑 ν•˜λ‚˜κ°€ λ˜λ„λ‘ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • μƒμˆ˜ 값은 기본적으둜 μ‚¬μš©μžμ—κ²Œ ν‘œμ‹œλ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 클래슀 μ•žμ— enum ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

Enum class example

enum class Color(val r: Int, val g: Int, val b: Int) {
   RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255)
}

println("" + Color.RED.r + " " + Color.RED.g + " " + Color.RED.b) // 255 0 0

Object/singleton

  • 클래슀의 μΈμŠ€ν„΄μŠ€κ°€ ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜κΈΈ 원할 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.
  • 클래슀 ν‚€μ›Œλ“œ λŒ€μ‹  object ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

Object/singleton example

object Calculator {
    fun add(n1: Int, n2: Int): Int {
        return n1 + n2
    }
}

println(Calculator.add(2,4)) // 6

Companion objects

  • 클래슀의 λͺ¨λ“  μΈμŠ€ν„΄μŠ€κ°€ 이곳에 μ„ μ–Έλœ λ³€μˆ˜λ‚˜ ν•¨μˆ˜λ₯Ό ν•˜λ‚˜μ˜ μΈμŠ€ν„΄μŠ€λ‘œ κ³΅μœ ν•©λ‹ˆλ‹€.
  • companion ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
  • ClassName.Property λ˜λŠ” ClassName.Function 을 톡해 μ°Έμ‘°λ©λ‹ˆλ‹€.

Companion object example

class PhysicsSystem {
    companion object WorldConstants {
        val gravity = 9.8
        val unit = "metric"
        fun computeForce(mass: Double, accel: Double): Double {
            return mass * accel
        }
    }
}
println(PhysicsSystem.WorldConstants.gravity) // 9.8
println(PhysicsSystem.WorldConstants.computeForce(10.0, 10.0)) // 100.0

Organizing your code

Single file, multiple entities

  • Kotlin은 파일 κ·œμΉ™λ‹Ή 단일 entitiy(class/interface)λ₯Ό κ°•μ œν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  • 같은 νŒŒμΌμ•ˆμ˜ μ—°κ΄€λœ ꡬ쑰λ₯Ό κ·Έλ£Ήν™”ν•  수 있고, ν•΄μ•Όν•©λ‹ˆλ‹€.
  • 파일의 길이와 지저뢄함을 염두에 두어야 ν•©λ‹ˆλ‹€.

Packages

  • 쑰직을 μœ„ν•œ μˆ˜λ‹¨ 제곡
  • μ‹λ³„μžλŠ” 일반적으둜 μ†Œλ¬Έμž λ‹¨μ–΄λ‘œ λ§ˆμΉ¨ν‘œλ‘œ κ΅¬λΆ„ν•©λ‹ˆλ‹€.
  • packageν‚€μ›Œλ“œ λ‹€μŒμ— μ˜€λŠ” νŒŒμΌμ—μ„œ 주석이 μ—†λŠ” 첫 번째 μ½”λ“œ 쀄에 μ„ μ–Έλ©λ‹ˆλ‹€.
  • org.example.game

Example class hierarchy

Visibility modifiers

  • κ°€μ‹œμ„± μˆ˜μ •μžλ₯Ό μ‚¬μš©ν•˜μ—¬ λ…ΈμΆœ 정보λ₯Ό μ œν•œν•©λ‹ˆλ‹€.
  • public은 μ™ΈλΆ€μ—μ„œ λ³Ό 수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 클래슀의 λ³€μˆ˜λ‚˜ λ©”μ†Œλ“œλ₯Ό ν¬ν•¨ν•˜μ—¬ λͺ¨λ“  것이 기본적으둜 κ³΅κ°œλ©λ‹ˆλ‹€.
  • private은 였직 ν•΄λ‹Ή 클래슀(λ˜λŠ” ν•¨μˆ˜λ‘œ μž‘μ—…ν•˜λŠ” 경우 μ†ŒμŠ€ 파일)μ—μ„œλ§Œ λ³Ό 수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.
  • protectedλŠ” private와 λ™μΌν•˜μ§€λ§Œ, λͺ¨λ“  subclassμ—μ„œ λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

0개의 λŒ“κΈ€