Kotlin/TIL

TIL (03.06)

내손은개발 🐾 2024. 3. 6. 22:29

코드카타


62번,63번 복습

 

알게된 것

distinct : 중복원소 제거
repeat : 어떤 문자열을 주어진 횟수만큼 반복

    println("A".repeat(5)) //AAAAA
    repeat(5){ print("B")} //BBBBB

 

 

 

 

강의


4
abstract class : 그 자체로 인스턴스화 될 수 없는 클래스이다. abstract class를 여러 클래스에서 공통으로 쓰는 프로퍼티와 메서드를 모아놓는 용도로 사용한다.

인스턴스화? 객체를 만드는 작업
init : 초기화 블록을 시작한다. 초기화 블록에는 클래스의 객체가 만들어질때 (인스턴스화 될때) 실행될 초기화 코드가 들어간다.

(클래스) 상속?
-공통적인 요소가 있다면 부모/자식 클래스를 구분해서 상속관계를 만들 수 있다.
-생략된 final 키워드로 기본적으로 상속을 막아두었다.
-무분별한 상속으로 예상치 못한 흐름을 방지하기 위해 막았다.
- open 키워드를 활용해서 상속 관계를 만들 수 있다.

왜 사용하나 ?
-다형성을 구현할 수 있다.
- 클래스의 내용을 변경해야하는 경우 부모 클래스만 변경하는 것으로 공수를 줄일 수 있다.

fun main() {
    var minsoo = Man("1000원")

    minsoo.howMuch()
}


open class Money(money:String){
    var money: String = ""

    init{
        this.money = money
    }
    fun howMuch() {
        println("${money}만큼 있습니다.")
    }
}

class Man(money:String): Money(money){

}

 

 

오버라이딩 ?

부모 클래스의 정보를 재설계하는 것이다.

주로 부모 클래스의 행위(메소드)를 재설계한다.

단축키 = ctrl/command + o(알파벳) 누르면 오버라이딩 할 수 있는 메소드 리스트가 나온다.

 

위에 코드 변경

fun main() {
    var minsoo = Man("1000원",10)

    minsoo.howMuch()
}


open class Money(money:String){
    var money: String = ""

    init{
        this.money = money
    }
    open fun howMuch() {
        println("${money}만큼 있습니다.")
    }
}

class Man(money:String,age:Int): Money(money){
    var age:Int = 0

    init{
        this.age = age
    }

    override fun howMuch() {
//        super.howMuch()
        println("${age}살에 ${money}만큼 있습니다.")
    }
}

open과 override

 

 

오버로딩 ?

매개변수의 개수나 자료형을 다르게하면 동일한 이름으로 메소드를 만들 수 있다.

예를 들어 int와 double을 더하는  add메소드가 필요한 경우 따로 addInt, addDouble처럼만들게 되면 나중에 관리하기가 힘들어진다. 그럴땐 메소드 이름을 같게 하여 자료형만 바꿔서 해주면 해결된다.

fun main() {
    println(Calculator().add(1, 2))
    println(Calculator().add(1, 2, 3))
    println(Calculator().add(1.1, 2.1))
}

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

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

    fun add(n1: Double, n2: Double): Double {
        return n1 + n2
    }
}

 

인터페이스 ?

공통적으로 필요한 기능을 외부에서 추가한다.

코틀린은 반드시 부모 클래스는 한개라서 모두 상속처리할 수 없다. 따라서 근복적인 공통적을 상속받고, 추가적인 기능들은 인터페이스로 추가한다.

 

사용 예시

interface Bank {
    fun saving(save:Int)
}
class Kid(money: Int): Money(money),Bank{
    override fun saving(save: Int) {
        println("지갑에는 ${money}원있고 ${save}만큼 적금 들었습니다.")
    }
fun main() {
    var john = Kid(100)
    john.saving(10000)
} //지갑에는 100원있고 10000만큼 적금 들었습니다.

위에 코드를 추가해서 넣은 것이다

 

전체코드

더보기

fun main() {
var minsoo = Man(1000,10)
var john = Kid(100)

minsoo.howMuch()
john.saving(10000)

}

open class Money(money:Int){
var money: Int = 0

init{
this.money = money
}
open fun howMuch() {
println("${money}만큼 있습니다.")
}
}

class Man(money:Int,age:Int): Money(money){
var age:Int = 0

init{
this.age = age
}

override fun howMuch() {
// super.howMuch()
println("${age}살에 ${money}원만큼 있습니다.")
}
}

class Kid(money: Int): Money(money),Bank{
override fun saving(save: Int) {
println("지갑에는 ${money}원있고 ${save}만큼 적금 들었습니다.")
}

}

 

-----------------------------------------------------

interface Bank {
fun saving(save:Int)
}

 

접근제한자 ?

  • 객체를 이용해서 변수나 메소드를 호출할 수 있는지의 여부
  • 종류
    • public : 명시하지 않으면 기본적으로 public이다.
    • private : 동일한 클래스 내부에서만 접근 가능
    • internal : 같은 모듈 내부에서만 접근 가능
    • protected: 기본적으로 private이지만 상속을 받은경우에 타 모듈에서 접근 가능
  • 사용하는 이유 ?
    • 데이터의 무분별한 접근과 접근하면 안되는 상황을 구분 가능

예외 처리의 활용

fun method1() {
    try {
        //예외가 발생할 가능성이 있는 코드
    }catch (예외종류){
        //예외 시 처리할 코드
    }
}

fun method2() {
	if(num1>0){
    	throw 예외종류
	}
}

fun method1() {
    try {
        //예외가 발생할 가능성이 있는 코드
    }catch (예외종류){
        //예외 시 처리할 코드
    }finally{  //항상 실행됨
        println("예외가 발생했습니다.")
    }
}

 

 

지연초기화 ?

변수나 상수의 값을 나중에 초기화할 수 있다.

초기의 값을 정의하기 난처해서 나중에 대입하기 위한 문법으로 lateinit, lazy를 사용한다.

변수는 lateinit / 상수는 lazy

 

-변수를 사용하기 전에 초기화되어있는지 확인해야 안정성을 높일 수 있다.

그럴때 사용하기 좋은 것은 isInitialized를 활용해서 값이 초기화되었는지 확인할 수 있다.

사용할땐 :: / this::를 붙인다.

class Student {
    lateinit var name: String
    
    fun method(){
        if(this::name.isInitialized){
            println("이름은 ${name}입니다.")
        }
    }
}

 

 

널 세이프티

코틀린의 장점인 Null 안정성을 향상시켜주는 것이다.

Null예외로부터 안전한 설계를 위해 자료형에 Null 여부를 명시할 수 있다.

? -> null 허용

!! -> null이 아님을 강제로 보장

?. ->null이 아닐때만 실행할 수 있다. null일 경우 null로 출력된다.

?: ->null일 때와 null이 아닐때 구분 가능(null일 경우에도 null이 아니라 대체해서 출력 가능)

 

withIndex()
    var array = arrayOf(1,2,3)
    for((idx,arr) in array.withIndex()){
        println("${idx}번의 값은 ${arr}입니다. ")
    }​

 

    var list1 = listOf(1,2,3)
    //수정 가능 리스트
    var list2 = mutableListOf(1,1,3)
    list2.set(1,2)
    //수정 가능 리스트, <자료형> 입력 필수
    var list3 = ArrayList<Int>(3)

 

    //읽기 전용 Map
    var map1 = mapOf("a" to 1, "b" to 2, "c" to 3)
    //수정 가능 Map
    var map2 = mutableMapOf("d" to 4, "e" to 5)
    map2["f"] = 6 //출력 {d=4, e=5, f=6}
    //출력
    for((key,value) in map2){
        println("key=${key}, value=${value}")
    }

 

Set ?

순서가 존재하지 않고 중복없이 데이터를 관리하는 집합 자료형

다른 컬렉션들은 요소를 찾는데에 집중하지만, Set은 요소가 존재하는지에 집중한다.

    //Set 읽기 전용
    var set1 = setOf("abc","def","ghi")

 

합집합 / 교집합 / 차집합 구하기

    var multiple2 = setOf(2,4,6)
    var multiple3 = setOf(3,6,9)
    //합집합
    var unionSet = multiple2.union(multiple3)
    println(unionSet) //[2, 4, 6, 3, 9]
    //교집합
    var intersectSet = multiple2.intersect(multiple3)
    println(intersectSet) //[6]
    //차집합
    var subtractSet = multiple2.subtract(multiple3)
    println(subtractSet) //[2, 4]

 

 

 

게터/세터

속성을 선언하면 게터와 세터가 자동으로 생성된다.(단 val로 선언했을 경우 게터만 생성)

클래스 속성 값을 가져오는 것을 게터

속성의 값을 변경하는 것을 세터

 

 

 

 

 

오늘은 과제진행으로 Android 공부를 하지 못했다.

'Kotlin > TIL' 카테고리의 다른 글

TIL (03.08)  (0) 2024.03.08
TIL (03.07)  (1) 2024.03.07
TIL (03.05)  (0) 2024.03.05
TIL (03.04)  (1) 2024.03.04
TIL (02.29)  (3) 2024.02.29