Kotlin

[Kotlin] 고급 문법

gangmini 2022. 7. 13. 02:07
반응형

💡람다식 (Lamda)

1. value 처럼 다룰 수 있는 익명함수

     1) 람다식을 메소드의 파라미터로 넘겨줄 수 있음

     2) return 값으로 사용 할 수 있음

 

2. val lamdaName : Type = {argumentList  → codeBody}

     1) Type은 (input type) → (output type)

     2)

val square : (Int) -> (Int) = {number : int -> number*number}

val nameAge : (String, Int) -> Stirng = {name : String, age : Int ->
	"my name us ${name} I'm ${age}"
}

fun main() : Unit{
	println(square(12)) // 144
	println(nameAge("mini", 23)) // my name us mini I'm 23
}

 

💡확장함수

1. 객체가 제공하는 기본 함수 정의 외의 함수를 람다식으로 사용자 정의하여 확장해 사용할 수 있다.

2. String 객체가 자기 자신(객체 본인)을 람다식의 input으로 넣어 return 값을 반환

3. 이때 람다식을 호출한 객체 본인을 this 라고 하고, input 매개변수가 1개일 때, 매개변수를 it 이라고 한다.

val pizzaIsGreat : String.() -> String = {this -> 
	this + "Pizza is the best!"
}

fun extendStirng(name : String, age : Int) : String{
	/* 함수 내부에 람다식 정의 */
	val introducMyself : String.(Int) -> String = {
		"I am ${this} and ${it} years old" // 파라미터가 딱 하나이기 때문에 it 이라는 예약어 사용
	}   
	return name.introducMyself(age) // return 시, 람다식 호출
	
}

fun main() : Unit {
	val a = "joyce said"
	val b = "mac said"

	println(a.pizzaIsGreat()) // 문자열 객체 a가 람다식으로 전달됨. 객체 자체가 input으로 쓰임
	println(b.pizzaIsGreat())
	println(extendStirng("ariana",27)) 
    
    /*
     extendStirng 함수 안에서 람다식(String 확장함수) 사용
     함수의 파라미터인 String 객체를 람다식의 input으로 넣어 사용 
    */
}

 

// 람다의 return
val calculateGrade : (Int) -> String = { // 파라미터가 1개 밖에 없어서 그냥 it으로 받음
	when(it){
		in 0..40 -> "fail"
		in 41..70 -> "pass"
		in 71..100 -> "perfect"
		else -> "error"
		}
}

// 람다를 표현하는 여러가지 방법
fun invokeLamda(lamda : (Double) -> Boolean) : Boolean { // lamda식을 input으로 함수에 넘겨주고 // 파라미터 이름이 lamda
	return lamda(5.2343) // return 에서 input으로 들어온 lamda식을 호출해 사용
}


fun main() : Unit {
	pritnln(calculateGrade(97))
	pritnln(calculateGrade(971))
    
	val lamda : (Double) -> Boolean = {number : Double -> // lamda식 정의
		number == 4.3213
	}
	
	println(invokeLamda(lamda))
	println(invokeLamda({it > 3.22})) // it > 3.22 가 람다식 (함수 body만 있음)
	invokeLamda{it > 3.22} // 람다식 이외의 파라미터는 없기 때문에 () 생략 가능 
	// 원래는 () 안에 파라미터를 , 로 구분해 쓰는데 여긴 람다식만 존재
    
	//invokeLamda{true} // invokeLamda 함수 안에는 람다식 형태의 무언가가 들어가야 하는데 이렇게 바로 논리형이 들어갈 수 있나???..
}

💡익명 내부 함수

1. 조건 1) Kotlin 인터페이스가 아닌 자바 인터페이스 

    조건 2) 그 인터페이스는 하나의 메소만 가져야 함

                  → 인터페이스 내부에 한 개의 메소드만 있기 때문에 람다식으로 작성하면 바로 그 메소드 호출

class MainActivity : AppCompatActivity(){
	override fun onCreate(savedInstanceState : Bundle?){
		super.onCreate(savedInstanceState)
		setcontentView(R.layout.activity_main)
    
		button.setOnClickListener(object : Veiw.OnClickListener { 
			// 버튼 클릭시 리스너 메소드로 감지. OnClickListener 인터페이스 구현 진행(implements X)
			overrride fun onClick(p0 : view?){   // 인터페이스 안에 메소드 오버라이드 해서 작성
				// to do..
			}
		})
    
		button.setOnClickListener { it : View   // object : Veiw.OnClickListener 를 말하는 것 같음
			// 어차피 클릭리스너 호출시 view 객체의 OnClickListener 인터페이스 호출 -> 그 인터페이스 안에 메소드 달랑 1개이니 바로 내용 작성
			// to do..
		}
    
	}
}

💡데이터 클래스

1. pojo(plain old java object) 클래스 :  어떤 동작을 수행 보다는 모델이 되는 클래스  작성을 위해 java 처럼  일일히 

    내용을 써주는 대신 간략하게 정의할 수 있도록 해주는 것

2. constructor(생성자), toString(), hashCode(), equals(), copy() 기능을 제공 

data class Ticket(val companyName : String , val name : String, var date : String, var seatNumber : Int)

fun main(){
	val TicketA = Ticket("KoreanAir","kkm","2022-12-23",23)
    
    println(TicketA) // Ticket(companyName=KoreanAir,name=kkm,date=2022-12-23,seatNumber=23)
    				 // 데이터 클래스 객체이므로 위와 같이 문자열로 정리하여 보여줌 // 일반적인 객체에서는X
}

💡Companion object

1. static 대신에 사용하는 기능으로 정적 변수, 정적 메소드를 선언할 때 사용

2. static 과는 조금 다르게 companion object도 엄연한 객체이고, 동반객체라고도 부른다.

3. 상위 객체당 딱 1개만 생성된다.

4. 싱글톤(Singletone) 구현

5. 접근 불가한 private property 나 메소드를 읽어올 수 있다. (private  생성자 대신 companion object 로 객체 생성 가능)

6. 이름 지정 가능

7. 인터페이스 상속 가능

class Book private constructor(val id : Int, val name : String){

	campanion object BookFactory : IdProvider{   // 이름 지정 가능, 인터페이스 상속 가능
    
    	val myBook = "new book" // property 생성 가능
		override fun getId() : Int { // 메소드 오버라이드
        	return 444
        }
    	fun create() : Book = Book(getId(), myBook) // Book 객체 생성
	}
}

interface IdProvider{
	fun getId() : Int
}

fun main(){
	val book : Book = Book.companion.create() // Book 클래스는 private 이므로 companion 객체의 메소드 사용
    
	println("${book.id} ${book.name}")
}

💡Object 클래스

1. 클래스당 1개의 객체만 생성

2. 다른 이름의 변수에 객체를 할당해도 결국 같은 객체를 가르키게 된다

object carFactory{ // carFactory객체는 object 객체이므로 1개만 생성
	val cars : MutableList<Car> = MutableListOf<Cars>  // 여러 car를 담는 list 배열
    
	fun makeCar(horsepower : Int){
		val car = Car(horsepower) // Car객체 생성
		cars.add(car)
		return car
	}

}

data class Car(val horsepower : Int)

fun main(){
	val car1 = carFactory.makeCar(10)   // 반환 되는 것은 Car 객체
	val car2 = carFactory.makeCar(200)  // 서로 다른 변수에 carFactory 객체를 생성한 것 같지만 실제 carFactory객체는 1개만 생성 
    
	println(car1)
	println(car2)
	println(carFactory.cars.size.toString())  // carFactory 는 1개만 생성, 그 안에 Car객체 계속 추가한 것이므로 size = 2
}

* Car 객체는 따로 생성 되지만 carFactory 객체는 하나만 생성되고, makeCar() 메소드를 통해 list에 계속 추가됨

 

[pojo 클래스]

https://m.blog.naver.com/weekamp/186678831

 

POJO(Plain Old Java Object) 란?

Java진영에서 어느날 갑자기 등장하여 개발자들을 모호하게 만들어 버렸던 POJO!! 이 녀석이 당췌 뭐...

blog.naver.com

[comapnion object]

https://jaejong.tistory.com/105

 

[Kotlin] 코틀린 기본 - object / Companion Object(동반 객체)

Kotlin - object 키워드 + Companion Object (동반 객체) Kotlin object 키워드 object는 흔히 JAVA에서 사용하는 무명 내부 클래스(anonymous inner class) 처럼 사용할 수 있습니다 object 키워드는 클래스를..

jaejong.tistory.com

 

반응형