λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

Android & Kotlin

[λ‚΄λ³΄λ‚΄λ²ˆ] Interfaces | Kotlin

Kotlin을 κ³΅λΆ€ν•˜λ©΄μ„œ 상속에 λŒ€ν•œ 뢀뢄을 κ³΅λΆ€ν•˜κ³ μž 곡식 λ¬Έμ„œλ₯Ό 직접 λ²ˆμ—­ν–ˆλ‹€.
ν•΄λ‹Ή λ¬Έμ„œλŠ” 2022λ…„ 3μ›” 3일자 곡식 λ¬Έμ„œμ΄λ‹€.
쀑간쀑간 πŸ‘€ ν‘œμ‹œκ°€ μžˆλŠ” λ¬Έμž₯μ΄λ‚˜ μ†Œμ œλͺ©μ€ λ²ˆμ—­μ΄ λΆ€μ •ν™•ν•  수 있으며 κ΅¬κΈ€μ΄λ‚˜ 파파고 λ²ˆμ—­κΈ°μ˜ 도움을 λ°›μ•˜λ‹€. 

Kotlin κ³΅μ‹λ¬Έμ„œ ν™•μΈν•˜κΈ° ➑️

 

Interfaces | Kotlin

 

kotlinlang.org

 

β€» μ˜μ–΄ μ „κ³΅μžλ„ ν•΄μ™Έ μœ ν•™νŒŒλ„ μ•„λ‹ˆκΈ°μ— λ²ˆμ—­μ—λŠ” μ˜μ—­, μ˜€μ—­, κ΅¬κΈ€ λ²ˆμ—­μ΄ λ¬΄μˆ˜νžˆ λ§Žμ„ 수 있으며, 혼자 κ³΅μ‹λ¬Έμ„œλ₯Ό μ°Έμ‘°ν•΄κ°€λ©° λ²ˆμ—­ν•˜λ‹€ λ³΄λ‹ˆ μ˜€νƒ€λ„ λ§Žμ„ 수 μžˆλ‹€. μ •ν™•ν•œ λ‚΄μš©μ€ κ³΅μ‹λ¬Έμ„œλ₯Ό 직접 μ‚΄νŽ΄λ³΄κ±°λ‚˜ λ‹€λ₯Έ 정보듀을 더 μ°Ύμ•„λ³΄λŠ” 것을 μΆ”μ²œν•œλ‹€.

(ν•˜μ§€λ§Œ λŒ“κΈ€ ν”Όλ“œλ°±λ„ ν™˜μ˜ν•©λ‹ˆλ‹€πŸ˜ƒ )

 

Interfaces in Kotlin can contain declarations of abstract methods, as well as method implementations. What makes them different from abstract classes is that interfaces cannot store a state. They can have properties, but these need to be abstract or provide accessor implementations.

μ½”ν‹€λ¦°μ˜ μΈν„°νŽ˜μ΄μŠ€λŠ” 좔상 λ©”μ„œλ“œ 선언과와 λ©”μ„œλ“œ κ΅¬ν˜„ λͺ¨λ‘ 포함할 수 μžˆλ‹€. 좔상 ν΄λž˜μŠ€μ™€μ˜ 차이점은 μΈν„°νŽ˜μ΄μŠ€λŠ” μƒνƒœλ₯Ό μ €μž₯ν•  수 μ—†λ‹€λŠ” 것이닀. μΈν„°νŽ˜μ΄μŠ€λŠ” 속성을 κ°€μ§ˆ 수 μžˆμ§€λ§Œ μΆ”μƒμ΄κ±°λ‚˜ μ ‘κ·Όμž κ΅¬ν˜„μ΄ μ œκ³΅λ˜μ–΄μ•Όν•œλ‹€. 

An interface is defined using the keyword interface:

μΈν„°νŽ˜μ΄μŠ€λŠ” interface ν‚€μ›Œλ“œλ‘œ μ •μ˜λœλ‹€: 

interface MyInterface {
    fun bar()
    fun foo() {
      // optional body
    }
}
 

Implementing interfaces

A class or object can implement one or more interfaces:

ν΄λž˜μŠ€λ‚˜ κ°μ²΄λŠ” ν•˜λ‚˜ ν˜Ήμ€ κ·Έ μ΄μƒμ˜ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€:

class Child : MyInterface {
    override fun bar() {
        // body
    }
}
 

Properties in interfaces

You can declare properties in interfaces. A property declared in an interface can either be abstract or provide implementations for accessors. Properties declared in interfaces can't have backing fields, and therefore accessors declared in interfaces can't reference them:

μΈν„°νŽ˜μ΄μŠ€μ— 속성을 μ„ μ–Έν•  수 μžˆλ‹€. μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ 속성은 μΆ”μƒμ΄κ±°λ‚˜ μ ‘κ·Όμžλ₯Ό μœ„ν•œ κ΅¬ν˜„μ΄ μ œκ³΅λ˜μ–΄μ•Όν•œλ‹€. μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ 속성듀은 backing ν•„λ“œλ₯Ό κ°€μ§ˆ 수 μ—†κ³  κ·Έλ ‡κΈ° λ•Œλ¬Έμ— μΈν„°νŽ˜μ΄μŠ€μ— μ„ μ–Έλœ μ ‘κ·ΌμžλŠ” μ ‘κ·Όν•  수 μ—†λ‹€. 

interface MyInterface {
    val prop: Int // abstract

    val propertyWithImplementation: String
        get() = "foo"

    fun foo() {
        print(prop)
    }
}

class Child : MyInterface {
    override val prop: Int = 29
}
 

Interfaces Inheritance

An interface can derive from other interfaces, meaning it can both provide implementations for their members and declare new functions and properties. Quite naturally, classes implementing such an interface are only required to define the missing implementations:

μΈν„°νŽ˜μ΄μŠ€λŠ” λ‹€λ₯Έ μΈν„°νŽ˜μ΄μŠ€λ‘œλΆ€ν„° νŒŒμƒλ  수 μžˆλ‹€. 즉, 멀버λ₯Ό μœ„ν•œ κ΅¬ν˜„μ„ μ œκ³΅ν•˜λŠ” 것과 μƒˆλ‘œμš΄ ν•¨μˆ˜μ™€ 속성을 μ„ μ–Έν•˜λŠ” 것 λ‘˜ λ‹€ κ°€λŠ₯ν•œ 것을 μ˜λ―Έν•œλ‹€. λ‹Ήμ—°νžˆ κ·ΈλŸ¬ν•œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό κ΅¬ν˜„ν•œ ν΄λž˜μŠ€λŠ” κ΅¬ν˜„λ˜μ§€ μ•Šμ€ λΆ€λΆ„λ§Œ μ •μ˜ν•˜λŠ” κ²ƒλ§Œ μš”κ΅¬λœλ‹€.  

interface Named {
    val name: String
}

interface Person : Named {
    val firstName: String
    val lastName: String

    override val name: String get() = "$firstName $lastName"
}

data class Employee(
    // implementing 'name' is not required
    override val firstName: String,
    override val lastName: String,
    val position: Position
) : Person
 

Resolving overriding conflicts

When you declare many types in your supertype list, you may inherit more than one implementation of the same method:

μŠˆνΌνƒ€μž… λͺ©λ‘μ—μ„œ λ§Žμ€ νƒ€μž…λ“€μ„ μ„ μ–Έν•  λ•Œ 동일 λ©”μ†Œλ“œμ— λŒ€ν•΄ ν•˜λ‚˜ μ΄μƒμ˜ κ΅¬ν˜„μ„ 상속할지 λͺ¨λ₯Έλ‹€: 

interface A {
    fun foo() { print("A") }
    fun bar()
}

interface B {
    fun foo() { print("B") }
    fun bar() { print("bar") }
}

class C : A {
    override fun bar() { print("bar") }
}

class D : A, B {
    override fun foo() {
        super<A>.foo()
        super<B>.foo()
    }

    override fun bar() {
        super<B>.bar()
    }
}
 

Interfaces A and B both declare functions foo() and bar(). Both of them implement foo(), but only B implements bar() (bar() is not marked as abstract in A, because this is the default for interfaces if the function has no body). Now, if you derive a concrete class C from A, you have to override bar() and provide an implementation.

μΈν„°νŽ˜μ΄μŠ€ A와 B λͺ¨λ‘ ν•¨μˆ˜ foo()와 bar()λ₯Ό μ„ μ–Έν–ˆλ‹€. λͺ¨λ‘ foo()λŠ” κ΅¬ν˜„ν–ˆμ§€λ§Œ B만 bar()λ₯Ό κ΅¬ν˜„ν–ˆλ‹€(bar()λŠ” Aμ—μ„œ abstract으둜 ν‘œμ‹œλ˜μ§€ μ•Šμ•˜λŠ”λ° 이것이 μΈν„°νŽ˜μ΄μŠ€μ—μ„œ ν•¨μˆ˜μ— λ°”λ””κ°€ 없을 λ•Œμ˜ 기본값이기 λ•Œλ¬Έμ΄λ‹€). 이제 Aλ‘œλΆ€ν„° 클래슀 Cλ₯Ό νŒŒμƒν•˜λ €λ©΄ bar()λ₯Ό μ˜€λ²„λΌμ΄λ“œν•˜κ³  κ΅¬ν˜„μ„ μ œκ³΅ν•΄μ•Όν•œλ‹€. 

However, if you derive D from A and B, you need to implement all the methods that you have inherited from multiple interfaces, and you need to specify how exactly D should implement them. This rule applies both to methods for which you've inherited a single implementation (bar()) and to those for which you've inherited multiple implementations (foo()).

그런데 Dλ₯Ό A와 Bλ‘œλΆ€ν„° νŒŒμƒν•˜λ €λ©΄ λ‹€μˆ˜μ˜ μΈν„°νŽ˜μ΄μŠ€μ—μ„œ 상속받은 λͺ¨λ“  λ©”μ„œλ“œλ“€μ„ κ΅¬ν˜„ν•΄μ•Όν•˜κ³  Dκ°€ μ–΄λ–»κ²Œ ꡬ체적으둜 그듀을 κ΅¬ν˜„ν–ˆλŠ”μ§€ λͺ…μ‹œν•΄μ•Όν•œλ‹€. 이 κ·œμΉ™μ€ bar()κ³Ό 같이 단일 κ΅¬ν˜„μ„ μƒμ†ν•œ λ©”μ„œλ“œμ™€ foo()같이 μ—¬λŸ¬ κ΅¬ν˜„μ„ μƒμ†ν•œ λ©”μ„œλ“œ λͺ¨λ‘μ— μ μš©λœλ‹€. 

'Android & Kotlin' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

[λ‚΄λ³΄λ‚΄λ²ˆ] Properties | Kotin  (0) 2022.03.03
[λ‚΄λ³΄λ‚΄λ²ˆ] Classes | Kotlin  (0) 2022.03.03
[λ‚΄λ³΄λ‚΄λ²ˆ] Inheritance | Kotlin  (0) 2022.03.02
Overloading / Overriding  (0) 2022.03.02
Lesson 6: App Architecture (Persistence)  (0) 2022.02.23