일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- 암호수학
- 시간복잡도
- C
- LoB
- 자료구조
- OSI
- windosws wbcs
- web
- PHP
- HTML
- 두근두근 자료구조
- 미로 탐색 알고리즘
- ftz
- ftz level13
- pwnable.kr
- 파이썬
- System
- 큐
- Stack
- 스택
- 백준
- SWiFT
- level13
- windosw 문자열
- 정렬 알고리즘
- 파일 시스템
- Java
- War Game
- 재귀
- c언어
- Today
- Total
나의 기록, 현진록
[Swift] 객체 지향 프로그래밍 Object-Oriented Programming, OOP 본문
프로그램을 절차적으로 실행되는 명령어의 집합이기 보다 여러 독립적인 부품(객체)들이 유기적인 집합체로 파악하고자 하는 패러다임이다.
객체지향적 설계
- 자동차를 만든다고 할 때 수많은 부품의 결합과 연결로 하나의 완전한 자동차가 만들어지는 것처럼 프로그램의 일부분에 해당하는 부품, 즉 객체를 먼저 만들고 여러 객체들을 조립해서 하나의 완성된 프로그램을 만드는 방법론라고 볼 수 있다.
- 컴퓨터 부품을 갈아끼울 떄 해당하는 부품만 쉽게 교체하고 나머지 부품들은 건들이지 않아도 되는 것처럼 객체 지향적 원리를 잘 적용해둔 프로그램은 각각의 객체들이 독립적인 역할을 가지기 때문에 코드의 변경을 최소화하고 유지보수 하는 데 유리하다.
- 객체 지향적 설계로 인해 프로그램을 보다 유연하고 변경이 용이하도록 만들 수 있다.
객체 지향 프로그래밍은 자동차에 비유했듯 우리가 보고 인지하는 실제 세계를 흉내내어 가장 기본적인 단위, 객체들을 만들고 객체간의 유기적인 상호작용을 규정하여 프로그램을 발전시키는 프로그래밍 방법론으로서 보다 인간친화적이고 직관적인 코드를 작성하는데 용이하다.
객체
- 객체란 객체 지향 프로그래밍의 가장 기본적인 단위이자 시작점이며 모든 실재하는 대상이다.
- 객체 지향 프로그래밍에서 객체는 속성(State)과 기능(Behavior)을 분류한 후에 변수(var)와 함수(func)로 정의할 수 있다.
객체 지향 프로그래밍의 특징 4가지
1. 추상화
- 객체 지향 프로그래밍에서의 추상화는 객체의 공통적인 속성과 기능에 대해서 추출하여 정의하는 것을 말한다.
- 추상화를 통해 공통 특성만을 다루기에 복잡성을 감소시킬 수 있다.
- 추상화된 코드는 변경이 발생할 때 해당 추상화 계층만 수정하면 되므로 유지보수가 용이하다.
- 추상화된 protocol로 다양한 객체들을 생성하고 재사용할 수 있다.
- 서울 지하철 노선도는 서울의 지리를 추상화시켜서 보여주는 좋은 예시이다. 불필요한 세부사항들은 제거하고 가장 본질적이고 공통적인 부분만 추출했기 때문이다.
- 자동차와 오토바이는 모두 이동수단이며 전진과 후진이라는 공통점을 가진다.
protocol Animal {
var name: String { get }
func makeSound()
}
class Dog: Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("\(name): 멍멍!")
}
}
class Cat: Animal {
var name: String
init(name: String) {
self.name = name
}
func makeSound() {
print("\(name): 야옹!")
}
}
let dog: Animal = Dog(name: "바둑이")
let cat: Animal = Cat(name: "나비")
dog.makeSound() // 바둑이: 멍멍!
cat.makeSound() // 나비: 야옹!
강아지와 고양이는 이름과 울음소리라는 공통적인 속성과 기능을 가지고 있다. Animal 프로토콜로 추출하여 추상화할 수 있다. 강아지와 고양이뿐 아니라 Animal 추상화한 특성들에 맞는 다른 동물도 추가하여 확장할 수 있다.
2. 캡슐화
- 객체의 속성과 메서드 등을 외부에서 직접적으로 접근하지 못하도록 보호하는 개념이다.
- 접근제어자를 사용하여 데이터를 은닉, 내부 데이터에 직접적인 접근을 못하도록 하여 데이터의 무결성을 보장한다.
- 외부에서는 객체의 공개된 메서드를 통해서 데이터를 접근할 수 있어 데이터를 안정적으로 관리할 수 있다.
class BankAccount {
private var balance: Double
init(initialBalance: Double) {
self.balance = initialBalance
}
func deposit(amount: Double) {
balance += amount
print("₩\(amount) 입금 완료. 현재 잔액: ₩\(balance)")
}
func withdraw(amount: Double) {
guard balance >= amount else {
print("잔액 부족! 현재 잔액: ₩\(balance)")
return
}
balance -= amount
print("₩\(amount) 출금 완료. 현재 잔액: ₩\(balance)")
}
func getBalance() -> Double {
return balance
}
}
let myAccount = BankAccount(initialBalance: 10000)
myAccount.deposit(amount: 5000) // ₩5000 입금 완료. 현재 잔액: ₩15000
myAccount.withdraw(amount: 2000) // ₩2000 출금 완료. 현재 잔액: ₩13000
// 직접 접근 불가 (에러 발생)
// myAccount.balance = 100000
balance 속성을 private으로 설정하여 외부에서 직접 변경할 수 없도록 보호한다.
deposit(), withDraw() 메서드를 통해서만 잔액을 조작할 수 있도록 한다.
3. 상속
- 이미 존재하는 클래스의 속성과 메서드를 물려받아 새로운 클래스를 정의한다. 부모-자식 관계로서 클래스를 확장하거나 변경할 수 있다.
- 부모 클래스의 코드를 재사용하여 코드 중복을 줄일 수 있다.
- 자식 클래스는 부모 클래스의 기능을 확장하거나 추가적인 기능을 정의할 수 있다.
- 클래스 간의 계층적 구조가 형성되어 코드의 구조를 보다 명확하게 이해할 수 있다.
class Person {
var name: String
init(name: String) {
self.name = name
}
func introduce() {
print("안녕하세요, 저는 \(name)입니다.")
}
}
class Student: Person {
var studentID: String
init(name: String, studentID: String) {
self.studentID = studentID
super.init(name: name) // 부모 클래스의 초기화 호출
}
override func introduce() {
print("안녕하세요, 저는 학생 \(name)이고 학번은 \(studentID)입니다.")
}
}
let person = Person(name: "김철수")
let student = Student(name: "이영희", studentID: "20241234")
person.introduce() // 안녕하세요, 저는 김철수입니다.
student.introduce() // 안녕하세요, 저는 학생 이영희이고 학번은 20241234입니다.
Student는 어차피 Person이기 때문에 Student가 Person을 상속하여 Person을 재사용할 수 있다. Student 클래스는 필요한 속성을 추가하여 확장시킨다.
4. 다형성
다형성은 다양한 클래스들이 같은 메서드나 인터페이스를 가진 객체들이 다양한 방식으로 동작할 수 있는 것을 말한다. 프로토콜과 상속을 이용하여 다형성을 구현할 수 있다.
- 새로운 클래스를 추가하거나 기존 클래스를 수정하지 않고도 코드를 확장하거나 변경할 수 있어 확장에 유연하다.
- 변경 사항을 최소화하여 기능을 수정하거나 추가할 수 있어 유지보수에 용이하다.
class Vehicle {
func move() {
print("탈것이 이동합니다.")
}
}
class Car: Vehicle {
override func move() {
print("자동차가 도로를 달립니다.")
}
}
class Airplane: Vehicle {
override func move() {
print("비행기가 하늘을 납니다.")
}
}
let vehicles: [Vehicle] = [Car(), Airplane()]
for vehicle in vehicles {
vehicle.move()
}
- Vehicle 클래스는 기본 move() 메서드를 가지고 Car와 Airplane은 move()를 오버라이딩하여 다른 동작을 수행한다.
'Programming > Swift' 카테고리의 다른 글
[Swift] 강한 참조 사이클(클로저) (0) | 2025.02.07 |
---|---|
[Swift] ARC(Automatic Reference Counting) (1) | 2025.02.06 |
[Swift] Struct와 Class의 특징 (0) | 2025.02.05 |
[Swift] 15.2 필터 (0) | 2021.09.14 |
[Swift] 15.1 맵 (0) | 2021.09.14 |