일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Exposed Drop-Down Menu
- android api
- 공유 기능
- 안드로이드 스튜디오
- 안드로이드 api
- 플레이 콘솔 프로덕션
- 플레이스토어 앱 게시 문제
- Retrofit
- Dialog
- 안드로이드스튜디오
- 앱 출시
- urlconnection
- Kotlin
- Bottom sheet
- 비동기
- Callback
- 안드로이드 http
- android studio
- 앱개발
- Today
- Total
Strong 감자의 공부
Ch02_ 코틀린에서는 모든것이 객체이다. 본문
책 : 개발자를 위한 Kotlin 프로그래밍 A to Z
읽다가 헷갈리는 문법들에 대해선 링크 달아두었습니당!
링크 단것들에 대해 다 설명을 달려다가,,, 글이 너무 길어지기도하고 후반부에도 다룰것이므로 링크만 걸어둡니당!
실습은 Intelij로 하였습니다.
build.gradle.kts 파일 -> dependencies 블록 안에 아래한줄 추가해야 코틀린 객체 확인이 가능했습니다.
dependencies {
...
implementation(kotlin("reflect"))
}
1 . 객체
- 코틀린은 모든것을 객체로 처리하고 객체에는 해당하는 클래스가 있다.
- 객체의 클래스를 확인하는 방법
class Exp { val h = "hello" } fun main() { val c = Exp().h println(c.javaClass.kotlin) }
✔️ 안드로이드 스튜디오에서 kotlin으로 액티비티를 넘길때 ::class.java로 하는 이유
::class는 코틀린에서 사용되는 KClass를 반환한다. 그래서
::class.java라고 해야 자바에서 사용되는 Class로 반환해 줍니다.
✔️ kotlin :: (더블클론, 리플렉션)
객체를 통해 클래스의 정보를 분석해 내는 프로그래밍 기법
구체적인 클래스 타입을 알지 못해도 그 클래스의 메소드, 타입, 변수들에 접근할 수 있다.
즉, 컴파일 시간이 아니라 런타임에 동적으로 특정 클래스의 정보를 객체화하여 분석 및 추출해낼 수 있는 프로그래밍 기법이다.
->리플렉션을 왜 사용하는지
정적 언어로의 한계점(구체적인 틀래스를 모르면 해당 클래스 정보에 접근이 불가)을 보완 구체적인 클래스를 알지 못해도 런타임 도중 해당 클래스의 정보에 접근할 수 있도록 해주는 것이 Reflection 이다.
https://velog.io/@spdlqjfire/Reflection → 나중에 다시 읽어보기
2. 객체 표현과 주석
🔶객체 표현
- 숫자 100, 문자 ‘가’등은 리터럴 표기법으로 작성하면 객체이면서 값으로 사용한다.
- 정수는 기본이 Int클래스의 객체이다. / Long클래스의 객체 표현: 100L(혹은 l)
- 실수는 기본이 Double클래스의 객체이다. / float 클래스의 객체 표현 : 100.0F
- 코틀린은 각 클래스의 자료형을 별도로 관리한다
- 메서드 : 클래스 내부에 정의한 함수고 객체가 점연산자로 접근해 실행
- 함수 : 함수이름과 호출자로 실행
- 연산자 : 예) + -… 100+100 이렇게 표기해도 내부에선 해당 메서드 100.plus(100)으로 변환해 처리
🔶주석
- 문서화 주석 : KDoc
- /** … */
- Dokka를 이용해 문서로 변환 가능
- ****https://velog.io/@dudgns0507/Kotlin-KDoc으로-코틀린-코드-문서화하기-feat.-Dokka
🔶 문자열
- charArrayOf('가', '을').contentToString()
- charArrayOf(문자들 ):문자를 인자로 받아 배열을 만듦
- .contentToString() :배열 내부 원소 출력
- var str = String(charArrayOf('가', '을' ))
fun main() {
println('가'.javaClass.kotlin)
println(charArrayOf('가','을').contentToString())
var str =String(charArrayOf('가','을'))
println(str)
}
- 문자열 탬플릿을 사용해서 문자열로 변환해 출력
fun main() {
val date = "20200101"
val a = 100
val b = 200
println("날짜 :$date")
println("100 +200 = ${a + b}")
}
- 이스케이프 문자 (\이용)
- (예를 들어 “” ‘’ 는 각각 문자열, 문자로 인식을 할 수있는데 \이스케이프 문자를 통해 “는 문자 자체라는걸 알려줄 수 있다.)
- \’ : 작은 따옴표 표현
- \” : 큰따옴표
- \/ : 슬래시
- \\ : 역슬래시
fun main() {
val date = "20200101"
println("날짜\\ :$date")
}
- \n : 다음줄 이동
- \r: 캐리지 리턴이라고 하는데 \r 앞에 단어들이 다 사라지는거 같다.
fun main() {
val date = "20200101"
println("날짜\r :$date")
}
- \t: 탭
- \b: 백스페이스
fun main() {
val date = "20200101"
println("날짜\b :$date")
}
- 원시 문자열 처리
- “”” “”” 를 이용하면 이스케이프 문자들을 그대로 인식함.
- “”” “”” 안에 문자열 탬플릿${} 기능 추가 가능
fun main() {
val date = "20200101"
println("""\n날짜 :$date""")
}
- 형식문자 포매팅
- $s : 문자열 처리
- %d : 정수처리
- % f : 실수 처리
- %e : 실수를 지수로 표기
- %x : 정수를 16진수로 표기
- %6.2f : 전체 실수는 6자리, 그중 소수점 이하는 2자리
- format이용한 코드
fun main() {
val float =123.4
val int =100
val string = "문자열"
val edec= 10e5 // 지수 표현 10*10^5
val hex = 0xffff // 16진수
println("float = %6.2f, int =%6d, string = %10s".format(float,int,string))
println("edec = %e , hex= %x".format(edec, hex))
}
03.값을 저장하는 변수와 상수
- 변수는
- 예약어 val, var 사용
- 변수이름을 작성시 소문자나 _스코어로 시작
- 카멜표기법 예 ) firstWord 두번째단어는 대문자
- 상수는
- const val예약어 사용
- 패키지나 objeect 예약어를 사용하는 곳에서만 정의 가능
- 변수와 구별하기 위해 상수 이름은 모두 대문자
- 파스칼표기법( 예) StudentFragment(첫글자, 다시 시작하는 단어의 첫글자 대문자) → 클래스, Object, 인터페이스 명을 지을떄
- 스네이크 표기법 예) const val GLOBAL_SCORE : 보통 상수는 모두 대문자로 쓰지만 ,단어 연결시 _이용하기도 한다.
- 지역변수와 전역변수
- 전역변수 : 코틀린은 패키지 단위로 관리하므로 패키지단위에 정의된 최상위 변수
- var 로 선언된 전역변수는 {} 지역영역 즉 함수내부나 for순환내부 등에서 변경할 수 있다.
- 지역변수: 함수코드 블록인 {} 사이에 정의해서 사용하는 변수
- 외부에서 참조 할 수 없다. = 서로 다른 코드블록안에 같은 이름의 지역변수를 만들 수 있고 각각 안에서 참조된다.
- 전역변수 : 코틀린은 패키지 단위로 관리하므로 패키지단위에 정의된 최상위 변수
fun main() {
for(i in 1.. 2){
val localVal = 100
println("for 지역변수" + localVal)
}
for(i in 1.. 2){
val localVal = 200
println("for 지역변수" + localVal)
}
}
위의 사진처럼 지역변수는 외부에서 참조 할 수 없지만 클로저 환경을 구성할 땐 외부 접근 허용
(클로저 환경이란?https://jaeyeong951.medium.com/java-클로저-vs-kotlin-클로저-c6c12da97f94 )
- 변수 정의 시 자료형
- 예) val a : String =”abc”
- 자료형에는 클래스, 추상클래스, 인터페이스가 올 수 있다.
- 자료형 지정하지 않으면 처음 할당된 값을 보고 자료형을 확정한다.
- 두번째 할당될 경우 같은 자료형이 아니면 예외를 발생
- 변수와 속성의 차이
- 코틀린에서 지역변수만 변수이고 나머진 다 속성이다
- 이 말은 자바엔 getter와 setter가 있는데 코틀린은 자동으로 getter와 setter가 구현돼 있다는 말같다. (하지만 상황에 따라 getter, setter 정의 가능하다.)
- +Object
class Exp {
val memberVal: Int =100 // 클래스 속성
}
object Obj{
val objval =100 // 객체 속성
}
fun main() {
val k = Exp()
println(k.memberVal) // 객체 인스턴스 생성 후 접근
println(Obj.objval) // 객체 이름으로 접근
}
https://www.bsidesoft.com/8187
- 타입변환
- 기본 자료형인 숫자나 문자열에 자료형 변환 메서드가 있어 이를 사용해 타입을 변환할 수 있다.
fun main() {
var number = 10000
var longNumber= 10L
longNumber = number.toLong()
println(longNumber.javaClass.kotlin)
}
- 다른 객체인 경우 as 예약어를 통해 자료형을 변환한다.
- 일반적으로 캐스트가 불가능한 경우 캐스트 연산자는 예외를 발생시킨다. 따라서 안전하지 않다고 한다. 코틀린의 안전하지 않은 캐스트는 중위 연산자 as에 의해 수행된다. 예외를 방지하려면 as?와 같이 사용한다. 실패 시 null을 리턴한다.
- https://yiyj1030.tistory.com/248
- 정수 자료형이 다른 경우에도 리터럴 표기법에서 계산 가능
- 대신 계산한 값이 상위 자료형이므로 변수에 할당하면 최종 처리된 결과인 자료형으로 확정
fun main() {
var number = 10000
var longNumber = 10L
var result = number + longNumber
println(result.javaClass.kotlin)
}
04. 계산 연산자
- 사칙 연산처리
- 표현식 내부적 실행
a+b a.plus(b) a-b a.minus(b) a*b a.times(b) a/b a.div(b) a%b a.rem(b) , a.mod(b)
- 할당복합
- 연산자표현식 내부적 실행
a+=b a.plusAssign(b) a-=b a.minusAssign(b) a*=b a.timesAssign(b) a/=b a.divAssign(b) a%=b a.modAssign(b) - 단항 연산자
- 연산자 표현식 메서드전환
+ +a a.unaryPlus() - -a a.unaryMinus() ! !a a.not() ++ ++a a.inc() — —a a.dec() - 예 )_currentWordCount.value = _currentWordCount.value?.inc() )
- 연산자를 추가로 사용하는 경우
- 연산자오버로딩 -> operator 예약어 추가해야함
- 문자열 등에도 덧셈연산자를 사용할 수 있다. 이때 덧셈연산자는 문자열을 결합하는 용도로 사용할 수 있다.
- 아래는 덧셈연산자가 문자열에 재정의 되어있어 문자열에서 연산자 사용한 예이다.
- 연산자오버로딩 -> operator 예약어 추가해야함
fun main() {
val start = "온고"
val middle = "지신"
val end= "-공자"
val result = start+middle+end
println(result)
}
fun main() {
val number =listOf("one","two")
val plusList = number+"five"
val minusList= number-listOf("one")
println(plusList)
println(minusList)
}
- 사용자 정의 클래스를연산자의 메서드 이름으로 재정의 하면 연산자 기호를 사용할 수 있다.
- plus를 - 로 재정의 하였다.
- 이때 재정의 함수는 클래스의 멤버 여야한다.
import kotlin.math.min
class Exp(val fir:Int){
}
operator fun Exp.plus(sec:Int) : Int = fir-sec // 재정의
fun main() {
val exp : Exp = Exp(5)
val result :Int = exp + 3 // 값은 5-3
print(result)
}
- 비트 연산자 처리
연산자 | 설명 |
shl | 이진수를 왼쪽으로 이동 |
shr | 이진수를 오른쪽으로 이동 |
ushr | 부호없는 이진수 오른쪽이동 |
and(&) | 같을 때 1 다르면 0 |
or(\) | 하나라도 1 이면 1 |
xor(^) | 서로다르면 1 같으면 0 |
inv | 비트를 반전시키는 연산 |
fun main() {
val bit1 :Int =17
val bit2 :Int = 0b1111
println(bit1.toString(2))
println("${bit1} xor ${bit2} = "+( bit1 xor bit2))
println((bit1 xor bit2).toString(2))
}
fun main() {
val bit1 :Int =17
val bit2 :Int = 0b1111
println("bit 1 이진수 "+bit1.toString(2))
println("${bit1} xor ${bit2} = "+( bit1 xor bit2))
println("${bit1} xor ${bit2} = "+(bit1 xor bit2).toString(2))
println("bit1 shiftLeft = ${bit1.shl(2).toString(2)}")
println("bit1 shiftRight = ${bit1.shr(2).toString(2)}")
}
🌻 .shr() : 이동으로 인한 빈자리는 부호값으로 채움(음수인 경우 1, 양수인경우 0)
.ushr() : 이동으로 인한 빈자리를 부호관계없이 0으로 채움
→ 부호관련은 오른쪽으로 비트 이동할때만 있어서 ushr만 존재
https://codedragon.tistory.com/7998
05.식별자 알아보기
- 코틀린은 패키지 단위로 파일에 작성된 코드를 관리. 파일이 달라도 패키지명이 동일하면 동일한 패키지로 관리= 패키지가 다르면 같은 이름으로 클래스 등 지정 가능
- as : 패키지 별칭 사용
- 패키지는 다르지만, 이름이 같을경우 import하면 이름의 충돌이 발생할 수 있다.
- import kotlin.math.PI as circleRatio
- import kotlin.math.cos as cosine
- println(circleRatio)
- 코틀린에서는 일부 예약어를 식별자로 사용할 수 있다.
fun main() {
val main_ ={print("hello")}
// println(main) // 에러
println(::main) // 메인함수 참조
println(main_) // 변수할당된 람다 표현식 참조
}
- 표준입출력
- 입력함수 : readline
- 출력함수 : print, println
fun main() {
// readline()으로 스트링형 입력받고 " " 단위로 분리 후 int형으로 변환, it은 값
val input=readLine()!!.split(" ").map{it.toInt()}
var sum=0
for(i in (0untilinput.size))
sum+=input[i]
println(sum)
}
map과 같은 고차함수에 대해
https://developer.android.com/codelabs/basic-android-kotlin-compose-higher-order-functions?hl=ko#2
🌻🌻 스터디 후기 🌻🌻
스터디원들에게 나온 질문들과 멘토님 피드백
1️⃣
- 코틀린은 모든 것을 객체로 본다.
- JVM으로 실행되어 자바와 동일하게 Primitive사용
- 컴파일 처리할 때 까지 모든 객체는 해당 클래스가 있다.
JVM내에서 컴파일 시 Kotlin -> Java로 바뀌는 과정에서 코틀린의 객체들이
Primitive으로 바뀔 수 있는건 바뀌는게 맞을까요?
예상 :
val num: Int = 10 // 컴파일 시 Primitive
val user: User = User() // 컴파일 시 Reference
코틀린 코드 디컴파일
IntelliJ -> tools->kotlin->show kotlin Bytecode ->새로운 창에서 Decompile한 결과이다.
코틀린 파일
class Exp {
var a = 12
}
fun main() {
var exp = Exp()
println(exp)
println(exp.a)
}
자바 디컴파일 결과
public final class ExpKt {
public static final void main() {
Exp exp = new Exp();
System.out.println(exp);
int var1 = exp.getA();
System.out.println(var1);
}
...
public final class Exp {
private int a = 12;
public final int getA() {
return this.a;
}
public final void setA(int var1) {
this.a = var1;
}
}
2️⃣ 비트 연산자는 개발시 어디에 쓰이는가?
안드로이드스튜디오에서 gravity줄 때 top & right, rop&left 처럼 동시에 줄 때 비트연산자 and, or, xor 이용할 수 있다.
추가로 수학적 연산이 들어갈때 쓴다고 하셨는데 거의 안쓰인다고 하셨다.
3️⃣
연산자가 a-b가 있고 이에 대응하는 메소드가 a.minus(b)인데 후자와 같이 메소드를 쓰면 null Safe Call할 때 좋다.
fun main() {
var a :Int ?=4
val b :Int =3
a= null
// println(a-b) // 오류
println(a?.minus(b)) // 결과값 : null
println(a?.minus(b) ?: 4) // 결과값 : 4
}
'CS > 문법_Kotlin' 카테고리의 다른 글
Ch_07 클래스 관계 등 추가 사항 알아보기 (0) | 2023.08.25 |
---|---|
Ch_ 06 내장자료형 알아보기 (0) | 2023.08.19 |
Ch_05 클래스 알아보기 (0) | 2023.08.11 |
Ch_04 함수 알아보기 (0) | 2023.08.04 |
Ch03_문장 제어 처리 알아보기 (0) | 2023.07.26 |