• [코틀린/Kotlin] 클래스 공부 내용 정리

    2021. 11. 2.

    by. 하루플스토리

    반응형

    https://www.youtube.com/watch?v=8RIsukgeUVw&list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN&index=2

    저는 위 강의를 보면서 개인적으로 공부한 내용을 정리하였습니다.

     

    클래스

     

    클래스는 고유의 특징값을 갖는 변수인 속성과 기능을 구현한 함수로 이루어져 있다.

    class Person (var name:String, var birthYear:Int)

     

    함수 없이 속성만으로 구현된 클래스는 위와 같이 이것만으로 구현이 완료될 수 있다.

     

    클래스는 인스턴스를 만드는 틀이라는 점을 이해해야한다.

    인스턴스 : 클래스를 이용해 만들어내는 서로 다른 속성의 객체를 지칭하는 용어

     

    예를 들어 우리가 입력할 데이터로

    1990년생 박보영, 1997년생 전정국, 2004년생 장원영이 있다면 프로그램에서는 같은 Person 클래스로 세 사람의 인스턴스를 만들어 사용하게 됩니다.

    fun main() {
        
        var a = Person("박보영", 1990) //인스턴스 생성
        var b = Person("전정국", 1997)
        var c = Person("장원영", 2004)
        
        //인스턴스를 사용하기 위해서 변수명 뒤에 참조 연산자로 속성명을 사용한다.
       	println("안녕하세요, ${a.birthYear}년생 ${a.name}입니다")
        
    }
    
    class Person (var name:String, var birthYear:Int)

    중괄호{}를 사용한 이유는 println이 문자로 오인할 수 있기 때문에 전체를 감싼 것.

    실행결과 : 안녕하세요, 1990년생 박보영입니다

     

    자주 사용하는 공통적인 기능은 클래스 내에 함수로 넣어주면 됩니다.

    fun main() {
        
        var a = Person("박보영", 1990) //인스턴스 생성
        var b = Person("전정국", 1997)
        var c = Person("장원영", 2004)
        
        a.introduce()
        b.introduce()
        c.introduce()
       	
    }
    
    class Person (var name:String, var birthYear:Int){
        fun introduce(){
            println("안녕하세요, ${birthYear}년생 ${name}입니다")
        }
    }

    실행결과

    안녕하세요, 1990년생 박보영입니다
    안녕하세요, 1997년생 전정국입니다
    안녕하세요, 2004년생 장원영입니다

     

    코틀린은 객체지향 언어를 기반으로 함수형 언어의 장점을 흡수한 실용적인 언어이다.

    따라서 객체지향의 기본 구조가 되는 클래스를 이해하는 것이 무엇보다 중요하다.

     

     

     

    생성자

    생성자 : 새로운 인스턴스를 만들기 위해 호출하는 특수한 함수. 인스턴스의 속성을 초기화하고 인스턴스 생성시 구문을 수행한다.

    class Person (var name:String, var birthYear:Int)

    괄호 부분이 모두 생성자이다. 이것은 클래스의 속성들을 선언함과 동시에 생성자 역시 선언하는 방법이다.

    하지만 인스턴스 생성시 구문을 수행하는 기능은 넣을 수 없었다.  이는 init 함수를 통해 수행할 수 있다.

     

    init 함수 : 파라미터나 반환형이 없는 특수한 함수. 생성자를 통해 인스턴스가 만들어질 때 호출되는 함수.

    fun main() {
        var a = Person("박보영", 1990) //인스턴스 생성
        var b = Person("전정국", 1997)
        var c = Person("장원영", 2004)
    }
    
    class Person (var name:String, var birthYear:Int){
        init{
            println("${birthYear}년생 ${name}님이 생성되었습니다.")
        }
    }

    인스턴스 생성을 통해 init이 호출되어 세 개의 인스턴스에 넣은 속성들이 출력되는 것을 보실 수 있습니다.

     

    실행결과

    1990년생 박보영님이 생성되었습니다.
    1997년생 전정국님이 생성되었습니다.
    2004년생 장원영님이 생성되었습니다.

     

     

    만약 100명의 사람이 가진 이름과 태어난 년도를 인스턴스로 만든다고 가정한다. 그 중 90명 정도가 1997년생이라면 어떨까? 당연히 1997년을 기본값으로 만들 수 있는 방법이 있으면 좋다. 이때는 보조생성자를 사용할 수 있다.

    보조생성자 : 기본 생성자와 다른 형태의 생성자를 제공하여 인스턴스 생성시 편의를 제공하거나 추가적인 구문을 수행하는 기능을 제공함.

     

    중요한 점은 보조생성자를 만들 때는 반드시 기본 생성자를 통해 속성을 초기화해줘야 한다.

    보조 생성자가 기본 생성자를 호출하려고 하면 콜론(:)을 붙인 후 this라는 키워드를 사용하고 기본 생성자가 필요로 하는 파라미터를 괄호안에 넣으면 된다.

     

    fun main() {
        var a = Person("박보영", 1990) //인스턴스 생성
        var b = Person("전정국", 1997)
        var c = Person("장원영", 2004)
        
        var d = Person("이루다")
    }
    
    class Person (var name:String, var birthYear:Int){
        init{
            println("${birthYear}년생 ${name}님이 생성되었습니다.")
        }
        
        constructor(name:String) : this(name, 1997){
            println("보조 생성자가 사용되었습니다.")
        }
    }

    실행결과

    1990년생 박보영님이 생성되었습니다.
    1997년생 전정국님이 생성되었습니다.
    2004년생 장원영님이 생성되었습니다.
    1997년생 이루다님이 생성되었습니다.
    보조 생성자가 사용되었습니다.

     

    이처럼 기본 생성자와 보조 생성자는 클래스를 사용하는 사람에게 다양한 방법으로 인스턴스를 생성하는 법을 제시함으로써 편의를 제공하는 기능이다.

     

     

     

    상속

    실무자 관점에서 볼 때 상속이 필요한 경우는 두 가지가 있다.

     

    1. 이미 존재하는 클래스를 확장하여 새로운 속성이나 함수를 추가한 클래스를 만들어야 할 때

     

    2. 여러개의 클래스를 만들었는데 클래스들의 공통점들을 뽑아 코드관리를 편하게 할 때 사용한다.

     

     

    여기서 속성과 함수를 물려주는 쪽을 수퍼 클래스, 물려 받는 쪽을 서브 클래스라고 부른다.

     

    fun main() {
    
    }
    
    class Animal (var name:String, var age:Int, var type:String){
        fun introduce(){
            println("저는 ${type} ${name}이고, ${age}살 입니다.")
        }
    }

    코틀린은 상속 금지가 기본 값이다.

    현재 Animal 클래스는 'open' 상태가 아니기 때문에 상속을 받을 수 없다.

    'open'은 클래스가 상속될 수 있도록 클래스 선언시 붙여줄 수 있는 키워드이다.

     

    먼저, 상속에 대한 두가지 규칙을 알아야 한다.

    1. 서브 클래스는 수퍼 클래스에 존재하는 속성과 '같은 이름'의 속성을 가질 수 없음.
    2. 서브 클래스가 생성될 때는 반드시 수퍼클래스의 생성자까지 호출되어야 함.

    *var, val 등을 붙이면 속성으로 선언됨.

    그래서 Dog 클래스를 만들 때는 클래스의 자체 속성으로 만들어주는 var을 붙이지 말고 일반 파라미터로 받아 Animal 클래스의 생성자에 직접 넘겨주어야 한다.

     

    클래스의 상속은 클래스 선언 뒤에 콜론을 붙이고 수퍼 클래스의 생성자를 호출할 수 있도록 해주면 된다.

    fun main() {
    	var a = Animal("별이", 5, "개") //a 인스턴스와
        var b = Dog("별이", 5) //b 인스턴스는 같은 속성과 함수의 기능을 갖는다.
        
        a.introduce()
        b.introduce()
    }
    
    open class Animal (var name:String, var age:Int, var type:String){
        fun introduce(){
            println("저는 ${type} ${name}이고, ${age}살 입니다.")
        }
    }
    
    class Dog (name:String, age:Int) : Animal(name, age, "개"){
        
    }

    실행결과

    저는 개 별이이고, 5살 입니다.
    저는 개 별이이고, 5살 입니다.

     

     

    Dog 클래스에 bark 함수를 추가하여 짖는 내용을 출력해본다.

    fun main() {
    	var a = Animal("별이", 5, "개") //a 인스턴스와
        var b = Dog("별이", 5) //b 인스턴스는 같은 속성과 함수의 기능을 갖는다.
        
        a.introduce()
        b.introduce()
        
        b.bark()
    }
    
    open class Animal (var name:String, var age:Int, var type:String){
        fun introduce(){
            println("저는 ${type} ${name}이고, ${age}살 입니다.")
        }
    }
    
    class Dog (name:String, age:Int) : Animal(name, age, "개"){
        fun bark(){
            println("멍멍") //짖는 함수 추가
        }
    }

    실행결과

    저는 개 별이이고, 5살 입니다.
    저는 개 별이이고, 5살 입니다.
    멍멍

     

    클래스의 상속은 클래스를 더 구조적으로 다룰 수 있게 해준다는 장점이 있지만, 지나친 상속 구조는 코드를 더 어렵게 만든다.
    반응형

    댓글