- [ ] AbstractOperation라는 추상화된 클래스를 만들기
- [ ] 기존에 구현한 AddOperation(더하기), SubtractOperation(빼기), MultiplyOperation(곱하기),
DivideOperation(나누기) 클래스들과 관계를 맺고 Calculator 클래스의 내부 코드를 변경
- [ ] 스위프트의 어떤 문법을 이용하여 추상화할 수 있을지 생각해 봅시다
- Lv3 와 비교해서 어떠한 점이 개선 되었는지 스스로 생각해 봅니다.
- hint. 클래스간의 결합도, 의존성(의존성역전원칙)
import Foundation
// Calculator 클래스
class Calculator {
func calculate(operation: Abstractoperation, firstNumber: Double, secondNumber: Double) -> Double {
return operation.operate(firstNumber: firstNumber, secondNumber: secondNumber)
}
}
// Abstractoperation 클래스
class Abstractoperation {
func operate(firstNumber: Double, secondNumber: Double ) -> Double {
return 0.0
}
}
// 덧셈 (상속 - 부모클래스의 프로퍼티, 함수/메서드를 자식클래스에서 동일하게 사용가능)
class AddOperation: Abstractoperation {
override func operate(firstNumber: Double, secondNumber: Double) -> Double {
return firstNumber + secondNumber
}
}
// 뺄셈
class SubtractOperation: Abstractoperation {
override func operate(firstNumber: Double, secondNumber: Double) -> Double {
return firstNumber - secondNumber
}
}
// 곱셈
class MultiplyOperation: Abstractoperation {
override func operate(firstNumber: Double, secondNumber: Double) -> Double {
return firstNumber * secondNumber
}
}
// 나누기
class DivideOperation: Abstractoperation {
override func operate(firstNumber: Double, secondNumber: Double) -> Double {
if secondNumber != 0 {
return firstNumber / secondNumber
} else {
//0으로 나눌 경우 "경고 : 0으로 나누었습니다"가 출력되도록
print("Error: Division by zero")
return 0.0
}
}
}
let calculator = Calculator()
//입력값 String을 Double로 형변환해서 사용
let input = readLine()!
let input2 = readLine()!
var firstNumber : Double = 0
var secondNumber : Double = 0
if let number = Double(input) {
firstNumber = number
}
if let number = Double(input2) {
secondNumber = number
}
//연산의 결과값 출력 함수
let addResult = calculator.calculate(operation: AddOperation(), firstNumber: firstNumber, secondNumber: secondNumber)
let subResult = calculator.calculate(operation: SubtractOperation(), firstNumber: firstNumber, secondNumber: secondNumber)
let multiplyResult = calculator.calculate(operation: MultiplyOperation(), firstNumber: firstNumber, secondNumber: secondNumber)
let devideResult = calculator.calculate(operation: DivideOperation(), firstNumber: firstNumber, secondNumber: secondNumber)
// 소숫점 두자리까지 출력하는 함수
let str = String(format: "%.2f", devideResult)
//연산의 결과값 출력
print(addResult)
print(subResult)
print(multiplyResult)
print(str)
let intValue = 123
let stringValue = String(intValue)
print("정수를 문자열로 변환한 값: \(stringValue)")
let doubleValue = 3.14
let stringValue = "\(doubleValue)"
print("실수를 문자열로 변환한 값: \(stringValue)")
//int type
let stringValue = "123"
if let intValue = Int(stringValue) {
print("문자열을 정수로 변환한 값: \(intValue)")
}
// double type
let doubleValue = Double(stringValue)
if let doubleResult = doubleValue {
print("문자열을 실수로 변환한 값: \(doubleResult)")
}
let stringValue = "123"
let intValue = Int(stringValue)!
print("강제 변환된 정수 값: \(intValue)")
var string: String = ""
// Double 타입을 문자열로 변환 (정확하게는 타입을 변환하는게 아니고, 생성자를 이용해서 새롭게 생성하는 것)
string = String(3.1415926)
//print(string)
string = "원하는 숫자는 " + String(format: "%.3f", pi) // 반올림
//print(string)
string = "원하는 숫자는 " + String(format: "%.2f", pi)
//print(string)
string = String(format: "원하는 숫자는 %.2f", pi) // %.2f 자리에 pi를 대체
//print(string)
/* Format Specifiers 종류 */
string = String(format: "%d", 7) // %d, %D ===> 정수
print(string)
string = String(format: "%2d", 7) // 두자리로 표현
print(string)
string = String(format: "%02d", 7) // 두자리로 표현하되, 0포함
print(string)
string = String(format: "%07.3f", pi) // 일곱자리로 표현하되 0과 .(dot) 포함, (소수점아래는 3자리)
print(string)
var swift = "Swift"
string = String(format: "Hello, %@", swift) // %@ ===> 문자열
print(string)
/* 활용 */
var firstName = "Gildong"
var lastName = "Hong"
var korean = "사용자의 이름은 %2$@ %1$@ 입니다." // 1$ 첫번째 파라미터, 2$ 두번째 파라미터
var english = "The username is %1$@ %2$@."
string = String(format: korean, firstName, lastName)
print(string)
string = String(format: english, firstName, lastName)
print(string)
숫자 <-> 문자 변환을 다루는 클래스
반올림모드(roundingMode), 최대자릿수, 최소자릿수, 숫자스타일 등등
// 소수점 버리기
let numberFormatter = NumberFormatter()
numberFormatter.roundingMode = .floor // 버림으로 지정
numberFormatter.maximumSignificantDigits = 3 // 최대 표현하길 원하는 자릿수
let value = 3.1415926
var valueFormatted = numberFormatter.string(for: value)! // 문자열화시키는 메서드
print(valueFormatted) // 3.14
// 소수점 필수적 표현하기
numberFormatter.roundingMode = .floor // 버림으로 지정
numberFormatter.minimumSignificantDigits = 4 // 최소 표현하길 원하는 자릿수
let value2 = 3.1
valueFormatted = numberFormatter.string(for: value2)! // 문자열화시키는 메서드
print(valueFormatted) // 3.100
// 세자리수마다 콤마 넣기
numberFormatter.numberStyle = .decimal // 10진수로 표현하는 방식
let price = 10000000
let result = numberFormatter.string(for: price)!
print(result) // "10,000,000"
class Animal {
func makeSound() {
print("소리")
}
}
class Dog: Animal {
override func makeSound() {
print("멍멍!")
}
}
let myPet = Dog()
myPet.makeSound() // 출력: 멍멍!
Animal 클래스 = 부모 클래스
Dog 클래스 = 자식 클래스
Animal 클래스는 makeSound()라는 메서드를 가지고 있음.
이 메서드는 "알 수 없는 소리"를 출력함.
그런데 Dog 클래스는 Animal 클래스를 상속받았기 때문에
Dog 클래스에도 makeSound() 메서드가 존재합니다.
Dog 클래스에서는 makeSound() 메서드를 재정의(override)하여 "멍멍!"을 출력하도록 변경했습니다.