231213 TIL #267 Kotlin #2 함수 / 변수 / 클래스 / 프로퍼티

김춘복·2023년 12월 12일
0

TIL : Today I Learned

목록 보기
267/571

Today I Learned

오늘은 코틀린 인 액션 2장!


코틀린 기초

함수와 변수

"Hello, World!" 선언 비교

  • in Java
public class Main{
  public static void main(String[] args) {
    System.out.println("Hello, World!");
  }
}
  • in Kotlin
  fun main(args: Array<String>){
      println("Hello, World!")
  }
  • 함수를 선언할땐 fun을 쓴다.

  • 함수의 파라미터는 파라미터명: 파라미터타입으로 타입을 지정한다.

  • 함수를 최상위 수준에 정의할 수 있다. 즉, 메서드가 클래스안에 없어도 된다.

  • System.out.println 대신 println으로 쓸 수 있다.

  • 세미콜론(;)을 쓰지 않아도 된다!


함수

fun max(a:Int, b:Int): Int {
    return if (a>b) a else b
}
/*
fun 함수명(파라미터명: 파라미터타입): 반환타입{
	함수내용
}
*/
  • 코틀린 if는 식(expression)이지 문(statement)이 아니다. (자바는 if문)
    식은 값을 return하면서 다른 요소의 하위요소로 계산에 참여할 수 있다.
    문은 자신을 둘러싼 가장 안쪽 블록의 최상위 요소로 존재하며 아무런 값을 만들지 않는다.

  • 식이 본문인 함수
    위의 max같은 방식이 블록이 본문인 함수, 아래 min 방식이 식이 본문인 함수.

fun min(a:Int, b:Int): Int = if(a<b) a else b
// 중괄호를 없에고 return을 제거하면서 등호(=)로 식이 본문인 함수를 표현한다.
  • 식이 본문인 함수는 반환타입조차 생략이 가능하다.
    컴파일러가 반환 타입을 알아서 유추해준다.
fun min(a:Int, b:Int) = if(a<b) a else b
// 컴파일러가 반환값을 유추해줘서 생략이 가능하다.

변수

자바는 타입을 명시하지만, 코틀린은 타입 지정을 생략하는 경우가 흔하다.

    val question = "질문"
    val answer = 4
    val answer2: Int
  • 대부분의 경우 타입은 생략한다. 컴파일러가 초기화 값을 토대로 타입을 지정한다.
    하지만 맨 아래처럼 초기화 하지 않고 변수를 선언하려면 변수명 뒤에 :타입으로 타입을 명시해야한다.

  • 코틀린에선 새롭게 변수나 인스턴스, 예외 등을 생성할 때 new 연산자를 쓰지 않아도 된다!

val

value. 변경 불가능한(immutable) 참조를 저장하는 변수. 자바로 치면 final.
한번 초기화하면 재대입이 불가능.

  • 단, val의 참조 자체는 불변이라도 그 참조한 객체의 상태는 변할 수 있다.
val lang = arrayListOf("Java")
lang.add("Kotlin)
// lang 변수에 할당된 어레이리스트 객체의 참조는 변하지 않지만 해당 리스트의 상태는 변경 가능.

var

variable. 변경 가능한 참조를 저장하는 변수

  • 기본적으로 모든 변수를 val로 선언하고 필요할때만 var을 쓰는 것이 일반적.

  • var으로 변수의 값은 변경할 수 있어도 처음 고정된 타입은 변하지 않는다

var ans = 5000
ans = "오천"
// Int -> String으로 타입이 바뀔 수 없으므로 컴파일 시 에러.

문자열 템플릿

문자열 리터럴의 필요한 곳에 변수를 넣고 변수 앞에 $를 넣는다.

fun main(args: Array<String>){
    val name = if (args.size > 0) args[0] else "Kotlin"
    println("Hello, $name!")
    // 문자열 템플릿 사용
    // 인자를 넘기면 해당 인자를 출력하고, 없으면 kotlin을 출력한다.
}
  • $라는 글자 자체를 넣고싶으면 \를 $ 앞에 써서 이스케이프 시키면 된다.

  • 단, 출력 문자열에 한글을 섞어 쓰면 변수명으로쓸수없다.변수명 으로 쓸 수 없다. `{변수명}처럼중괄호`로 감싸야 한다. 평소에도 이렇게 쓰는 것이 가독성에 좋다.
    println("안녕, ${name}!")

  • 아예 위의 중괄호 안에 식을 넣어서 사용할 수도 있다.

fun main(args: Array<String>){
    println("Hello, ${if (args.size > 0) args[0] else "Kotlin"}!")
}

클래스와 프로퍼티

클래스

  • in Java
public class Person{
	private final String name;
    
    public Person(String name){
    	this.name = name
    }
    
    public String getName() {
    	return name;
    }
  • in Kotlin
class Person(val name: String)
  • 자바의 긴 클래스 선언(변수, 생성자, 게터)을 코틀린은 단 한줄로 줄였다.
    이런 유형의 코드 없이 데이터만 저장하는 클래스를 value object, 값 객체라고 한다.

  • 코틀린은 기본 접근제어자가 public이므로 클래스 선언 시 public을 생략해도 된다.


프로퍼티

  • 자바의 클래스에서 일반적으로 필드의 변수는 private이며 여기에 접근하기 위한 접근자 메서드로 게터와 세터가 존재한다. 필드와 접근자를 한 데 묶어 프로퍼티라 한다.

  • 코틀린은 프로퍼티를 기본으로 제공하며, 이는 자바의 필드와 접근자 메서드를 완전히 대체한다.

  • val로 필드 선언 시 읽기 전용으로 private 필드와 public 게터만 제공한다.
    var로 필드 선언 시 쓰기 가능해지며 private 필드와 public 게터, 세터를 제공한다.

class Person(
	val name: String
    var isMarried: Boolean
)
  • 코틀린에서는 변수에 바로 접근하는 것처럼 사용해도 자동으로 게터와 세터가 사용된다.
fun main(args: String){
	val person = Person("choonB", true)
	println(person.name)
    person.isMarried = false
    println(person.isMarried)
}

커스텀 접근자

프로퍼티의 접근자를 아래처럼 직접 작성할 수 있다.

class Rectangle(val height: Int, val width: Int) {
    val isSquare: Boolean
        get() {				// 프로퍼티 게터 선언
            return height == width
        }
        // get() = height == width 로 표현해도 된다.
}
  • 위처럼 구현시 직사각형 클래스는 정사각형 여부를 프로퍼티에 접근할 때 마다 계산해 알려준다.

패키지와 디렉토리

  • package 상위패키지명.하위패키지명.~~~ 같이 맨 윗줄에 적어 패키지 선언을 할 수 있다.

  • import 패키지명.패키지명.~~ 으로 다른 패키지의 요소를 임포트해와서 쓸 수 있다.

  • 기본적으로는 자바의 패키지와 거의 비슷하다.
    하지만 자바와는 달리 같은 패키지라고해서 같은 디렉토리(폴더)안에 있을 필요는 없다. 다른 폴더여도 패키지 선언만 같이 해줘도 된다.

  • 하지만! 기본적으로 자바처럼 패키지별로 같은 디렉토리에 넣어 구성하는 것이 가독성, 그리고 자바와의 호환성 측면에서 훨씬 좋다. 그냥 자바처럼 쓰는 것을 권유.

profile
Backend Dev / Data Engineer

0개의 댓글