TIL 230718

장재용·2023년 7월 17일

TIL

목록 보기
2/32

코틀린 반복문 (for)

for(요소 in 리스트)
for(인덱스 in 시작값 until 마지막값)
for(인덱스 in 시작값 ... 마지막값)

0 until 9 : 0 <= x < 9
0 .. 9 : 0 <= x <= 9

코틀린 반복문 (while)

while(조건식){
로직
증감식
}

코틀린 반복문 (break, continue)

  • break
    가장 가까운 반복문에서 탈출하고 다음 블록으로 간다.

  • continue
    continue 이후의 코드는 실행하지 않고 반복문의 다음 인덱스가 실행된다.

arrayOf() : 배열을 만들어주는 함수
var infos = arrayOf("꿩","닭","참색","오목눈이","공작새") 로 배열을 만들 수 있다.

메소드

fun 메소드이름( 자료형 : 변수명, ... ) : 반환되는 값의 자료형 {
   ...
}

만약 함수에 반환되는게 없다면 반환자료형을 생략하거나 Unit을 쓰면 된다.

클래스

코틀린은 모든것이 클래스형태이므로 객체화할 수 있다.
클래스는 정보(프로퍼티)와 행위(메소드)를 가진다.
OOP의 5대 키워드 : 상속, 캡슐화, 추상화, 클래스, 다형성

class 클래스이름 {
	    정보1
		정보2

		행위1
		행위2
}
  • 특별한 클래스

1. 데이터 클래스

프로퍼티만 가진 클래스다.
data class 키워드를 사용해 만듬.
아래와 같은 유용한 메소드를 자동으로 만들어줌.
hashCode(): 객체를 구분하기 위한 고유값을 리턴해줘요
eauals(): 동일한 객체인지 비교해서 true 또는 false를 리턴해줘요
copy(): 현재 객체의 모든 정보를 복사해서 새로운 객체를 리턴해줘요
toString(): 현재 객체의 모든 정보(프로퍼티)를 예쁘게 출력해줘요
getXXX()/setXXX(매개변수): 변수의 값을 리턴하거나 설정해줘요

2. 실드 클래스(Sealed Class)

클래스 상속과 관련된 개념임
상속받을 자식클래스를 미리 정의 가능
무분별한 상속을 방지할 수 있다.
컴파일 시점에 생성할 수 있는 자식을 알 수 있기에 효율적인 다형성 구현 가능하다.

sealed class 부모클래스 {
	class 자식클래스1 : 부모클래스생성자
	class 자식클래스2 : 부모클래스생성자
}

3. 오브젝트 클래스

자바의 static 대신 사용하는 키워드다.
클래스를 만들었다고 해서 프로그램 메모리에 바로 올라가는게 아닌데 object를 클래스 앞에 붙이면 바로 메모리에 적재되어 객체를 만들지 않아도 바로 사용가능하다.

생성자

  1. 기본 생성자

  2. 명시적 생성자 ( 주 생성자와 부 생성자로 구성)

  • 주 생성자
    init이 있다.
    클래스 옆에 매개변수가 있다.
    한개의 생성자밖에 없다.
    init안의 문장이 무조건 실행된다.
init {
        println("매개변수없는 생성자 실행 완료!")
        // 항상 클래스가 생성될때 이 코드가 실행됨.
    }
  • 부 생성자
    Constructor가 있다.
    클래스 옆에 매개변수가 없다.
    여러개의 매개변수를 가진 생성자를 만들 수 있다.
constructor(_name:String, _hairColor:String, _height:Double) {
        println("${_name}을 생성자로 넘겼어요")
        println("${_hairColor}를 생성자로 넘겼어요")
        println("${_height}를 생성자로 넘겼어요")
    }

객체와 인스턴스

  • 객체 (object)
    클래스 타입으로 선언된 것들
  • 인스턴스 (instance)
    객체가 메모리공간을 차지하고 주소를 할당받은 것

상속

코틀린에서는 생략된 final키워드로 상속을 막아두고 있다.
그래서 상속을 활성화하기 위해선 클래스 앞에 open 키워드를 활용해 상속 관계를 만들 수 있다.
상속을 이용하면 부모클래스만 변경하는것으로 코드의 재사용성을 높일 수 있다.
부모 클래스에서 생성자를 받는다면 자식 클래스에서도 파라메터로 생성자를 넣어야한다.

	open class Bird{
    	fun fly(){
        	println("새~가 날아~간~다~")
            }
          }
     }
     
     class Chicken : Bird() { }
     class Duck : Bird() { }
     
     fun main(){
     	var bird = Bird()
        var chicken = Chicken()
        var duck = Duck()
        
        chicken.fly()
        duck.fly()
      }

오버라이딩(Overriding)

부모 클래스의 프로퍼티(정보)나 메소드(행위)를 재설계할 수 있다.
주로 부모 클래스의 메소드를 재설계한다.

  • 재설계할꺼면 상속을 대체 왜 사용하는걸까?
    OOP관점에서 일관성을 높여 유지보수를 쉽게하기 위해.

클래스 앞에 open을 붙이면 다른 클래스에서 상속이 가능하다.
메소드 앞에 open을 붙이면 자식 클래스에서 오버라이딩 가능하다.

오버라이딩 단축어 : Ctrl + O

오버로딩(Overloading)

동일한 이름의 메소드여러개 만들수 있는것을 말한다.
다 되는건 아니고 매개변수의 갯수, 자료형을 달리 하면 가능하다.
반환형의 차이는 해당사항이 없다.

정수를 더하는 add라는 메소드를 만들었다.
그런데 실수도 더하고 싶은데 이미 add가 있어서 만들수없다. 그렇다고 addInt(), addDouble()이렇게 만들자니 영 맘에 안든다. 이럴때 오버로딩을 이용해 매개변수의 자료형만 달리해서 같은 이름 add()로 만들 수 있다.

인터페이스(Interface)

인터페이스는 추상메소드(로직을 구현하지 않은 메소드)로 구성하는게 근본이긴하나 최근엔 로직을 구현하는것도 가능하다곤 한다.

코틀린에서는 부모클래스는 오직 한개라 모두 상속으로 처리할 수 없다. 따라서 근본적인 공통점은 상속받고, 추가적인 기능은 인터페이스로 추가하면 된다.

interface 인터페이스이름 {
	fun 메소드이름()
}
class Duck(name: String) : Bird(name), WaterBirdBehavior {
    override fun swim() {
        println("${name}가 수영해요~")
    }
}

접근제한자

  • public: 명시하지 않으면 기본적으로 public 입니다 (어디서나 접근할 수 있어요)
  • private: 동일한 클래스 내부에서만 접근할 수 있습니다
  • internal: 같은 모듈 내부에서만 접근할 수 있습니다
  • protected: 기본적으로 private이지만 상속을 받은경우에 타 모듈에서 접근할 수 있습니다.

예외처리

1. try~catch문

try{
	예외가 발생할 것 같은 코드
    } catch(예외 종류){
    	예외발생 시 실행할 코드
        }

예시) 숫자를 입력하지 않으면 숫자가 입력될때까지 무한히 반복되는 코드.

while(true) {
        try {
            var num1 = readLine()!!.toInt()
            println("내가 입력한 숫자는 ${num1}입니다")
            break
        } catch(e:java.lang.NumberFormatException) {
            println("숫자를 입력하세요")
        }
    }

2. try~catch-finally문

try{
	예외가 발생할 것 같은 코드
    } catch(예외 종류){
    	예외발생 시 실행할 코드
        }
      finally{
        예외가 발생 안해도, 발생해도 항상 실행하는 코드.
        }

예시) 위 예시와 같으나 예외 발생 유무와 관계없이 finally 문장이 실행된다.

		while(true) {
        try {
            var num1 = readLine()!!.toInt()
            println("내가 입력한 숫자는 ${num1}입니다")
            break
        } catch(e:java.lang.NumberFormatException) {
            println("숫자를 입력하세요")
        } finally {
            println("키보드와의 연결은 정상적입니다")
        }
    }

지연초기화 (늦은 초기화)

안정성을 위해 코틀린에선 변수를 선언하고 초기화를 해줘야하나 나중에 초기화를 해줘도 된다. 그것을 지연초기화(늦은 초기화)
라고 한다.
-> 지연초기화를 사용하는 궁극적인 이유는 저사양 환경에서 사용할 때 값을 대입해 메모리를 효율적으로 사용하기 위함이다.

  • 변수
    lateinit 키워드 사용

var agent:String = " "
lateinit var agent:String

  • 상수
    lazy 키워드 사용
    상수를 사용하는 시점에 값을 대입하고 초기화 됨
    val address:String by lazy

  • isInitialized
    값이 초기화되었는지 확인할 수 있다.
    값이 아니라 참조형태이기에 this:: 또는 ::이 붙는다.

if(this::name.isInitialized)

널 세이프티

Null 예외는 프로그램이 실행도중 꺼질 수 있는 치명적인 오류
그래서 코틀린은 Null 예외로부터 벗어나기 위해 자료형에 Null을 가질수있는지 여부를 명시할 수 있다.
코틀린은 ?, !!, ?., ?:를 사용해 Null 예외로부터 벗어날려 한다.
강제로 Null이 아니라는 !!는 최대한 사용을 지양하자.

? : null이 저장될수 도 있다.

ex) var address:String? = null

!! : null이 아님을 강제로 보장 (권장X)
?. : null이 아닐때만 참조해줌, null일 때는 null이란 문자열이 그대로 출력( safe-calls 연산자, 안전 호출 연산자)
?: : ?. 에서 null일 경우 null이 그대로 출력된다. 다만 null이 출력되는게 보기 싫어 null대신 다른 문자열로 출력하고 싶을때 사용한다. (엘비스 연산자)

배열

내장 메소드 arrayOf() 사용

var arr = arrayOf("1","5","8")

    println(Arrays.toString(arr))
    
    //[1, 5, 8]

Arrays.toString(배열명) 으로 배열 안에 든 값 출력

withIndex()와 함께 쓰면 배열의 인덱스와 값을 동시에 출력 가능하다.

fun main() {
    var kors = arrayOf(90, 94, 96)
    for((idx, kor) in kors.withIndex()) {
        println("${idx}번째 국어 점수는 ${kor}입니다")
    }
}

0번째 점수는 90입니다.
1번째 점수는 94입니다.
2번째 점수는 96입니다.
profile
enjoy_error_message!

1개의 댓글

comment-user-thumbnail
2023년 7월 18일

소중한 정보 감사드립니다!

답글 달기