또는

[코틀린의 기본 문법 2]

 

class (클래스)

class Person {  }                       // 빈 클래스 형태

 

class Person {                          // 생성자를 정의한 클래스 (*k1)
   constructor(name: String) {
      println(name)
   }
}

 

희한하게 클래스를 아래 처럼도 정의하는군요...

class Person (var name: String) {  }    // (생성자를 갖는) 빈 클래스 (참고: var 생략 가능)
                                        // 굳이 클래스명 옆에 이런 문법을 만들것 까지야...
                                        // 메소드 오버로드는 없나보군요...

 

class Person (name: String) {
   init {                    // init 블럭은 생성자와 함께 제일 먼저 실행됨 (위 *k1과 동일 결과)
      println(name)
   }
}

 

var person1 = Person("원빈")     // 개체 생성
person1.name = "한효주"           // 프로퍼티 쓰기
println(person1.name)            // 프로퍼티 읽기

 

 

접근 제한자

public  : (생략가능) 전체 공개
private : 현재 파일 내에서만 공개
internal : 같은 모듈 내에서만 공개 (모듈? 예를 들면, 한 프로젝트 내에 스마트폰용 모듈, 시계용 모듈, TV용 모듈,
            태블릿용 모듈 등등 여러 모듈들을 제작하는 경우가 있음. 모듈은 여러 개의 파일 조각으로 이뤄져 있음)
protected : 부모로 부터 상속받은 클래스에서만 공개

 

 

클래스 상속

※ 코틀린에서는 기본적으로 상속을 금지합니다. (추상 클래스 제외)
그러나 꼭 사용하고자 한다면 open 키워드를 사용할 수 있습니다.

 

빈 클래스 상속

open class Animal { }
class Dog : Animal( ) { }     // SHS: 반드시 상위 클래스의 생성자를 호출하는 형식임 

 

생성자를 갖는 클래스의 상속

open class Animal(val name: String) { }
class Dog(name: String) : Animal(name) { }

 

중첩 클래스

안쪽 클래스는 바깥 클래스A와 거의 독립적입니다.

안쪽과 바깥쪽 변수명이 같아도 됩니다. 단지 선언된 위치가 클래스A 안쪽일 뿐입니다.

class A {
    class B {          // 중첩 클래스
    }
}
var bb = A.B( )     // 클래스B의 위치를 명시하고 클래스B를 객체화 할 수 있음.

 

(중첩된) 내부 클래스

안쪽 클래스에 inner 키워드를 붙여주면 바깥 클래스 멤버에 접근할 수 있고,

이 때의 내부 클래스B는 클래스A의 멤버로 소속이 바뀝니다.

class A {
    var a=10
 
    inner class B {       // (중첩된) 내부 클래스 - 멤버가 된 클래스
        fun result( ) {
            a = 20        // 바깥 클래스 멤버에 접근 가능
        }
    }
}
var bb = A( ).B( )      // 클래스B는 클래스A의 멤버이므로 객체화된 바깥 클래스를 통해서만 객체화가 가능

 

 

추상 클래스

미구현 메소드가 포함된 클래스를 의미하죠. 키워드: abstract

클래스명과 미구현 메소드명 앞 모두에 키워드를 작성해야 합니다.

미구현 메소드가 단 한 개라도 포함되어 있다면 추상 클래스 입니다.

추상 클래스는 반드시 상속을 목적으로 제작하는 클래스입니다.

반드시 상속한 후, 미구현 메소드를 구현해야 합니다.

이것은 반드시 지켜야 하는 개발 팀원들 간의 약속입니다.

abstract class A {
    abstract fun func1( ) { }
    fun func2( ) { }
}
class B: A( ) {
    override fun func3( ) {
        println("Hello")
    }
}

 

 

인터페이스

추상 클래스와 거의 같지만, 일단 2가지 큰 차이점이 있습니다.

1. 추상 클래스는 하나만 상속 가능

   인터페이스는 복수 개를 상속 받을 수 있음 ('다중 상속')

2. 추상 클래스 내부에는 추상 메소드만 선언 가능 (abstract 키워드 필수)

   인터페이스 내부에서는 추상 메소드 + 일반 메소드 모두 사용가능 (abstract 키워드 불필요)

 

interface Runable {
    fun run( )                  // { } 코드가 없는 추상 메소드
    fun walk( ) = println("걷는다")   // 일반 메소드 포함 가능
}

  class Human : Runable {
   override fun run( ) { println("달린다") }
}

 

 

※ 상속과 인터페이스를 함께 사용해본 예)

class Animal { ... }
interface Runable { ... }
interface Eatable { ... }
class Dog : Animal( ), Runable( ), Eatable( ) { ... }   // 클래스 상속과 인터페이스 다중 상속

 

 

 

 

(계속...)

 

<<< 이전 글 보기      다음 글 보기 >>>

 

+ Recent posts