📱 모바일 프로그래밍/iOS 프로그래밍 기초
iOS 프로그래밍 6주차
SA성아
2024. 10. 16. 16:47
클래스(class)
클래스 vs. 객체 vs. 인스턴스

객체지향 용어 비교

클래스 vs. 인스턴스(객체)
각 언어별 클래스 생성 및 객체 생성
1. Swift
// 클래스 정의
class Car {
var brand: String
var year: Int
// 생성자 (Initializer)
init(brand: String, year: Int) {
self.brand = brand
self.year = year
}
// 메서드
func drive() {
print("\(brand) 자동차가 운전 중입니다.")
}
}
// 객체 생성
let myCar = Car(brand: "Tesla", year: 2020)
myCar.drive() // 출력: Tesla 자동차가 운전 중입니다.
2. Java
// 클래스 정의
public class Car {
private String brand;
private int year;
// 생성자
public Car(String brand, int year) {
this.brand = brand;
this.year = year;
}
// 메서드
public void drive() {
System.out.println(brand + " 자동차가 운전 중입니다.");
}
// Getter와 Setter (옵션)
public String getBrand() {
return brand;
}
public int getYear() {
return year;
}
}
// 객체 생성
public class Main {
public static void main(String[] args) {
Car myCar = new Car("Hyundai", 2021);
myCar.drive(); // 출력: Hyundai 자동차가 운전 중입니다.
}
}
3. C#
// 클래스 정의
public class Car {
public string Brand { get; set; }
public int Year { get; set; }
// 생성자
public Car(string brand, int year) {
Brand = brand;
Year = year;
}
// 메서드
public void Drive() {
Console.WriteLine($"{Brand} 자동차가 운전 중입니다.");
}
}
// 객체 생성
class Program {
static void Main(string[] args) {
Car myCar = new Car("BMW", 2019);
myCar.Drive(); // 출력: BMW 자동차가 운전 중입니다.
}
}
4. JavaScript
// 클래스 정의
class Car {
constructor(brand, year) {
this.brand = brand;
this.year = year;
}
// 메서드
drive() {
console.log(`${this.brand} 자동차가 운전 중입니다.`);
}
}
// 객체 생성
const myCar = new Car("Audi", 2022);
myCar.drive(); // 출력: Audi 자동차가 운전 중입니다.
5. Python
# 클래스 정의
class Car:
def __init__(self, brand, year):
self.brand = brand
self.year = year
# 메서드
def drive(self):
print(f"{self.brand} 자동차가 운전 중입니다.")
# 객체 생성
my_car = Car("Toyota", 2023)
my_car.drive() # 출력: Toyota 자동차가 운전 중입니다.
각 언어별 상속을 구현하는 방법
1. Swift
// 기본 클래스
class Car {
var brand: String
var year: Int
init(brand: String, year: Int) {
self.brand = brand
self.year = year
}
func drive() {
print("\(brand) 자동차가 운전 중입니다.")
}
}
// 서브 클래스
class ElectricCar: Car {
var batteryLife: Int
init(brand: String, year: Int, batteryLife: Int) {
self.batteryLife = batteryLife
super.init(brand: brand, year: year) // 부모 클래스의 생성자 호출
}
func charge() {
print("\(brand) 전기차가 충전 중입니다. 배터리 수명: \(batteryLife)%")
}
}
// 객체 생성 및 사용
let myElectricCar = ElectricCar(brand: "Tesla", year: 2023, batteryLife: 90)
myElectricCar.drive() // 출력: Tesla 자동차가 운전 중입니다.
myElectricCar.charge() // 출력: Tesla 전기차가 충전 중입니다. 배터리 수명: 90%
2. Java
// 기본 클래스
public class Car {
protected String brand;
protected int year;
public Car(String brand, int year) {
this.brand = brand;
this.year = year;
}
public void drive() {
System.out.println(brand + " 자동차가 운전 중입니다.");
}
}
// 서브 클래스
public class ElectricCar extends Car {
private int batteryLife;
public ElectricCar(String brand, int year, int batteryLife) {
super(brand, year); // 부모 클래스의 생성자 호출
this.batteryLife = batteryLife;
}
public void charge() {
System.out.println(brand + " 전기차가 충전 중입니다. 배터리 수명: " + batteryLife + "%");
}
}
// 객체 생성 및 사용
public class Main {
public static void main(String[] args) {
ElectricCar myElectricCar = new ElectricCar("Hyundai", 2024, 80);
myElectricCar.drive(); // 출력: Hyundai 자동차가 운전 중입니다.
myElectricCar.charge(); // 출력: Hyundai 전기차가 충전 중입니다. 배터리 수명: 80%
}
}
3. C#
// 기본 클래스
public class Car {
public string Brand { get; set; }
public int Year { get; set; }
public Car(string brand, int year) {
Brand = brand;
Year = year;
}
public void Drive() {
Console.WriteLine($"{Brand} 자동차가 운전 중입니다.");
}
}
// 서브 클래스
public class ElectricCar : Car {
public int BatteryLife { get; set; }
public ElectricCar(string brand, int year, int batteryLife) : base(brand, year) { // 부모 클래스 생성자 호출
BatteryLife = batteryLife;
}
public void Charge() {
Console.WriteLine($"{Brand} 전기차가 충전 중입니다. 배터리 수명: {BatteryLife}%");
}
}
// 객체 생성 및 사용
class Program {
static void Main(string[] args) {
ElectricCar myElectricCar = new ElectricCar("BMW", 2023, 70);
myElectricCar.Drive(); // 출력: BMW 자동차가 운전 중입니다.
myElectricCar.Charge(); // 출력: BMW 전기차가 충전 중입니다. 배터리 수명: 70%
}
}
4. JavaScript
// 기본 클래스
class Car {
constructor(brand, year) {
this.brand = brand;
this.year = year;
}
drive() {
console.log(`${this.brand} 자동차가 운전 중입니다.`);
}
}
// 서브 클래스
class ElectricCar extends Car {
constructor(brand, year, batteryLife) {
super(brand, year); // 부모 클래스 생성자 호출
this.batteryLife = batteryLife;
}
charge() {
console.log(`${this.brand} 전기차가 충전 중입니다. 배터리 수명: ${this.batteryLife}%`);
}
}
// 객체 생성 및 사용
const myElectricCar = new ElectricCar("Audi", 2025, 85);
myElectricCar.drive(); // 출력: Audi 자동차가 운전 중입니다.
myElectricCar.charge(); // 출력: Audi 전기차가 충전 중입니다. 배터리 수명: 85%
5. Python
# 기본 클래스
class Car:
def __init__(self, brand, year):
self.brand = brand
self.year = year
def drive(self):
print(f"{self.brand} 자동차가 운전 중입니다.")
# 서브 클래스
class ElectricCar(Car):
def __init__(self, brand, year, battery_life):
super().__init__(brand, year) # 부모 클래스의 생성자 호출
self.battery_life = battery_life
def charge(self):
print(f"{self.brand} 전기차가 충전 중입니다. 배터리 수명: {self.battery_life}%")
# 객체 생성 및 사용
my_electric_car = ElectricCar("Tesla", 2026, 95)
my_electric_car.drive() # 출력: Tesla 자동차가 운전 중입니다.
my_electric_car.charge() # 출력: Tesla 전기차가 충전 중입니다. 배터리 수명: 95%
Swift 클래스 선언하기

클래스에 저장 프로퍼티(stored property) 추가하기

클래스 안에 있는 저장 프로퍼티는 반드시 초기값이 있어야 한다.
class Man {
var age : Int = 0
var weight : Double = 0.0
}
1. 초기값 직접 주기
class Man {
var age : Int?
var weight : Double?
}
2. optional 변수로 선언하기, 자동으로 nil로 초기화 함
프로퍼티는 초기값이 있거나 옵셔널 변수(상수)로 선언

인스턴스 만들고 메서드와 프로퍼티 접근
class Man {
var age : Int = 0
var weight : Double = 0.0
func display() {
print(age, weight)
}
}
var x : Int
// 클래스명 다음의 괄호는 눈에 보이지 않는 default initializer를 나타낸다
var sung : Man = Man() // :Man 생략 가능
sung.age = 10
class Man {
var age : Int = 0
var weight : Double = 0.0
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
var x : Int
var sung : Man = Man()
print(sung.age) // 0
sung.age = 10
sung.weight = 20.5
print(sung.age, sung.weight) // 10 20.5
sung.display() // 나이: 10, 몸무게: 20.5
클래스(class or type) 메서드
class Man {
var age : Int = 0
var weight : Double = 0.0
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
class func cM(){
print("cM은 클래스 메서드입니다.")
}
static func scM(){
print("scM은 클래스 메서드(static)")
}
}
var x : Int
var sung : Man = Man()
Man.cM() // 클래스 메서드는 클래스가 호출
// cM은 클래스 메서드입니다.
Man.scM() // 클래스 메서드는 클래스가 호출
// scM은 클래스 메서드(static)
class 키워드로 만든 클래스 메서드는 자식 클래스에서 override 가능하다
인스턴스 초기화하기: Init()
class Man {
var age : Int = 0
var weight : Double = 0.0
init(yourAge: Int, yourWeight : Double){
age = yourAge
weight = yourWeight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
// var sung : Man = Man() // 오류
// init()을 하나라도 직접 만들면 default initializer는 사라짐
var sung : Man = Man(yourAge: 5, yourWeight: 10.3)
sung.display()
designated initializer:
모든 프로퍼티(age, weight)를 다 초기화시키는 생성자
인스턴스 만들 때 클래스명 다음 괄호의 의미: init() 호출
class Man {
var age : Int = 0
var weight : Double = 0.0
init(yourAge: Int, yourWeight : Double){
age = yourAge
weight = yourWeight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
var sung : Man = Man(yourAge: 5, yourWeight: 10.3)
// init(yourAge: 5, yourWeight: 10.3) 호출
sung.display()
sung.age = 10
sung.weight = 20.5
sung.display()
self
class Man {
var age : Int = 0
var weight : Double = 0.0
init(age: Int, weight : Double){
self.age = age //프로퍼티 = 매개변수
self.weight = weight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
var sung : Man = Man(age:10, weight:20.5)
sung.display()
this와 self
언어 | 키워드 | 사용 예 | 설명 |
JavaScript | this | this.brand | 객체 메서드에서 현재 객체의 속성이나 메서드를 참조합니다. |
Python | self | self.brand | 메서드의 첫 번째 매개변수로 사용되며, 현재 인스턴스의 속성이나 메서드를 참조합니다. |
Java | this | this.brand | 생성자나 메서드 내부에서 현재 객체의 속성을 가리키고, 매개변수와 속성 간의 혼동을 피합니다. |
C# | this | this.brand | 클래스 내에서 현재 객체의 속성을 명확히 지정하고, 메서드 내부에서 해당 인스턴스를 참조합니다. |
Swift | self | self.brand | 메서드 내에서 현재 인스턴스를 참조하며, 주로 인스턴스 변수와 메서드를 명확하게 지정할 때 사용됩니다. |
method overloading: 생성자 중첩
class Man {
var age : Int = 0
var weight : Double = 0.0
init(age: Int, weight : Double){
self.age = age
self.weight = weight
} //designated initializer
init(age: Int){ // 2
self.age = age
}
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
var sung : Man = Man.init(age: 5, weight: 10.3) // 1
var kim : Man = Man(age: 33) // 2
sung.display()
kim.display()
매개변수의 개수와 자료형이 다른 같은 이름의 함수를 여러 개 정의
UIImage클래스의 init()함수 overloading

UIImage
1. UIImage(named:)
- 용도: 앱 번들에 포함된 이미지를 로드할 때 가장 자주 사용됩니다.
- 예시:
let image = UIImage(named: "exampleImageName")
- 설명: 앱에 포함된 정적 이미지를 로드하는 데 매우 빈번하게 사용됩니다.
2. UIImageView(image:)
- 용도: 이미지 뷰에 이미지를 표시할 때 사용됩니다.
- 예시:
let imageView = UIImageView(image: UIImage(named: "exampleImageName"))
- 설명: UIImageView를 초기화할 때 사용되며, 이미지를 화면에 표시하기 위해 많이 사용됩니다.
3. UIImage(contentsOfFile:)
- 용도: 앱 번들 외부의 이미지 파일을 로드할 때 사용됩니다.
- 예시:
if let filePath = Bundle.main.path(forResource: "exampleImage", ofType: "png") {
let image = UIImage(contentsOfFile: filePath)
}
- 설명: 파일 경로를 통해 이미지를 불러올 때 사용되며, 일반적으로 로컬 저장소에서 이미지를 로드할 때 사용됩니다.
4. UIImage(systemName:)
- 용도: iOS 13 이상에서 제공하는 SF Symbols 아이콘을 로드할 때 사용됩니다.
- 예시:
let icon = UIImage(systemName: "heart.fill")
- 설명: 시스템 제공 아이콘을 사용할 때 사용되며, 최근 iOS에서 자주 사용됩니다.
5. UIImage(data:)
- 용도: 이미지 데이터로부터 이미지를 생성할 때 사용됩니다. 예를 들어, 네트워크에서 이미지를 다운로드한 후 사용됩니다.
- 예시:
if let imageData = try? Data(contentsOf: url) {
let image = UIImage(data: imageData)
}
- 설명: 원격 서버에서 이미지를 받아올 때나 데이터를 이미지로 변환할 때 사용됩니다.
6. UIImage.resizableImage(withCapInsets:)
- 용도: 이미지가 늘어나도 품질이 유지되도록 일부 영역만 늘어나게 설정할 때 사용됩니다.
- 예시:
let resizableImage = image.resizableImage(withCapInsets: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
- 설명: 특히 버튼 배경 등에 자주 사용되며, 이미지의 특정 영역이 반복되어도 깨지지 않도록 조정할 수 있습니다.
7. UIImageRenderingMode
- 용도: 이미지를 템플릿 또는 원본 모드로 렌더링할 때 사용됩니다.
- 예시:
let templateImage = image.withRenderingMode(.alwaysTemplate)
- 설명: 템플릿 모드를 사용하여 아이콘에 다양한 색상을 적용할 수 있습니다.
8. UIImage(cgImage:)
- 용도: CGImage 객체를 사용하여 이미지를 생성할 때 사용됩니다.
- 예시:
let cgImage = image.cgImage
let newImage = UIImage(cgImage: cgImage!)
- 설명: Core Graphics 이미지 객체를 UIImage로 변환할 때 사용되며, 이미지 처리 시 유용합니다.
9. UIImage.scaleAspectFit / scaleAspectFill
- 용도: 이미지 뷰의 콘텐츠 모드를 설정하여 이미지의 비율을 유지하며 화면에 맞게 조정할 때 사용됩니다.
- 예시:
imageView.contentMode = .scaleAspectFit
- 설명: 이미지가 비율을 유지하면서 화면에 맞게 표시되도록 조정할 때 사용됩니다.
클래스(class) 상속
superclass와 subclass

스위프트 상속

suepr: 부모 메서드 호출 시 사용
class Man {
var age : Int = 0
var weight : Double = 0.0
init(age: Int, weight : Double){
self.age = age
self.weight = weight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
class Student : Man {
var name : String
func displayS() {
print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double, name : String){
self.name = name
super.init(age:age, weight:weight) //과제: 이 줄을 안쓰면?
}//error:'super.init' isn't called on all paths before returning from initializer
}
var lee : Student = Student(age: 25, weight: 77.7, name: "soft")
lee.display()
lee.displayS()
override: 부모와 자식에 같은 메서드가 있으면 자식 우선

class Man {
var age : Int = 0
var weight : Double = 0.0
init(age: Int, weight : Double){
self.age = age
self.weight = weight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
class Student : Man {
var name : String
override func display() {
print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
}
init(age: Int, weight : Double, name : String){
self.name = name
super.init(age:age, weight:weight) //과제: 이 줄을 안쓰면?
}//error:'super.init' isn't called on all paths before returning from initializer
}
var lee : Student = Student(age: 25, weight: 77.7, name: "soft")
lee.display()
- 부모와 자식에 display()라는 메서드가 있어서 Student클래스는 display() 메서드가 두 개임
- Student클래스의 인스턴스 lee가 display()를 호출할 때, 자식클래스가 새로 만든 display() 메서드가 우선적으로 호출되려면 func 앞에 override키워드 씀
failable initializers(실패 가능한 생성자: init?)

failable initializer(실패 가능한 생성자: init? init!)
init다음에 “?”나 “!” 하며 옵셔널 값이 리턴됨
오류 상황에 nil을 리턴하는 조건문이 있음
- return nil
init?
init!
failable initializer 만드는 방법
1. ? 붙이기
class Man {
var age : Int = 0
var weight : Double = 0.0
init?(age: Int, weight : Double){
self.age = age
self.weight = weight
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
if문 추가
class Man {
var age : Int = 0
var weight : Double = 0.0
init?(age: Int, weight : Double){
if age <= 0 || weight <= 0.0 {
return nil
} else {
self.age = age
self.weight = weight
}
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
2. 선언할 때 optional 형으로 선언해야 한다
var sung : Man? = Man(age: 5, weight: 10.3)
failable initialize가 있는 클래스의 인스턴스 생성

var kim : Man? = Man(age:1, weight:3.5)
// 1-1. 옵셔널 형식으로 Man 객체 생성: 'Man?' 타입으로 옵셔널 선언. 객체가 있을 수도, 없을 수도 있다.
if let kim1 = kim { //1-2. 옵셔널 바인딩
kim1.display()
}
// 1-2. 옵셔널 바인딩: 'if let' 구문을 사용하여 옵셔널이 nil이 아닌 경우 안전하게 unwrapping 함.
// 'kim' 객체가 nil이 아닌 경우 'kim1'에 할당되고, 'display()' 메서드 호출 가능.
if let kim2 = Man(age:2, weight:5.5) {
kim2.display()
}
// 2. 인스턴스 생성과 동시에 옵셔널 바인딩: 객체를 생성하며 바로 옵셔널 바인딩.
// 'if let'을 통해 객체 생성과 동시에 unwrapping, nil이 아니면 'display()' 메서드 호출.
var kim3 : Man = Man(age:3, weight:7.5)!
// 3. 인스턴스 생성하면서 바로 강제 언래핑: 객체 생성 시 '!'로 강제 언래핑을 통해 바로 unwrapping.
// 옵셔널 형식이 아닌 'Man' 타입으로 선언했기 때문에 nil이 아님을 확신하는 경우에 사용.
kim3.display()
// 'kim3'는 강제 언래핑으로 옵셔널이 아니므로 바로 'display()' 메서드 호출 가능.
var kim4 : Man? = Man(age:4, weight:10.5)
// 4. 옵셔널 인스턴스 생성: 'Man?' 타입으로 옵셔널 객체 생성, nil이 될 수 있는 경우에 사용.
kim4!.display()
// 4. 옵셔널 인스턴스를 사용시 강제 언래핑: 'kim4!'로 강제 언래핑 후 'display()' 메서드 호출.
// 옵셔널 값이 nil이 아닐 것을 확신할 때만 사용해야 안전하다. 그렇지 않으면 런타임 에러 발생.
class Man {
var age : Int = 0
var weight : Double = 0.0
init?(age: Int, weight : Double){
if age <= 0 || weight <= 0.0 {
return nil
} else {
self.age = age
self.weight = weight
}
} //designated initializer
func display() {
print("나이: \(age), 몸무게: \(weight)")
}
}
var sung : Man? = Man(age: 0, weight: 10.3)
if let sung = sung {
sung.display()
}
가장 좋은 방법
정리
// 기본 클래스 Person 정의
class Person {
var name: String
var age: Int
// 기본 생성자
init(name: String, age: Int) {
self.name = name
self.age = age
}
// 메서드: 기본 정보 출력
func displayInfo() {
print("Name: \(name), Age: \(age)")
}
}
// Person을 상속받은 Employee 클래스 정의
class Employee: Person {
var employeeID: String
// failable initializer: 조건에 맞지 않으면 nil 반환
init?(name: String, age: Int, employeeID: String) {
// 나이가 18세 이상이어야만 Employee 객체 생성 가능
if age < 18 {
return nil // 조건에 맞지 않으면 nil 반환
}
self.employeeID = employeeID
super.init(name: name, age: age) // 상위 클래스의 init 호출
}
// 메서드 오버라이딩: Employee 정보 출력
override func displayInfo() {
super.displayInfo() // 상위 클래스의 메서드 호출
print("Employee ID: \(employeeID)")
}
}
// Person 인스턴스 생성 및 사용
let person = Person(name: "Alice", age: 30)
person.displayInfo()
// 출력:
// Name: Alice, Age: 30
// 조건을 만족하는 Employee 인스턴스 생성
if let employee = Employee(name: "Bob", age: 25, employeeID: "E123") {
employee.displayInfo()
// 출력:
// Name: Bob, Age: 25
// Employee ID: E123
} else {
print("Failed to create employee.")
}
// 조건을 만족하지 않는 경우(nil 반환)
if let employee = Employee(name: "Charlie", age: 16, employeeID: "E124") {
employee.displayInfo()
} else {
print("Failed to create employee.")
// 출력: Failed to create employee.
}
출처: iOS 프로그래밍 기초 강의 자료