오늘도 9시가 넘어서야 TIL을 작성하구 있네요..!
너무 집중이 안되서 커피 수혈을 조금 했는데..
심장이 쿵! 쾅! 쿵! 쾅! 과다 카페인 섭취를 한 거 같아요..
몸이 아주 무리데스네
그렇게 오늘 저녁은 패스입니다요..
과제를 풀다가 다운 캐스팅을 사용해서 기깔나게 마무리하려고 했는데.. 반복적으로 생기는 오류!
대체 뭐가 문제인지 모르겠어서 구글링을 거쳐서 다운 캐스팅과 업 캐스팅부터 다시 공부합니다.
두 단어 모두 클래스의 상속과 관련된 용어로 부모클래스와 자식클래스 사이의 타입 변환을 위해 사용됩니다.
업캐스팅이란?
하위 클래스의 인스턴스를 상위 클래스 타입으로 변환하는 것
다운캐스팅이란?
상위 클래스의 인스턴스를 하위 클래스 타입으로 변환하는 것
다운캐스팅은 항상 안전하게 진행될 수 없기 때문에 오류가 생길 수도 있습니다. 옵셔널 바인딩을 하는 것과 같이 캐스팅하는 방법이 두 가지 존재합니다.
제가 에러가 난 부분을 다시 확인해보니 저는 강제 다운 캐스트를 진행을 했는데 런타임 시점에서 성공하지 못해서 에러가 났습니다.
클래스 선언부
class AbstractOperation {
func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return 0.0
}
}
class AddOperation4: AbstractOperation {
override func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return Double(firstNumber + secondNumber)
}
}
class SubtractOperation4: AbstractOperation {
override func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return Double(firstNumber - secondNumber)
}
}
class MultiplyOperation4: AbstractOperation {
override func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return Double(firstNumber * secondNumber)
}
}
class DivideOperation4: AbstractOperation {
override func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return Double(firstNumber) / Double(secondNumber)
}
}
class ModulusOperation4: AbstractOperation {
override func calculate(_ firstNumber: Int ,_ secondNumber: Int) -> Double {
return Double(firstNumber % secondNumber)
}
}
다운캐스팅하여 위의 클래스의 인스턴스를 활용하려는 클래스
class Calculator4 {
var firstNumber: Int = 0
var secondNumber: Int = 0
var op: Character?
init(firstNumber: Int, secondNumber: Int, op: Character? = nil) {
self.firstNumber = firstNumber
self.secondNumber = secondNumber
self.op = op
}
func calculate() -> Double {
var operation = AbstractOperation()
// 🚨Error
if op == "+" { operation as! AddOperation4 }
else if op == "-" { operation as! SubtractOperation4 }
else if op == "/" { operation as! DivideOperation4 }
else if op == "*" { operation as! MultiplyOperation4 }
else if op == "%" { operation as! ModulusOperation4 }
else { return 0.0 }
return operation.calculate(firstNumber, secondNumber)
}
}
Calculator4의 인스턴스를 만들어 해당 메서드를 이용해 값 출력
let calculator4 = Calculator4(firstNumber: 30, secondNumber: 6, op: "+")
let addResult = calculator4.calculate()
print("addResult : \(addResult)")
위의 코드는 addResult에서 " error: execution was interrupted, reason: signal sigabrt. the process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation. " 이런 에러가 나더라구요. 강제 다운 캐스팅에 실패했을 때 뜨는 에러라고 합니다.
우선 업캐스팅과 다운캐스팅을 공부하고 다시 봤더니 제가 난 오류는 단순히 다운 캐스팅때문에 난 오류가 아니더라구요.. 개념적으로 풀 수 없는 방법으로 풀려고 시도했더니 안되지..
그래도 혹시나 혹시나 가능할 수도 있으니 내일 튜텨님께 질문을 꼭 해봐야겠어요!
Calculator4의 calculate() 메서드를 이렇게 고쳤더니 해결이 되었습니다!
func calculate() -> Double {
// 🚨Error
// var operation = AbstractOperation()
// if op == "+" { operation as! AddOperation4 }
// else if op == "-" { operation as! SubtractOperation4 }
// else if op == "/" { operation as! DivideOperation4 }
// else if op == "*" { operation as! MultiplyOperation4 }
// else if op == "%" { operation as! ModulusOperation4 }
// else { return 0.0 }
guard let op = op else { return 0.0 }
switch op {
case "+" :
return AddOperation4().calculate(firstNumber, secondNumber)
case "-" :
return SubtractOperation4().calculate(firstNumber, secondNumber)
case "/" :
return DivideOperation4().calculate(firstNumber, secondNumber)
case "*" :
return MultiplyOperation4().calculate(firstNumber, secondNumber)
case "%" :
return ModulusOperation4().calculate(firstNumber, secondNumber)
default :
print("계산기에 존재하지 않는 연산자입니다.")
return 0.0
}
}
[ 내일 해결해야 할 문제 ]
❎ 한가지의 변수에 부모 클래스의 인스턴스를 대입하고, 그 변수를 자식 클래스로 다운캐스팅하여 메서드를 사용하려고 할 때, 경우에 따라 다른 다운 캐스팅을 하여 진행하면 안되는지.. 안된다면 왜 안되는지..!!!!