kiosk lv3-추상클래스 구현
kiosk lv2에서는 추상클래스를 구현하지 않았다.
그래서 lv3에서는 추상클래스 Food를 나머지 (Salads, Sandwiches , Wraps) 클래스에서 상속을 받을 수 있도록
설계했다.
먼저 Food.kt을 작성했고,
코드는 아래와 같이 작성했다.
package com.ellycrab.kiosklv3
open class Food(val foodOptions:List<String>,val foodCategory: String) {
//대분류
fun displayOptions(){
println("$foodCategory 카테고리 선택:")
foodOptions.forEachIndexed {
index, value ->
println("${index+1}.$value")
}
}
//세부메뉴
open fun orderItem(choice:Int):String?{
if(choice in 1..foodOptions.size){
return foodOptions[choice-1]
}
return null
}
}
해당 메서드들은
대분류 카테고리를 선택할때 세부메뉴 선택기능도 나오기때문에 저렇게 설계했다.
그 이후 대분류 메뉴 Salads Sandwiches Wraps 클래스를 설계했다.
[Salads.kt]
package com.ellycrab.kiosklv3
class Salads : Food(
listOf("Egg Slice", "Spicy Shrimp", "Spicy Italian", "Steak Cheese", "Chicken Bacon", "KBBQ"),
"Salads"
)
Food클래스를 상속받으면서 동시에 파라미터로 바로 값을 전달했다.
타입은 이미 Food에서 List<String> 타입과 String으로 정의 해놨다.
[Sandwiches.kt]
package com.ellycrab.kiosklv3
class Sandwiches : Food(
listOf("Egg Slice", "Italian BMT", "Chicken Bacon Avocado", "Rotisserie Barbecue", "Shrimp", "Roasted Chicken"),
"Sandwiches"
)
[Wraps.kt]
package com.ellycrab.kiosklv3
class Wraps : Food(
listOf("Steak Wrap", "Egg Mayo", "Chicken Bacon"),
"Wraps"
)
마지막으로 대분류 선택시 세부분류가 나오도록 출력을 담당하는 메서드 [Main.kt]을 아래와 같이 작성했다.
package com.ellycrab.kiosklv3
import java.lang.Exception
fun main(){
val menus:List<Food> = init()
while(true){
println("서브웨이 메뉴:")
println("1. Salads(Egg Slice, Spicy Shrimp, Spicy Italian, Steak Cheese, Chicken Bacon, KBBQ)")
println("2. Sandwiches(Egg Slice, Italian BMT, Chicken Bacon Avocado, Rotisserie Barbecue, Shrimp, Roasted Chicken)")
println("3. Wraps(Steak Wrap, Egg Mayo,Chicken Bacon)")
println("0. 프로그램 종료")
print("서브웨이 메뉴 카테고리를 선택해주세요. (1-3): ")
val categoryChoice = readLine()?.toIntOrNull()
when (categoryChoice) {
in 1..3 -> if (categoryChoice != null) {
orderSebuItem(menus[categoryChoice - 1])
}
0 -> {
println("프로그램을 종료합니다.")
return
}
else -> {
//숫자이외에 다른것을 선택했을때
println("유효하지 않은 카테고리 선택입니다.")
}
}
}
}
fun orderSebuItem(menuCategory: Food) {
menuCategory.displayOptions()
print("세부 메뉴를 선택해주세요. : ")
val itemChoice = readLine()?.toIntOrNull()
val orderedItem = itemChoice?.let {
sebumenuNumber->
menuCategory.orderItem(sebumenuNumber)
}
orderedItem?.let {
println("당신의 주문입니다 => $it")
} ?: println("유효하지 않은 세부 선택입니다.")
}
fun init(): List<Food> {
return listOf(Salads(), Sandwiches(), Wraps())
}
메서드 init을 이용해
일일이 객체를 생성하지 않고 리스트의 형태로 관리했다.
그래서 해당 클래스틀을 List<Food>의 타입으로 변수 menus에 저장한다.
대분류 메뉴판을 보여준 후 세부메뉴 선택 출력문을 띄우고 readLine()으로 받는데,
그것을 categoryChoice 변수에 담아준다.
카테고리가 1~3에 존재하면 대분류 메뉴안에 속하는 범위이고,
그외의것을 입력받는다면 유효하지 않는 카테고리 선택이라고 처리한다.
0을 눌렀을때는 프로그램을 종료한다.
categoryChoice는 1,2,3 중하나를 입력받는데
orderItem() 메서드안에 파라미터로들어간다.
orderItem(menus[categoryChoice - 1])
categoryChoice - 1 => menus에서 인덱스로 표현해야해서 1을 뺐고
만약 categoryChoice가 1이라면
categoryChoice[0] 이되어 Salads 가 선택된다.
그렇게되면 Salads가 orderItem의 매개변수 menuCategory에 담기게된다.
menuCategory.displayOptions()를하면 Salads전체 메뉴가 나오고
세부메뉴를 입력 후 Food 의 orderItem 메서드에 세부메뉴번호를 넘긴다.
그 후 어떤 메뉴를 주문했는지 출력한다.
객체를 리스트로 관리해서 코드양이 줄어드는것 같았다.