Swift에 대해서 개인적으로 공부하고 기록한 포스팅입니다.
구조체를 활용한 상속?
중복된 속성이 존재할 때,
- 객체 지향 설계에서는 중복된 속성을 부모 클래스를 통해 캡슐화가 가능합니다.
- 스위프트에서 상속을 사용하기 위해서는 구조체가 아닌 클래스를 이용해야 합니다. (Call by Ref)
아래와 같이 상속을 위해서는 구조체를 활용할 수 없습니다.
struct User {
let email: String
let password: String
let joinDate: Date
var level: Int
var exp: Int
}
struct Admin {
let email: String
let password: String
let joinDate: Date
var logs: [String]
}
클래스를 활용한 상속
클래스의 특징
- 구조체와 다르게 멤버 초기화 메서드가 자동으로 제공되지 않습니다.
- 사용자는 프로퍼티의 초기값을 지정하거나, 초기화 메서드를 통해 초기화를 수행 해주어야 합니다.
class Account {
let email: String
let password: String
let joinDate: Date
init(email: String, password: String, joinDate: Date) {
self.email = email
self.password = password
self.joinDate = joinDate
}
}
위 클래스를 상속받은 User Class를 만들고자 할 때는 아래와 같이 상속합니다.
[중요]
초기화 메서드를 작성할 때는 자신의 속성을 먼저 초기화하고, 부모의 지정 초기화 메서드를 통해 초기화를 진행해야 합니다.
class User: Account {
var level: Int
var exp: Int
init(email: String, password: String, joinDate: Date, level: Int, exp: Int) {
self.level = level
self.exp = exp
// 자신의 속성을 먼저 초기화 하고, 부모 지정 초기화 메서드를 통해서 초기화를 진행합니다.
super.init(email: email, password: password: joinDate: joinDate)
}
}
함수 오버로딩 (다형성)
class Account {
{ ... 중략 ... }
func display() {
print("Account Display")
}
}
class User: Account {
{ ... 중략 ... }
override func display() {
print("Account Display")
}
}
class Admin: Account {
{ ... 중략 ... }
override func display() {
print("Admin Display")
}
}
let arr: [Account] = [
User(...),
Admin(...),
]
for e in arr {
e.display()
}
// 출력 : "Account Display"
// 출력 : "Admin Display"
클래스를 활용한 상속의 문제점
경직된 설계
새로운 Account 기반 타입을 도입할 때, 기존에 설계한 구조와 다를 경우 전체적인 구조를 변경해야 하는 어려움이 있습니다.
만약 Account 가 가져야 하는 값들이 Guest 대응을 위해서 email, psssword가 필요 없는 경우는 어떻게 해야할까요?
Account 에 대한 설계를 모두 뜯어 고치는 상황이 생길 것입니다.
클래스 사용
상속을 이용하기 위해서는 참조 타입인 Class를 사용해야 합니다.
Struct를 활용할 수 있다면 Class보다 활용하는 것이 더욱 효율적일 수도 있습니다. Class는 Reference Type으로 메모리 관리를 해주어야 하기 때문입니다.
Enum을 사용해 Class를 활용한 상속에 대한 문제점을 어느정도 해결할 수 있다.
Enum을 활용한 상속
장점
- 새로운 유형을 추가할 때, 기존 코드 구조적인 변경이 필요하지 않습니다.
- 구조체를 활용할 수 있습니다.
단점
- Enum을 사용하면 중복된 항목을 별도로 캡슐화하는 것이 어렵습니다.
- 다형성을 구현하기 위해서는 직접 분기 코드를 작성해야 합니다.
표현 방법
struct User {
let email: String
let password: String
let joinDate: String
var level: Int
var exp: Int
}
struct Admin {
let email: String
let password: String
let joinDate: Date
var logs: [String]
}
enum Account {
case user(User)
case admin(Admin)
}
let arr: [Account] = [
.user(User(email: "a@abc.com", password: "123", joinDate: Date(), level: 1, exp: 0)),
.admin(Admin(email: "aa@abc.com", password: "123", joinDate: Date(), logs: []))
]
함수 오버로딩 (다형성)
Enum으로 상속의 관계를 흉내냈을 경우에 Class를 활용한 상속의 다형성으로 함수 오버로딩을 하고자 할 때는 어떻게 할 수 있을까?
Switch-case를 활용하면 됩니다.
enum Account {
case user(User)
case admin(Admin)
func display() {
switch self {
case let .user(user):
print("User Display - \(user)")
case let .admin(admin):
print("Admin Display - \(admin)")
}
}
}
let arr: [Account] = [
.user(User(email: "a@abc.com", password: "123", joinDate: Date(), level: 1, exp: 0)),
.admin(Admin(email: "aa@abc.com", password: "123", joinDate: Date(), logs: []))
]
for e in arr {
e.display()
}
반응형
'iOS > Swift' 카테고리의 다른 글
[Swift] 프로퍼티(Property) (0) | 2022.12.26 |
---|---|
[Swift] Enum2 (0) | 2022.12.26 |
[Swift] Tuple (0) | 2022.12.26 |
[Swift] Enum (0) | 2022.12.26 |
[Swift] 문자열 (String) (0) | 2022.12.26 |