class Car(val color : String)
val car = Car("red") // 객체 생성
println("My car color is ${car.color}") // 객체의 color 프로퍼티 사용
class Person1 constructor(name : String) {}
class Person2(name : String) {}
class Person3(val name : String) {}
class Person4 {
constructor(age : Int) {
println("I'm $age years old")
}
}
class Person5(name : String) {
constructor(name : String, age : Int) : this(name) {
println("I'm $age years old")
}
}
class Person6(name : String) {
val name : String
init {
if (name.isEmpty()) { // 문자열이 비어 있는 걍우 에러 발생
throw IllegalArgumentException("이름이 없어요.")
}
this.name = name // 문자열이 안 비어 있으면 이름 저장
}
}
val newPerson = Person6("") // 에러 발생
val newPerson = Person6("yeon-seo") // 객체 생성 성공
open class Flower {
open fun waterFlower() {
println("water flower")
}
}
class Rose : Flower() {
override fun waterFlower() {
super.waterFlower() // Flower 클래스의 메서드 먼저 실행
println("Rose is happy now")
}
}
val rose = Rose() // 객체 생성
rose.waterFlower() // water flower; Rose is happy now
open class Flower(val name : String) {}
class Rose(name : String, color : String) : Flower(name) {}
private val b = 2
class Dinner{
companion object{ // object 키워드
val MENU = "pasta" // 정적 변수 생성
fun eatDinner() {
println("$MENU is yummy!")
}
}
}
println(Dinner.Companion.MENU) // pasta
println(Dinner.MENU) // Companion 생략 가능 -> pasta
Dinner.eatDinner() // pasta is yummy!
abstract class Game {
fun startGame() {
println("게임을 시작했습니다.")
}
// 추상 메서드
abstract fun printName()
}
class Overwatch : Game() {
override fun printName() { // 추상 메서드 구현
println("오버워치입니다.")
}
}
val overwatch = Overwatch()
overwatch.startGame() // Game 클래스 메서드 -> 게임을 시작했습니다.
overwatch.printName() // Overwatch 클래스에서 구현한 메서드 -> 오버워치입니다.
data class Memo(val title : String, val content: String, var isDone:Boolean)
var memo1 = Memo("마트 가기", "계란, 우유, 빵", false)
data class Memo(val title: String, val content: String, var isDone: Boolean)
var memo1 = Momo("마트가기", "계란, 우유, 빵", false)
var memo2 = memo1.copy(content = "칫솔, 과자") // content 프로퍼티만 변경
println(memo1.toString())
// Memo(title=마트 가기, content=계란, 우유, 빵, isDone=false)
println(memo2.toString())
// Memo(title=마트 가기, content=칫솔, 과자, isDone=false)
interface Car{
abstract fun drive()
fun stop() // abstract 생략 가능
}
interface Car{
abstract fun drive()
fun stop() // abstract 생략 가능
fun destroy() = println("차가 파괴되었습니다.")
}
class Ferrari: Car {
}
class Ferrari : Car {
override fun drive() {
println("페라리가 달립니다.")
}
override fun stop() {
println("페라리가 멈춥니다.")
}
}
val myFerrari = Ferrari() // 객체 생성
myFerrari.drive() // 페라리가 달립니다.
myFerrari.stop() // 페라리가 멈춥니다.
myFerrari.destroy() // Car 인터페이스 디폴트 메서드 -> 차가 파괴되었습니다.
interface Animal {
fun breath()
fun eat()
}
interface Human {
fun think()
}
class Korean : Animal, Human { // 2개 이상의 인터페이스 구현
override fun breath() {
println("후-하 후-하")
}
override fun eat() {
println("한식 먹기")
}
override fun think() {
println("생각하기")
}
}
interface Animal {
fun breath()
fun eat()
}
interface Human {
fun think()
}
open class Name(val name : String) {
fun printName() {
println("제 이름은 $name")
}
}
class Korean(name : String) : Name(name), Animal, Human {
override fun breath() {
println("후-하 후-하")
}
override fun eat() {
println("한식 먹기")
}
override fun think() {
println("생각하기")
}
}
val joyce = Korean("정아")
joyce.breath()
joyce.printName()
var myName : String
var myName : String = null
var myName : String? = null
var myName : String? = null
myName = "Joyce"
println(myName.reversed()) // 에러 발생
fun reverseName(name : String?) : String? {
return name?.reversed()
}
println(reverseName("joyce"))
println(reverseName(null))
fun reverseName(name : String?) : String {
return name?.reversed() ?: "이름을 확인해주세요."
}
println(reverseName("joyce"))
println(reverseName(null))
fun reverseName(name : String?) : String { // 반환 자료형은 null 불가능
return name!!.reversed() // 절대 null이 아님을 보증
}
println(reverseName("joyce")) // ecyoj
println(reverseName(null)) // 에러 발생. java.lang.NullPointerException
lateinit var lunch : String
lunch = "waffle"
println(lunch)
val lazyBear : String by lazy{
println("곰이 일어났습니다.")
"bear"
}
println(lazyBear) // lazy 블록 실행됨
println(lazyBear) // 이미 초기화되었으므로 블록 실행 안됨
val sayHello = fun() { println("안녕하세요.") }
sayHello() // 안녕하세요.
val squareNum : (Int) -> (Int) = { number -> number*number }
println(squareNum(12)) // 144
val squareNum2 = {number : Int -> number*number}
val squareNum3 : (Int) -> Int = {it*it}
fun invokeLambda(labmda : (Int) -> Boolean) : Boolean {
return lambda(5)
}
val paramLambda : (Int) -> Boolean = {num -> num == 10}
println(invokeLambda(paramLambda))
invokeLambda({num -> num == 10}) // 람다식 바로 넣어주기
invokeLambda({it == 10}) // 인수가 하나일 때 it으로 변경 가능
invokeLambda() {it == 10} // 만약 하수의 마지막 인수가 람다일 경우 밖으로 뺄 수 있음
invokeLambda{it == 10} // 그 외 인수가 없을 때 () 생략 가능
button.setOnClickListener{
// 버튼이 눌렸을 때 작동할 코드
}
public ovid setOnClickListener(@Nullable OnClickListener l) {
...
}
public interface OnClickListener {
void onClick(View v);
}
// 람다를 사용하지 않았을 때
button.setOnClickListener(object : OnClickListener{
override fun onClick(view: View) {
doSomething()
}
})
// 람다 사용 1
button.setOnClickListener({ view -> doSomething() })
// 람다 사용 2 : 코틀린 컴파일러가 인수를 미리 알기 때문에 생략,
// (인수가 여러 개일 때) 마지막 인수가 람다인 경우 {}를 밖으로 이동
button.setOnClickListener() { doSomething() }
// 람다 사용 3 : 유일한 인수인 경우 () 생략
button.setOnClickListener { doSomething() }
NOXMLActivity.kt
package com.example.helloworld
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
class NoXMLActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ConstraintLayout 생성
val layout = ConstraintLayout(this).apply {
layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.MATCH_PARENT
)
id = ConstraintSet.PARENT_ID
}
// 버튼 생성
val button = Button(this).apply {
id = View.generateViewId()
text = "클릭하세요"
layoutParams = ConstraintLayout.LayoutParams(
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
setOnClickListener {
Toast.makeText(this@NoXMLActivity, "안녕하세요", Toast.LENGTH_SHORT).show()
//Toast.makeText(applicationContext, "안녕하세요", Toast.LENGTH_SHORT).show()
}
}
// 레이아웃에 버튼 추가
layout.addView(button)
// 버튼을 레이아웃 중앙에 배치
ConstraintSet().apply {
clone(layout)
connect(button.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0)
connect(button.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
connect(button.id, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START, 0)
connect(button.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END, 0)
applyTo(layout)
}
// 생성된 레이아웃을 액티비티의 콘텐츠 뷰로 설정
setContentView(layout)
}
}