왕초보일지

231213 TIL 해시코드출력현상/싱글턴

다시은 2023. 12. 13. 21:01

작업 중 브랜치를 변경할 때 그냥 변경하면 파일이 리셋된다.

git stash

git switch ~~

과정 거칠 것

 

인텔리제이에서 깃과 깃헙 연동은 됐으나

master 브랜치 외에 보이지 않을 경우

git fetch 시도해보기! 

fetch : 로컬과 원격 동기화

pull : 데이터까지 땡겨옴

pull > fetch

 

 

키오스크 기능에 잔액 클래스 추가하기

class Account {

    var balance : Int = 0 //충전 전에도 잔액을 불러올 수 있도록

    //잔액 확인
    fun getBalance():Int {
        return balance
    }

    //결제 시 잔액 차감
    fun deductBalance (c:Int) {
        balance -= c
    }

    //충전 또는 거스름돈 추가
    fun addChange(a : Int) {
        balance += a
    }
    
}

잔액 클래스를 만들고 pay 함수에서 접근하려하니 안된다.

fun pay() {
    println("총 금액은 ${mycart.sumOf { it.price }}원입니다.")
    println("고객님의 카드 잔액은 ${Account().getBalance()}입니다.")
    println("충전할 금액을 입력하십시오")
    var paycash = 0
    var total = mycart.sumBy { it.price }

    //현재 날짜, 시간
    var nowDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"))

    //문자, 공백입력 예외처리
    while (true) {
        try {
            paycash = readLine()!!.toInt()
            var myChange = paycash - total
            Account.addChange(paycash)

Account().addChange(paycash)

에서 매번 새로운 객체를 생성하기 때문

 

이런 때에 싱글턴을 사용

싱글턴은?

  • 인스턴스가 오직 하나 
  • 메모리 전역에서 유일한 객체임을 보장
  • 전역적으로 활용할 수 있어서 다른 클래스들에서 쉽게 접근할 수 있다
  • 객체 자원 간의 충돌 방지 
  • object 키워드가 객체의 구조를 정의하는 동시에 객체를 생성

싱글턴 패턴 클래스로 바꾸었다.

//유일한 객체로 접근하기 위해 싱글턴 활용
object Balance {

    private var balance : Int = 0 //충전 전에도 잔액을 불러올 수 있도록

    //잔액 확인
    fun getBalance():Int {
        return balance
    }

    //결제 시 잔액 차감
    fun deductBalance(c:Int) {
        balance -= c
    }

    //충전 또는 거스름돈 추가
    fun addChange(a : Int) {
        balance += a
    }

}

 

pay()함수 수정

//결제
fun pay() {
    println("총 금액은 ${mycart.sumOf { it.price }}원입니다.")
    println("고객님의 카드 잔액은 ${Balance.getBalance()}입니다.") //잔액 불러오기
    println("충전할 금액을 입력하십시오")
    var paycash = 0
    var total = mycart.sumBy { it.price }

    //현재 날짜, 시간
    var nowDateTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss"))

    //문자, 공백입력 예외처리
    while (true) {
        try {
            paycash = readLine()!!.toInt()
            Balance.addChange(paycash) //잔액 충전
            var myBalance = Balance.getBalance()
            var myChange = myBalance - total

            if (myBalance < total) { //잔액 부족
                println("현재 잔액은 ${myBalance}원으로 ${total - myBalance}원이 부족하여 결제가 불가합니다.")
                pay()
            } else {
                    println("결제가 완료되었습니다:-) ${nowDateTime}")
                    Balance.deductBalance(total) //결제 후 잔액 차감
                    println("고객님의 카드 잔액은 ${Balance.getBalance()}입니다.")
                    main()
                }
            }
        catch (e: NumberFormatException) {
            println("숫자를 입력하세요")
        } catch (e: KotlinNullPointerException) {
            println("숫자를 입력하세요")
        }
    }
}

프로그램을 종료하지 않는 한 싱글턴 패턴 클래스의 객체가 유지돼서 남은 잔액으로 더 주문하거나 추가로 충전할 수 있다.

 

 

 

 

데이터베이스 형식으로 수정

예시에 차례대로 나와있는게 리스트에서 뽑아온게 맞구나 싶다.....

인덱스는 0부터 시작하니 1씩 더해준다

 

문제가 생겼다.

모든 메뉴를 한 곳에 넣으니까 인덱스 번호가 카테고리마다 따로 나오는게 아니라 합쳐져서 나온다

그래서 카테고리별로 따로 인덱스를 매겨주는데 

그냥 변수를 따로 선언해주었다.

fun showDesserts(){
    var dessertindex = 1
    for((index, food) in foods.withIndex()){
        if(food.category == "Dessert")
            println("${dessertindex++} ${food.name} | ${food.price}")
    }
}

메뉴 밑에 따라오는 나머지 선택지의 번호를 어떻게 매기냐

println("${menus.size + 1} 장바구니 확인")
    println("${menus.size + 2} 종료")

그냥 리스트 사이즈에 1,2 씩 더해줬다...선택지가 늘어나야될 사항이 있으면 함수로 관리해줘야겠지만 일단은 저 2개뿐이니

 

난장판이다.....

 

열심히 꼬인 것들을 다 고치고 나니 

커피 음료 디저트 각각의 리스트에서 불러와져야 할게 아무것도 안 나온다. 오류도 안뜬다.

그래서 각 리스트의 사이즈를 출력해봤는데 이것도 정상이다. 도대체 원인이 뭘까?

 

override fun toString(): String {
    return "Food(name='$name', price=$price, category='$category')"
}

food 클래스에 위와 같이 추가했더니

org.example.CoffeeFood@26a1ab54

메뉴가 나오긴 나오는데 알 수 없는 것들과 같이 출력된다. 클래스이름@16진수로_표시된_해시코드 란다.

자바에서 배열을 직접 출력할 때 나오는 현상으로 코틀린도 마찬가지. 배열 객체의 정보를 출력하는 것.

 

자바의 경우     Arrays.toString(arr)

코틀린의 경우 println(arr.contentToString())

 

 

이 값이 아닌 사용자가 원하는 문자열을 출력하도록 만들기 위해서

부모 클래스인 Food 클래스에  toString() 메소드를 넣고 자식 함수에 각각 오버라이딩 시켜주었다.

open class Food () {
   open var name:String = ""
    open var price:Int = 0
    open var category:String = ""

    constructor(name: String, price: Int, category: String):this(){
        this.name = name
        this.price = price
        this.category = category
    }

    open fun displayFoods() {
        println(" $name | $price")
    }

open fun addcart() {
    println("이 메뉴를 장바구니에 추가하시겠습니까? 1. 확인 2. 취소")
}

    //리스트 출력 시 해시코드 값이 나오는 현상 해결
    override fun toString(): String {
        return "$name | $price"
    }
}
class CoffeeFood(_name: String, _price: Int, _category: String) : Food(_name, _price, "Coffee") {

override var name = _name
override var price = _price
override var category = _category

    override fun displayFoods() {
        println(super.toString())
    }