본문 바로가기

Study/Kotlin

Kotlin / 코틀린에서는 모든 것이 객체이다

반응형

1. 객체

객체는 항상 유일하고 특정한 자료형(클래스)를 가진다. 변수, 반환값, 매개변수 등에 할당할 수 있다.

 

javaClass: 자바 클래스를 확인하는 속성

javaClass.kotlin: 코틀린 클래스를 확인하는 속성

 

2. 클래스

객체를 만들기 위해서는 클래스가 필요하다.

먼저 클래스를 정의 -> 이 정의된 클래스 내의 생성자를 호출 -> 객체를 생성

 

클래스 : 클래스를 정의하는 예약어이며 객체를 생성하는 템플릿 도구

생성자 : 클래스 정의 이후 객체를 생성하는 기능. 보통 이름으로 호출하고 생성자를 실행하면 객체 내의 속성들을 초기화 처리한다.

 

3. 객체 표현과 주석

리터럴 (literal) : 하나의 값을 말한다. 보통 숫자, 문자, 문자열이다. 클래스로 만들어 객체로 만든 값은 모두 리터럴이다.

연산자 (operator) : 두 개의  리터럴을 연산할 때 사용하는 도구. 보통 기호로 표시하지만 코틀린 내부에서는 메서드로 처리한다.

표현식(expression) : 여러 리터럴과 연산자가 연결된 수식. 이 수식은 평가되어 하나의 값으로 변환된다.

객체 (object) : 클래스에 의해 생성되는 모든 것

 

실수 : Float(4바이트) Double(8바이트). 기본이 Double 클래스의 객체. Float로 처리할때는 숫자 표현 끝에 F 붙여 사용.

정수 : Int(4바이트) Long(8바이트). 기본이 Int 클래스의 객체. Long클래스 정수는 L을 숫자 표현 끝에 붙인다.

val intVar = 100
val longVar = 100L
val doubleVar = 100.0
val floatVar = 100.0F

println("intVar :: ${intVar.javaClass.kotlin}") // intVar :: int
println("longVar :: ${longVar.javaClass.kotlin}") // longVar :: long
println("doubleVar :: ${doubleVar.javaClass.kotlin}") // doubleVar :: double
println("floatVar :: ${floatVar.javaClass.kotlin}") // floatVar :: float

 

문자, 문자열, 논릿값

val charVar = 'a'
val stringVar = "string"
val boolVar = true

println(charVar.javaClass) // char
println(stringVar.javaClass) // class java.lang.String
println(boolVar.javaClass) // boolean

문자 : 작은따옴표로 나타내는 하나의 문자 / Char 클래스로 만든다. (2바이트)

문자열 : 빈 문자도 포함하는 여러 개의 문자 묶음 String 클래스

 

객체는 메서드로 연산을 수행

숫자 객체는 변경할 수 없는 객체이므로 연산자를 수행하면 새로운 객체를 생성한다.

- 메서드는 클래스 내부에 정의한 함수. 객체가 점연산자로 접근해서 실행할 수 있다.

- 함수는 함수 이름과 호출연산자로 실행한다.

- 연산자는 특정 기호로 표기한다. 연산자를 표기하면 내부에서 해당하는 메서드로 변환해서 처리한다.

println("${100+100} / ${100.plus(100)}")
println("${100-100} / ${100.minus(100)}")
println("${200/100} / ${200.div(100)}")
println("${300%7} / ${300.rem(7)}")
println("${10*20} / ${10.times(20)}")

주석 처리

// 한줄
/* 여러줄 */

/**
    *
    문서화 주석
    *
    */

문자열

문자와 문자열 구분하기 - Char(문자) / String(문자열)

문자 배열 생성 함수 : charArrayOf - 문자를 인자로 받아 배열을 만든다

배열 정보 출력 : contentToString 메서드 - 배열 내부 원소를 출력한다

println('가'.javaClass.kotlin) // class kotlin.Char
println(charArrayOf('가','을').contentToString()) // [가,을]

var str = String(charArrayOf('가','을')) // 문자 배열을 문자열로 변환 -> 문자열 객체 만들어짐
println(str) // 가을

 

원시 문자열 - 일반 문자나 이스케이프 문자들을 그대로 문자로 인식해서 처리한다. => """ """

val s1 = """ 문자열에 \n이스케이프 문자를 넣고 처리"""

println("$s1") // 문자열에 \n이스케이프 문자를 넣고 처리

val s2 = """ 문자열 템플릿 기능은 ${100+200}"""

println("$s2") // 문자열 템플릿 기능은 300

 

형식문자포매팅(String Formatting)

val float = 1234.5
val int = 100
val string = "문자열"
val edec = 10e15
val hex = 0xffff

println("float = %6.2f int = %6d string = %10s".format(float,int,string))
println("edec = %e hex = %x ".format(edc,hex))

// float = 1234.50 int =      100 string =           문자열
// edec = 1.0000000e+16 hex = ffff

%6.2f - 전체 실수는 6자리이고 그중에 소수점 이하는 2자리 라는 것을 나타낸다

 

3. 변수와 상수

프로그램 언어 내에서 특정 값을 보관하는 장소는 변수와 상수이다.

 

상수 - 패키지나 object 예약어를 사용한 곳에서만 정의할 수 있다 //  const val 예약어 사용 // 모두 대문자로 사용

 

- 정의(Declaration) : 변수와 상수를 처음으로 만드는 것

- 참조(Reference) : 만들어진 변수나 상수의 값을 이름으로 조회하는 것

- 할당(Assignment) : 변수나 상수에 초기값을 지정하는 것. 재할당은 변수의 값을 바꾸는 것

val abc123 = 100 // 변수 정의
val _abc123 = 100

object Const { // 상수 정의
	const val CONST = 100
}

println(Const.CONST) // 100

변수 정의

- 변수를 정의할 때는 해당하는 값의 자료형을 지정해야 한다.

- 자료형으로 지정하지 않으면 처음 할당된 값을 보고 자료형을 확정한다. 두번째 할당될 경우 같은 자료형이 아니면 예외를 발생시킨다.

- 변수에 자료형을 지정할 때는 변수명 다음에 콜론(:)을 쓰고 자료형을 지정한다. 그 다음 할당연산자를 사용해 초깃값을 할당한다.

val 불변변수 = "불변변수" // 한 번 초기화되면 재할당 X
var 가변변수 = "가변변수" // 초기화한 후에 항상 재할당 O

val 변수정의 : String = "초기값"

println(변수정의)

 

식별자 이름 작성 방법

- 식별자(identifier) : 변수, 함수, 클래스 등을 이름으로 구별해서 참조하는 모든 것

- 카멜 표기법(camel notation) : 변수 이름의 첫 글자는 소문자, 다음 단어의 첫 글자는 대문자 ==> intVal 

- 파스칼 표기법(Pascal notation) : 단어들의 첫 글자를 대문자. 클래스, object, interface는 첫 글자를 대문자로 쓰고 단어를 이어쓸 때는 시작하는 단어의 첫 글자를 대문자로 쓴다. ==> MainClass

- 팟홀 표기법(pothole)/스네이크 표기법(snake) : 단어와 단어를 언더스코어로 연결해서 쓴다. 보통 상수는 모두 대문자로 쓰지만, 단어를 연결해 쓸 때는 스네이크 표기법도 같이 사용한다. 한 번만 정의하므로 -> 전체 이름을 대문자로 쓴다 SNAKE_NOTATION

 

지역변수 / 전역변수

코틀린은 패키지 단위로 관리하므로 파일에 변수를 정의하면 전역변수로 인식한다.

지역변수는 함수 내부나 코드 블록에 사용하는 문장에 정의한 변수이다.

- 지역변수 : 외부에서 참조할 수 없다. 클로저 환경을 구성할 때만 외부에서 접근할 수 있다.

- 전역변수 : 지역변수 이외에서 정의된 변수. 코틀린에서는 보통 패키지 단위에 정의된 최상위 변수가 전역변수. 동일한 패키지에서 함수 등에서 항상 참조할 수 있다.

val globalLevel = "글로벌 변수" // 최상위 변수는 전역변수

fun funcGlobal(){ 
val localLevel : Int //	함수 내부는 지역변수
    localLevel = 100
    println("지역변수 : $localLevel") // 지역변수 : 100
    println("최상위변수 : $globalLevel") // 최상위변수 : 글로벌 변수
}

* 클로저

클로저(Closure)는 outer scope(상위 함수의 영역)의 변수를 접근할 수 있는 함수를 말한다.

 

속성

코틀린은 변수를 정의하지만, 이 변수에 해당하는 메서드를 가진 속성으로 사용한다.

 

- 코틀린에서는 지역변수를 제외하고 모두 속성이다. -> 실제 변수를 정의하면 게터와 세터, 변수를 참조하는 메서드를 내부적으로 제공. 변수 이름으로 참조하면 메서드가 실행된다.

- 보통 속성은 클래스나 object 내부에 구현된다.

- 객체가 만들어질 때 객체 영역에서 사용하는 상태를 만든다.

// 클래스 정의와 object 정의에 변수 즉 속성을 정의했다.
// 클래스는 객체 즉 인스턴스를 만들므로 이 객체를 가지고 점연산자로 속성을 이름으로 참조한다.

class Klass{
val memberVar : Int = 100 // 클래스 속성
}

object Obj { 
val objVal  = 100 // 객체 속성
}

val k = Klass() // 객체 인스턴스 생성 후 사용
println(k.memberVar) // 100
println(Obj.objval) // 객체 이름으로 직접 접근 -> 100

 

4. 계산연산자

연산자

표현식 메서드 이름 내부적 실행 결과
100+100 plus 100.plus(100) 200
200-100 minus 200.minus(100) 100
2*100 times 2.times(100) 200
300/3 div 300.div(3) 100
300%7 rem/mod 300.rem(7), 300.mod(7) 6

할당복합연산자

동일한 변수로 사친연산을 실행하고 동일한 변수에 할당할 경우 축약형인 할당복합연산자를 사용한다

표현식 같은 표현식 내부적 실행
a+=b a = a + b a.plusAssign(b)
a -= b a = a - b a.minusAssign(b)
a *= b a = a * b a.timesAssign(b)
a /= b a = a / b a.divAssign(b)
a %= b a = a % b a.modAssign(b)

단항연산자

증감연산자와 부호연산자가 있다. 

증감연산자는 뒤에 붙이면 현재상태를 반환한 후에 계산한다. 앞에 붙이면 먼저 계산하고 값을 반환한다.

표현식 의미 표현식 메서드 전환
+ 양수표시 +a a.unaryPlus()
- 음수표시 -a a.unaryMinus()
! 부정의 not !a a.not()
++ 증감연산 ++a a.inc()
-- 감소연산 --a a.dec()

연산자 사용 - 문자, 리스트 함수에서도 사용 가능

 

5. 식별자

코틀린에는 이름을 정의해서 사용하는 것으로 변수, 상수, 함수, 클래스, 인터페이스, object 등이 있다.

패키지, 클래스, 함수, 인터페이스, object 내부에서도 정의할 수 있다. 

어떻게 이름을 구분해서 참조할 수 있는지 알아보자!!!

 

패키지

패키지가 다를 경우에는 import해서 사용해야 한다.

패키지를 식별자로 사용 

최상위 레벨을 정의하면 패키지 이름이 식별자의 기준이 된다. -> 패키지가 다르면 같은 이름으로 클래스 등을 지정할 수 있다.

 

식별자 : 변수명, 함수명, 객체명, 인터페이스명, 클래스명 등을 작성할 때 이름의 충돌을 막고 항상 동일하게 조회해서 접근할 수 있는 이름을 말한다. 

 

프로그램 언어에서는 보통 예약어를 만들어 두고 이 예약어를 식별자로 쓰지 못하게 한다.

그러나, 코틀린에서는 일부 예약어를 식별자로 사용할 수 있다. 식별자 작성하는 방법을 알아보자!!

 

중요 예약어

- 하드 예약어 : 식별자로 사용할 수 있다 (as, break, class, do/while, els, false, for, fun ...)

- 소프트 예약어 : 특정 컨텍스트를 벗어날 경우 식별자로 사용할 수 있다 (by, catch, constructor, delegate, dynamicKotlin, field ...)

- 수정자 예약어/연산자 기호 : 특정 컨텍스트를 벗어날 경우 식별자로 사용할 수 있다 

 

식별자 처리 규칙

- 패키지 내에 지정된 클래스, 인터페이스, 함수, 속성은 패키지 이름 전체와 클래스, 인터페이스 함수, 속성 이름이 연결되어야 하나의 식별자로 인식한다.

- 클래스 내의 함수와 속성은 반드시 객체를 만들어 함수와 속성에 접근해야 처리할 수 있다.

- 함수 내에 정의된 변수는변수 이름이 식별자이다.

- 변수에 정의된 자료형인 클래스, 인터페이스, 함수 타입 등은 자신이 속한 패키지 이름과 자신의 일므까지가 하나의 식별자이다.

 

식별자 구분

- intArrayOf 함수 : kotlin 패키지에 있는 정수 배열을 만드는 함수

- intArray : kotlin 패키지에 있는 정수 배열 클래스

- println : 표준 출력 함수

 

표준 입출력

컴퓨터 키보드로 입력하면 화면에 보여주는 기능을 지원하는 패키지이다.

- 입력 함수 : readline

- 출력 함수 : print, println

 

val a = readline()!!.toInt()
val b = readLine()!!.toInt()

print("a= $a"); print(" b= $b");print("\n")
println(" sum ${a + b}")

/*
stdin: 100
stdin:200
a = 100 b= 200
 sum 300
*/

 

===== 

 

putExtra 상수

const val EXTRA_AGE = "age"

const val ARG_AGE = "age"