본문

170818(금) - Kotlin docs (Classes and Inheritance)

Kotlin docs


Classes and Inheritance


Classes

class Invoice { }


class Empty


ㆍConstructor

- primary constructor는 class header의 일부분


class Person constructor(firstName: String) { }


class Person(firstName: String) { }


- code를 포함할 수 없으므로 다음과같이 initializer blocks를 사용한다.


class Customer(name: String) { init { logger.info("Customer initialized with value ${name}") } }


- 더 간단한 선언


class Person(val firstName: String, val lastName: String, var age: Int) { // ... }


- annotation이나 visibility modifiers가 있으면, constructor keyword를 붙여줘야 한다.


class Customer public @Inject constructor(name: String) { ... }


ㆍSecondary Constructor

- secondary constructor


class Person { constructor(parent: Person) { parent.children.add(this) } }


- delegation (use this)


class Person { constructor(parent: Person) { parent.children.add(this) } }


- non-abstract class가 constructor를 선언하지 않으면, parameter가 없는 primary constructor를 가진다.

- private constructor


class DontCreateMe private constructor () { }


ㆍCreating instances of classes

- class의 instance를 생성하기 위해서 constructor를 regular function처럼 호출


val invoice = Invoice() val customer = Customer("Joe Smith")


- Kotlin은 new를 쓰지 않는다.


ㆍClass Members

- can contain


Inheritance

- All class는 common superclass Any를 가진다.

- Any

ㆍsupertypes이 선언되지 않은 class의 default super class

ㆍjava.lang.Object가 아니다.

ㆍequals(), hachCode(), toString() 등의 멤버가 없다.

Java interoperability


class Example // Implicitly inherits from Any


- explicit supertype


open class Base(p: Int) class Derived(p: Int) : Base(p)


- primary constructor가 없으면 기본유형의 다른 constructor 호출 가능


class MyView : View { constructor(ctx: Context) : super(ctx) constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) }


- open annotation

ㆍjava의 final과 반대.

ㆍ다른 class에서 이 class를 inherit 가능

ㆍdefault로 모든 Kotlin class는 final이다.


- Overriding Methods

ㆍKotlin은 일을 explicit하게 하는것에 집중

ㆍJava와는 다르게 overridable member에 대해서 explicit한 annotations를 요구한다.


open class Base { open fun v() {} fun nv() {} }

class Derived() : Base() { override fun v() {} }


ㆍfinal class (no open annotation) 에서는 open member는 금지된다.


ㆍoverride로 marked 된 member는 자체적으로 open되어 있다.

ㆍ다시 re-overriding을 막으려면 final 사용


open class AnotherDerived() : Base() { final override fun v() {} }


- Overriding properties

ㆍmethod overriding과 유사하다.

ㆍderived class에서 super class의  property를 redeclared 하려면, 선언된 property는 override로 시작해야 하며, compatible type 이여야 한다.


open class Foo { open val x: Int get { ... } } class Bar1 : Foo() { override val x: Int = ... }


ㆍvar 속성으로 val override 가능 (반대는 불가)

ㆍprimary constructor에서 override 사용 가능


interface Foo { val count: Int } class Bar1(override val count: Int) : Foo class Bar2 : Foo { override var count: Int = 0 }


- Calling the super class implementation

ㆍsuper keyword 사용


open class Foo { open fun f() { println("Foo.f()") } open val x: Int get() = 1 } class Bar : Foo() { override fun f() { super.f() println("Bar.f()") } override val x: Int get() = super.x + 1 }


ㆍinner class의 경우, super@Outer 로 accessing 가능


class Bar : Foo() { override fun f() { /* ... */ } override val x: Int get() = 0 inner class Baz { fun g() { super@Bar.f() // Calls Foo's implementation of f() println(super@Bar.x) // Uses Foo's implementation of x's getter } } }


- Overriding Rules

ㆍmany implementations of same members

-> overriding해서 직접 구현해야 한다. (모호성 제거)

-> 구분은 super<Base> 


open class A { open fun f() { print("A") } fun a() { print("a") } } interface B { fun f() { print("B") } // interface members are 'open' by default fun b() { print("b") } } class C() : A(), B { // The compiler requires f() to be overridden: override fun f() { super<A>.f() // call to A.f() super<B>.f() // call to B.f() } }



Abstract Classes

- class나 function에 open annotation을 달 필요가 없다.

- non-abstract class를 abstract class로 override 가능하다.

open class Base { open fun f() {} } abstract class Derived : Base() { override abstract fun f() }



Companion Object

- Java, C# 과는 다르게 class가 static method를 가지지 못한다.

- 대부분의 경우 package-level function을 사용하길 권장한다.

- Factory method를 사용해야 하는 경우, class 내에 object declaration member로 작성 가능.

- class내에 Companion object를 선언하면 Class 이름만 사용하여 static method 호출과 동일하게 member call 가능하다.

공유

댓글