abstract class AbstractOperation {
    abstract fun operate(num1: Int, num2: Int): Double}

class Calculator(private val operator: AbstractOperation) {
    fun operate(num1: Int, num2: Int): Double {
        return operator.operate(num1, num2)}}

class AddOperation : AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 + num2).toDouble()}

class SubstractOperation: AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 - num2).toDouble()}

class MultiplyOperation : AbstractOperation() {
    override fun operate(num1: Int, num2: Int): Double = (num1 * num2).toDouble()}

class DivideOperation : AbstractOperation() {
    @Throws(ArithmeticException::class)
    override fun operate(num1: Int, num2: Int): Double {
        require(num2 != 0) {
           ArithmeticException( "Divide by Zero")}
        return (num1 / num2).toDouble()}}

fun main() {
    // 더하기
    val addCalc = Calculator(AddOperation())
    println("10 더하기 20 결과는 : ${addCalc.operate(10, 20)} 입니다")
    // 빼기
    val subCalc = Calculator(SubstractOperation())
    println("10 빼기 20 결과는 : ${subCalc.operate(10, 20)} 입니다")
    // 곱하기
    val mulCalc = Calculator(MultiplyOperation())
    println("10 곱하기 20 결과는 : ${mulCalc.operate(10, 20)} 입니다")
    // 나누기
    val divCalc = Calculator(DivideOperation())
    println("10 나누기 20 결과는 : ${divCalc.operate(10, 20)} 입니다")}