71일차(1)/Android App(15) : Kotlin Abstract Class, Companion, Map
Stpe05_AbstractClass
package com.example.kotlin_test
//추상 클래스
abstract class Weapon{
fun move(){
println("이동합니다.")
}
abstract fun attack()
}
class MyWeapon : Weapon(){
override fun attack() {
println("무언가를 공격해요")
}
}
fun main(){
val w1=MyWeapon()
w1.move()
w1.attack()
println("-------------------")
/*
with( 참조값 ){
}
참조값을 가지고(참조값과 함께 여러가지 작업을 {} 안에서 한다.
*/
with(w1){
move()
attack()
}
//익명 클래스를 이용해서 추상클래스(Weapon) type의 참조값 얻어내기
val w2= object : Weapon(){//클래스 상속은 ()가 있어야 한다.
override fun attack() {
println("공중 공격을 해요")
}
}
w2.move()
w2.attack()
//다형성 확인
val a:MyWeapon = w1
val b:Weapon = w1
val c:Any = w1 //java에서 Object type 에 해당되는 type이다.
}
- 코틀린에서 추상클래스 만들기!
- 추상클래스에 들어 있는 메소드는 완성되었을 수도 있고 아닐 수도 있다.

- 단 미완성된 메소드가 하나라도 있으면
클래스 앞에 abstract 를 붙여서 추상클래스를 정의해야 한다.

- 추상 클래스를 상속하면 추상메소드를 override 하는 것이 강제된다.
- 상속한 클래스에서 추상 메소드를 완성해주면 된다. java와 거의 똑같다!
- 담은 변수 w1에 점을 찍어서 그대로 사용할 수 있다.
** 코틀린의 특이한 문법 : With

- 메소드의 설계가 잘 되어있다면 이렇게 연속으로 호출할 수도 있다.
- 이 경우, move() 메소드 안에서 자기 자신의 객체를 다시 리턴해줄 수 있는 구조가 되어야 한다.

- 이런 구조이면 자기자신이 리턴되어 메소드를 연속으로 호출할 수 있다.

- 자기 자신의 참조값을 다시 리턴하기 때문에 가능한 것
- 이렇게 설계되어 있지 않으면 이렇게 호출할 수 없다. 에러가 난다.

- with( ){ } 라는 구문이 있다.
- 그 안에 w1이라는 참조값을 넣어주면 w1에서 사용할 수 있는 메소드를 연속으로 작성해 사용할 수 있다.
- { } 안에서 this 는 MyWeapon 타입이라는 것을 알려주고 있다.
- 그래서 안에서 this.move(), this.attack() 이라고 작성하지 않아도 되는 것이다.(메소드가 매우 많을때 유용하다)

- weapon 추상클래스를 상속받은 익명클래스이다.
- 똑같이 밑줄에서 alt+enter로 메소드를 override 해주면 된다.

- 클래스 상속은 () 가 있어야 한다.
- 인터페이스를 구현할 때와의 차이!
- 코틀린은 java보다 훨씬 더 많은 기능을 제공해주기 때문에,
코틀린을 사용하면 java보다 적은 코딩양으로 많은 것을 할 수 있다.
- spring boot 에서 작성한 코드도 코틀린으로 변경할 수 있다.

val / var 식별자 : 타입 = 값 (대입)
- 이런 형태로 작성한다. 타입을 추론할 수 있는 경우에는 생략이 가능하다.
- value에 있는 값이 식별자에 들어간다.
- val 상수로 사용: 값이 한번 결정되면 바꾸지 않는다,
- var 변수로 사용: 그때그때 다른 값을 넣어서 사용하겠다.
val a:MyWeapon = w1
val b:Weapon = w1
val c:Any = w1 //java에서 Object type 에 해당되는 type이다.
- w1은 현재 weapon타입의 참조값이 들어가있다.
- 여러 타입에 넣어보면서 다형성 확인하기!
val a:MyWeapon = w1
val a = w1
- 위와 같이 쓰는 것이 타입을 확실하게 표기하는 것이지만,
타입을 추론할 수 있으면 아래와 같이 써도 된다.
- java의 object (모든타입의 부모타입) 와 같은 것으로
코틀린에는 Any 라는 타입이있다.
- 어떤 타입의 객체든 모두 Any 타입에 담을 수 있다.
Step06_Companion
package com.example.kotlin_test
class Util{
//Util 클래스와 함께하는 동반객체
companion object {
//동반객체의 필드와 메소드(함수)를 정의하면 된다.
val version:String="1.1.2"
fun send(){
println("전송합니다.")
}
}
}
fun main(){
/*
클래스명에 . 찍어서 동반객체에 있는 필드나 메소드를 활용할 수 있다.
*/
Util.send()
println(Util.version)
}
- companio, 동반하는 이라는 뜻!

- 위: 참조값 얻어내서 사용하기
- 아래: 클래스에 점 찍어서 사용하기 ← 오류가 발생한다.
- java에서는 이것이 구분되었는데, 코틀린에서는 안 된다.
- static 이라는 예약어가 코틀린에는 없다.
- 그러면 클래스에 점을 찍어서 바로 사용하는 것은 어떻게 만들면 될까?

- Companion object : 동반 객체라는 것이 있다!
- Companion object{ } 안에 메소드를 정의한다.

- 이렇게 특이한 모양으로 만드는 이유는? 여러 언어와의 호환성을 위해서
- 이렇게 작성해두면 아래에서 Util.send() 형태로 작성할 수 있다.
- 클래스명에 . 점을 찍어서 동반 객체에 있는 필드나 메소드를 활용할 수 있다.
- 클래스가 하나만 만들어지는 java에서의 static 클래스/메소드와 비슷한 것이다.
- companion object{} 이 중괄호 안에 정의하면 된다.

- 필드도 정의할 수 있고,
필드 또한 클래스명에 점을 찍어서 바로 사용할 수 있다.
Step07_Map
package com.example.kotlin_test
fun main(){
//수정 불가능한 Map
val mem=mapOf<String, Any>("num" to 1, "name" to "바나나", "isMan" to false)
//Map 에 저장된 데이터 참조하는 방법1
val num=mem.get("num")
val name=mem.get("name")
val isMan=mem.get("isMan")
//Map 에 저장된 데이터 참조하는 방법2
val num2=mem["num"]
val name2=mem["name"]
val isMan2=mem["isMan"]
//수정 가능한 Map
val mem2= mutableMapOf<String, Any>()
//빈 Map에 데이터 넣기 방법1
mem2.put("num",2)
mem2.put("name","딸기")
mem2.put("isMan", true)
val mem3:MutableMap<String,Any> = mutableMapOf()
//빈 Map에 데이터 넣기 방법2
mem3["num"]=3
mem3["name"]="복숭아"
mem3["isMan"]=false
}
- java의 HashMap 사용법
- 코틀린에서 java 클래스를 import해서사용할 수 있을까?

- 클래스를 import 하려고 보면 java.util 이 있다??!
- 이외에도 java의 ArrayList 등도 사용할 수 있다.
- 코틀린은 java와 100% 호환되기 때문에 java에 있는 클래스를 가져다 쓸 수 있다.

- HashMap도 두가지 버전이 있다.
- 코틀린에서 HashMap<>() 과 비슷한 메소드로는 mapOf<>() 라는 메소드가있다.

- key : value 가 아니라 key to value 로 작성한다.
//Map 에 저장된 데이터 참조하는 방법1
val num=mem.get("num")
val name=mem.get("name")
val isMan=mem.get("isMan")
//Map 에 저장된 데이터 참조하는 방법2
val num2=mem["num"]
val name2=mem["name"]
val isMan2=mem["isMan"]
1) 변수명.get("데이터")
2) 변수명["데이터"]
- 데이터를 참조하여 가져오는 방법이 2가지가 있다.

mapOf<>()
- mapOf 는 수정 불가능한 Map이다. 데이터가 한번 들어가면 상수처럼 사용해야 한다.
- 제네릭을 굳이 쓰자면...? 안에 들어있는 타입 종류가 여러개이므로 Any로 받아주어야 한다.
- 근데 key, value의 타입을 모두 추론(infer)할 수 있기 때문에 굳이 작성 안해줘도 된다. 생략가능!
mutableMapOf<>()
- 수정가능한 맵
- .put() 으로 새로 넣어주기 가능

- <> 제너릭 타입을 지정하는 것은 메소드에다가 넣을 수도 있고, 변수를 받을 때 지정할 수도 있다.
(당연 위의 방법이 더 편하다!)
'국비교육(22-23)' 카테고리의 다른 글
72일차(1)/Android App(17) : Kotlin에서 java 클래스 사용, Lambda 표현식 (0) | 2023.01.18 |
---|---|
71일차(2)/Android App(16) : Fragment(1) (1) | 2023.01.18 |
70일차(2)/Android App(14) : Kotlin Extend, Interface / inner class 사용하기 (0) | 2023.01.16 |
70일차(1)/Android App(13) : Custom Adapter 생성, Serializable 인터페이스 구현 (0) | 2023.01.16 |
69일차(2)/Android App(12) : ListView, Adapter 활용 예제 / java to kotlin 작성 연습 (0) | 2023.01.15 |