오늘은 스파르타 본캠프 2주차 시작하며 지급받은 'Kotlin 문법 종합반' 강의영상을 보며 문법 공부를 했다.
변수선언, 반복문등 간단한 내용은 빠르게 지나갔고, 조금이라도 헷갈리던 부분을 집중적으로 공부했다.
예를 들며 보는게 제일 이해가 쉬워 예를 들며 다시한번 오늘 배운내용을 정리해보면
특정한 로직을 가지는 소스코드에 이름을 붙일 수 있다.
fun main() {
var num1 = readLine()!!.toInt()
var num2 = readLine()!!.toInt()
// sum이라는 이름의 메소드를 호출!
sum(num1, num2)
}
fun sum(num1:Int, num2:Int) {
var result = num1 + num2
println("num1과 num2의 덧셈결과는 ${result}입니다.")
}
sum이라는 메소드를 설계한 내용이다. 이 메소드는 Int형 변수 num1과 num2를 입력받아서 두개의 값을 더해서 result라는 새로운 변수에 저장하고, 결과를 print시켜준다.
Object Oriented Programming(OOP)라고 불리며 5대 키워드가 존재한다.
프로그램의 각 요소별 설계도라고 해석할 수 있다. 클래스에는 정보와 행위(프로퍼티와 메소드)를 작성해준다. 보통 하나의 파일에 하나의 클래스를 사용하지만 예외인 경우도 존재한다.
fun main() {
}
class Character {
var name:String = ""
var hairColor:String = ""
var height:Double = 0.0
fun fireBall() {
println("파이어볼!")
}
}
예를 들면, rpg게임을 만들때, 캐릭터를 생성한다고 가정하면, Character클래스를 만들어줄 수 있다. 그 안에 캐릭터의 정보인 name, hairColor,height등의 정보를 선언해주고, fireBall()이라는 행위를 선언해 줄 수 있다.
fun main() {
}
class Character {
var name:String = ""
var hairColor:String = ""
var height:Double = 0.0
var age:Int = 0
var gender:String = ""
// 명시적 생성자 (Constructor)
constructor(_name:String, _hairColor:String, _height:Double) {
println("${_name}을 생성자로 넘겼어요")
println("${_hairColor}를 생성자로 넘겼어요")
println("${_height}를 생성자로 넘겼어요")
}
constructor(_name:String, _hairColor:String, _height:Double, _age:Int, _gender:String) {
println("${_name}을 생성자로 넘겼어요")
println("${_hairColor}를 생성자로 넘겼어요")
println("${_height}를 생성자로 넘겼어요")
println("${_age}를 생성자로 넘겼어요")
println("${_gender}를 생성자로 넘겼어요")
}
fun fireBall() {
println("파이어볼!")
}
}
ex)위 예시와 같이 캐릭터 클래스를 만드는데 명시적 생성자 constructor을 이용해서 두가지의 케이스를 만들수 있다. 이름,머리색,키 3가지값만 받아왔을때는 위에꺼, 나이와 성별까지 포함한 5가지 값을 받아왔다면 아래꺼를 이용할 수 있다.
-> 형식이 고정되어있지 않아 더 자유롭게 활용이 가능하다.
객체란?
fun main() {
// 불마법사로 객체화
var magicianOne = Character("불마법사", "red", 180.2)
println("${magicianOne.name}의 머리색상은 ${magicianOne.hairColor}입니다")
magicianOne.fireBall()
// 냉마법사로 객체화
var magicianTwo = Character("냉마법사", "blue", 162.2, 25, "여")
println("${magicianTwo.name}의 머리색상은 ${magicianTwo.hairColor}이고 나이는 ${magicianTwo.age}입니다.")
magicianTwo.fireBall()
}
class Character {
var name:String = ""
var hairColor:String = ""
var height:Double = 0.0
var age:Int = 0
var gender:String = ""
// 명시적 생성자 (Constructor)
// _name, _hairColor, _height와 같이 생성자에 변수를 넘기는 경우에 사용함
constructor(_name:String, _hairColor:String, _height:Double) {
println("${_name}을 생성자로 넘겼어요")
println("${_hairColor}를 생성자로 넘겼어요")
println("${_height}를 생성자로 넘겼어요")
name = _name
hairColor = _hairColor
height = _height
}
// _name, _hairColor, _height, _age, _gender와 같이 생성자에 변수를 넘기는 경우에 사용함
constructor(_name:String, _hairColor:String, _height:Double, _age:Int, _gender:String) {
println("${_name}을 생성자로 넘겼어요")
println("${_hairColor}를 생성자로 넘겼어요")
println("${_height}를 생성자로 넘겼어요")
println("${_age}를 생성자로 넘겼어요")
println("${_gender}를 생성자로 넘겼어요")
name = _name
hairColor = _hairColor
height = _height
age = _age
gender = _gender
}
}
생성자에서 예로든 내용에서 main함수에 Character클래스를 객체화해서 여러가지 캐릭터를 만들 수 있다. 원하는 값을 넣으면 해당 클래스에 값을 넣고, 내용을 가져올 수 있다.
클래스를 상속한다?
fun main() {
var bird = Bird()
var chicken = Chicken()
var sparrow = Sparrow()
bird.fly()
chicken.fly()
sparrow.fly()
}
open class Bird {
fun fly() {
println("새는 날아요~")
}
}
class Chicken : Bird() {}
class Sparrow : Bird() {}
닭과 참새는 둘다 새라는 공통점이 있다. Bird클래스를 open키워드를 사용해서 부모 클래스로 만들고, Chicken클래스와 Sparrow클래스에 :Bird()를 써주면 부모 자식 클래스로서 상속되며, 자식클래스에서는 선언되지 않았던 print문을 사용할 수 있게 된다.
단축키: ctrl+O
부모 클래스의 정보를 재설계 할수 있다.
fun main() {
var bird = Bird("새")
var chicken = Chicken("닭", 2)
var sparrow = Sparrow("참새", "갈색")
bird.fly()
chicken.fly()
sparrow.fly()
}
open class Bird(name:String) {
var name: String = ""
init {this.name = name}
open fun fly() {
println("${name}은 날아요~")
}
}
class Chicken(name: String, age: Int) : Bird(name) {
var age:Int = 0
init {this.age = age}
override fun fly() {
println("${age}살의 ${name}이 날아봅니다~ 꼬끼오!")
}
}
class Sparrow(name: String, color: String) : Bird(name) {
var color:String = ""
init {this.color = color}
override fun fly() {
println("${color}의 ${name}이 날아봅니다~ 짹짹!")
}
}
부모클래스에서 사용하던 fly()함수를 open을 이용해서 상속시켜서 자식 클래스에서 재정의한 내용이다. 원래 .fly()를 사용하면 '닭은 날아요~/참새는 날아요~' 가 출력되어야 하지만 새로 재정의 했기 때문에 '2살의 닭이 날아가봅니다~ 꼬끼오!'가 출력된다.
동일한 이름의 메소드를 여러 형태로 만들 수 있다.
fun main() {
var calc = Calculator()
var intResult = calc.add(1,2)
var doubleResult = calc.add(1.2, 2.2)
println("정수 덧셈결과: ${intResult}")
println("실수 덧셈결과: ${doubleResult}")
}
class Calculator {
fun add(num1: Int, num2: Int): Int {
return num1+num2
}
fun add(num1: Double, num2: Double): Double {
return num1+num2
}
}
같은 이름은 add로 선언 했지만, 서로 받는 자료형이 Int와 Double로 달라서 선언할 수 있다.
공통적으로 필요한 기능을 외부에서 추가해 줄 수 있다.
앞서 보여준 예시에서는 닭과 참새들을 예로 들어 새라는 부모클래스에 난다! 라는 print를 사용했지만 여기에 오리가 들어간다면 오리는 헤엄친다! 라는말이 더 잘어울린다. 하지만 이런 내용은 부모클래스에 넣기에는 부적절하다.
interface WaterBirdBehavior {
fun swim()
}
이렇게 새로운 인터페이스를 만들어서 swim이라고 선언해준 후에,
fun main() {
var chicken = Chicken("닭")
var sparrow = Sparrow("참새")
var duck = Duck("오리")
chicken.fly()
sparrow.fly()
duck.swim()
}
open class Bird(name:String) {
var name: String = ""
init {this.name = name}
fun fly() {
println("${name} 날아요~")
}
}
class Chicken(name: String) : Bird(name) {}
class Sparrow(name: String) : Bird(name) {}
class Duck(name: String) : Bird(name), WaterBirdBehavior {
override fun swim() {
println("${name}가 수영해요~")
}
}
이런식으로 Duck이라는 클래스에 인터페이스를 같이 선언해줌으로써 해당 내용을 사용할 수 있게 된다.
오늘은 새로운 주차가 시작되고, 문법을 집중적으로 공부한 날이다. 문법은 본격적인 앱개발, 혹은 kotlin을 시작하기에 앞서 이해하고 넘어가지 못하면 힘들다고 생각해서 평소보다 더 꼼꼼히, 자세히 공부하였다.
고생하셨어요~👍