20231207 (목) Kotlin 5주차 강의
2023. 12. 7. 21:03ㆍTIL
코틀린 심화단계 강의
1.<유용한 기능>
우선 이문단은 상당히 길어질것으로 예상
자료형의 변환
일반 자료형
예시코드)
var num1 = 20 //정수만 표시하는 Int 상태
var num2 = 30.2 //소수까지 표현된 Double 상태
var num3 = num2.toInt() //num2에 해당하는값을 Int로 바꾼다. 예상 결과 30
var num4 = num1.toDouble() //num1에 해당하는 값을 Double로 바꾼다. 예상 결과 20.0
var strNum5 = "10" //Num5와 6은 String 형태이다.
var strNum6 = "10.21"
var num5 = Integer.parseInt(strNum5) //Num5를 Int로 바꾼다.
var num6 = strNum6.toDouble() //Num6를 Double로 바꾼다.
println("num3: $num3")
println("num4: $num4")
println("num5: $num5")
println("num6: $num6")
num3: 30
num4: 20.0
num5: 10
num6: 10.21
객체 자료형
이는 특이하게 서로 상속 된 관계에서만 가능하다.
자식에서 부모는 업캐스팅 / 부모에서 자식은 다운캐스팅이라 하며 서로 비슷한듯 하면서 다르다.
예시코드)
업캐스팅
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt() //여기에 적는 숫자는 List의 자료 갯수가 된다.
var birds = mutableListOf<Bird>()
for(idx in 0..count-1) { //List는 0부터 시작하기 때문에 적은 숫자에 -1을 하는모습.
println("조류의 이름을 입력해주세요")
var name = readLine()!! //List에 들어갈 새이름을 추가
// as Bird는 생략가능
birds.add(Sparrow(name) as Bird) //이는 이해를 돕기위해 as Bird를 추가함
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) { //위에서 입력한 이름이 여기에 추가된다
}
다운캐스팅
fun main() {
println("몇 마리를 생성하시겠습니까?")
var count = readLine()!!.toInt()
var birds = mutableListOf<Bird>()
for(idx in 0..count-1) {
println("조류의 이름을 입력해주세요")
var name = readLine()!!
birds.add(Sparrow(name) as Bird)
}
println("============조류 생성완료============")
for(bird in birds) {
bird.fly()
}
// 다운캐스팅 오류
// Sparrow는 Bird가 가져야할 정보를 모두 가지고 있지 않기 때문임
// var s1:Sparrow = birds.get(0) 위와 완전히 똑같지만 이부분만 다름
}
open class Bird(name: String) {
var name: String
init {
this.name = name
}
fun fly() {
println("${name}이름의 조류가 날아요~")
}
}
class Sparrow(name: String): Bird(name) {
}
다운캐스팅은 이렇듯 자식클래스가 부모클래스의 내용을 모두 갖고있지않아서 변환하기가 힘들다.
코틀린은 is 키워드를 활용해서 자료형의 타입을 확인가능하다
if(name is String) { //name is String 명령어로 String인지 아닌지 확인
println("name은 String 타입입니다")
} else {
println("name은 String 타입이 아닙니다")
}
또 복수의 데이터를 리턴할수가 있는데
두개이상의 데이터를 포함하는 데이터클래스를 설계하고 리턴하면 된다.
두개에는 Pair 세개에는 Triple을 쓸 수 있다.
fun main() {
var chicken = Chicken()
var eggs = chicken.getThreeEggs()
var listEggs = eggs.toList()
// first, second, third로 관리
// var firstEgg = eggs.first
// var secondEgg = eggs.second
// var eggTime = eggs.third 이는 list를 표시하는 방법중 하나
// 리스트로 관리
var firstEgg = listEggs[0]
var secondEgg = listEggs[1]
var eggTime = listEggs[2]
println("달걀의 정보는 ${eggs} 입니다.") //eggs에 대항하는 값을 가져오기때문에 ()형식으로 나온다.
println("리스트 달걀의 정보는 ${listEggs} 입니다.") //list를 불러오기때문에 [] 형식으로 나온다
println("첫번째 달걀의 종류는 ${firstEgg} 입니다.")
println("두번째 달걀의 종류는 ${secondEgg} 입니다.")
println("달걀은 ${eggTime}에 나왔습니다.") //Pair로는 불러올수없는 내용
}
class Chicken {
fun getTwoEggs(): Pair<String, String> { //Pair를 적용함. 여기부터
var eggs = Pair("달걀", "맥반석")
return eggs
} //여기까진 없어도 되지만 Pair에 대한 설명때문에 남겨둠
fun getThreeEggs(): Triple<String, String, Int> { //Triple을 적용함
var eggs = Triple("달걀", "맥반석", 20230101) //3번째로 20230101을 추가해준 모습
return eggs
}
}
클래스를 여러개로 구분해도 되지만, 매번 그렇게 설계하면 비효율적이다.
이후에도 5주차 강의목록이 많이 남아있지만
일단은 계산기 만들기에 몰두하였다.
그렇게 하여서 만든 계산기
lv1 조건문을 써서 만든 간단한 계산기
fun main() {
println("첫번째 숫자를 입력하시오")
var num1 = readln().toDouble()
println("사용할 기호를 입력하시오 예) +, -, *, /")
var op = readln()
println("두번째 숫자를 입력하시오")
var num2 = readln().toDouble()
var calc = Calculator(num1 , op, num2)
calc.operation()
}
class Calculator(num1: Double, op:String, num2: Double) {
var num1:Double = num1
var op:String = op
var num2:Double = num2
init {
}
fun operation() {
println("계산 진행 중!")
if (op == "+") {
println("${num1} ${op} ${num2} = ${num1+num2}")
}
else if(op == "-" ) {
println("${num1} ${op} ${num2} = ${num1-num2}")
}
else if(op == "*" ) {
println("${num1} ${op} ${num2} = ${num1*num2}")
}
else if(op == "/" ){
println("${num1} ${op} ${num2} = ${num1/num2}")
lv2 클래스를 활용하기 시작한 단계
fun main() {
println("첫번째 숫자를 입력하시오")
var num1 = readln().toDouble()
println("사용할 기호를 입력하시오 예) +, -, *, /")
var op = readln()
println("두번째 숫자를 입력하시오")
var num2 = readln().toDouble()
var calc = Calculator2ver2 (num1 , op, num2)
calc.operation()
}
class Calculator2ver2 (num1: Double, op:String, num2: Double) {
var num1 = num1
var op = op
var num2 = num2
init {
}
fun operation() {
println("계산 진행 중!")
when(op) {
"+" -> {
println("${num1} ${op} ${num2} = ${num1+num2}")
}
"-" -> {
println("${num1} ${op} ${num2} = ${num1-num2}")
}
"*" -> {
println("${num1} ${op} ${num2} = ${num1*num2}")
}
"/" -> {
println("${num1} ${op} ${num2} = ${num1/num2}")
}
"%" -> {
println("${num1} ${op} ${num2} = ${num1%num2}")
}
}
}
}
lv3 클래스를 여러개 만들어서 서로간의 관계를 구축한 단계
fun main() {
// 처음에 숫자 2개와 사칙연산 기호 입력
println("첫번째 숫자를 입력해주세요")
var num1 = readln().toDouble()
println("사용할 기호를 입력해주세요 예) +, -, *, /")
var op = readln()
println("두번째 숫자를 입력해주세요")
var num2 = readln().toDouble()
var c = Calc3() // a는 Calc3 클래스를 명시함
// +, -, *, / 중 어떤 기호를 입력했는지에 따라 어느 메소드를 사용할것인지 나눔
while (true){
if (op == "+") { //만약 op가 +라면 ~~
println("${num1} 더하기 ${num2} 결과는 ${c.add(num1, num2)}입니다.")
break
}
if (op == "-") { //만약 op가 +라면 ~~
println("${num1} 빼기 ${num2} 결과는 ${c.sub(num1, num2)}입니다.")
break
}
if (op == "*") { //만약 op가 +라면 ~~
println("${num1} 곱하기 ${num2} 결과는 ${c.mul(num1, num2)}입니다.")
break
}
if (op == "/") { //만약 op가 +라면 ~~
println("${num1} 나누기 ${num2} 결과는 ${c.div(num1, num2)}입니다.")
break
}
else {
println("기호를 다시 입력해주세요")
op = readln()
continue
}
}
}
class Calc3{
fun add(num1:Double,num2:Double): Double {
var a = AddOp2()
return a.operate(num1,num2)
}
fun sub(num1:Double,num2:Double): Double {
var s = SubOp2()
return s.operate(num1,num2)
}
fun mul(num1:Double,num2:Double): Double {
var m = MulOp2()
return m.operate(num1,num2)
}
fun div(num1:Double,num2:Double): Double {
var d = DivOp2()
return d.operate(num1,num2)
}
}
class AddOp2 {
fun operate(num1: Double, num2: Double): Double = (num1 + num2).toDouble()
}
class SubOp2 {
fun operate(num1: Double, num2: Double): Double = (num1 - num2).toDouble()
}
class MulOp2 {
fun operate(num1: Double, num2: Double): Double = (num1 * num2).toDouble()
}
class DivOp2 {
fun operate(num1: Double, num2: Double): Double = (num1 / num2).toDouble()
}
lv4 추상 클래스를 활용하여 하위 클래스들을 하나로 묶고 다형성을 구축한 단계
fun main() {
// 처음에 숫자 2개와 사칙연산 기호 입력
println("첫번째 숫자를 입력해주세요")
var num1 = readln().toDouble()
println("사용할 기호를 입력해주세요 예) +, -, *, /")
var op = readln()
println("두번째 숫자를 입력해주세요")
var num2 = readln().toDouble()
var a = Calculator4() // a는 Calculator4 클래스를 명시함
// +, -, *, / 중 어떤 기호를 입력했는지에 따라 어느 메소드를 사용할것인지 나눔
while (true){
if (op == "+") { //만약 op가 +라면 ~~
a.operateC(AddOperation2(),num1,num2) //Calculator4의 AddOperation2()를 실행하고 num1 num2를 넣어줌)
break
}
if (op == "-") {
a.operateC(SubstractOperation2(),num1,num2)
break
}
if (op == "*") {
a.operateC(MultiplyOperation2(),num1,num2)
break
}
if (op == "/") {
a.operateC(DivideOperation2(),num1,num2)
break
}
else {
println("기호를 다시 입력해주세요")
op = readln()
continue
}
}
}
class Calculator4{
fun operateC(operation: AbstractOperation, num1: Double, num2: Double) {
//15줄에서 AddOperation2가 실행가능했던 이유가 operateC는 AbstractOperation를 포함하고있기때문
operation.operate(num1,num2) //윗줄과 아랫줄 모두 오퍼레이션이 들어감
}
}
abstract class AbstractOperation { //추상클래스
abstract fun operate(num1: Double, num2: Double)//아래 AddOperation2 와 공통되는 부분만 메소드에 표시해놓았다.
}
class AddOperation2 : AbstractOperation() { //AddOperation2는 AbstractOperation를 상속받고있음
override fun operate(num1: Double, num2: Double) { //내가 기호로 +를 입력했다면 아래의 문구가 출력된다
println("${num1} 더하기 ${num2} 결과는 ${num1 + num2} 입니다.")
}
}
class SubstractOperation2 : AbstractOperation() { //AbstractOperation를 상속받고있음
override fun operate(num1: Double, num2: Double) { //내가 기호로 -를 입력했다면 아래의 문구가 출력된다
println("${num1} 빼기 ${num2} 결과는 ${num1 - num2} 입니다.")
}
}
class MultiplyOperation2 : AbstractOperation() { //AbstractOperation를 상속받고있음
override fun operate(num1: Double, num2: Double) { //내가 기호로 *를 입력했다면 아래의 문구가 출력된다
println("${num1} 곱하기 ${num2} 결과는 ${num1 * num2} 입니다.")
}
}
class DivideOperation2 : AbstractOperation() { //AbstractOperation를 상속받고있음
override fun operate(num1: Double, num2: Double) { //내가 기호로 /를 입력했다면 아래의 문구가 출력된다
println("${num1} 나누기 ${num2} 결과는 ${num1 / num2} 입니다.")
}
}
일단 기록으로 남겨둔다.
오늘의 한마디 : 내일은 호텔 예약 프로그램좀 만져보도록 하자
'TIL' 카테고리의 다른 글
20231211 (월) 코틀린 키오스크 만들기 및 깃 특강 (0) | 2023.12.11 |
---|---|
20231208 (금) 금주 회고 (0) | 2023.12.08 |
20231206 (수) Kotlin 4주차 강의 (0) | 2023.12.06 |
20231205 (화) Kotlin 3주차강의 (1) | 2023.12.05 |
20231204 (월) Kotlin 1~2주차 강의 (0) | 2023.12.04 |