IOS앱개발

iOS 앱 개발 6주차(1010)

taeho1630 2024. 10. 10. 16:49

클래스 기본 구조

 

class 새로운 클래스 이름 : 부모 클래스 {

   // 프로퍼티    //  프로퍼티 = 변수

  // 인스턴스 메서드(일반적인 메서드)     // 메서드 = 함수

  // 타입(type) 메서드(클래스 메서드)

 

저장 프로퍼티(stored property)

 

- 초기값이 있어야된다

class Man{
	var age : Int = 0
    var weight : Double = 0.0
}

위의 코드에서 age, weight를 저장 프로퍼티라고 하며, 초기값으로 0과 0.0을 주지 않으면 오류가 생긴다.

 

1) 위의 코드와 같이 Int = 0처럼 초기값 지정

2) 다른 방법으로는 Int! 혹은 Double? 처럼 옵서널 변수로 선언(일반적으로는 ?로 많이 만든다)

3) init을 이용해서 초기화(일반적인 방법)

 

메서드

 

인스턴스 메서드 - 인스턴스가 사용

클래스 또는 타입 메서드 - 클래스가 사용

 

var 인스턴스명 : 클래스명 = 클래스명() - 클래스명 다음의 괄호는 눈에 보이지 않는 default initializer를 나타낸다

클래스 메서드

 

클래스명.클래스메서드()

 

- 타입 메서드는 class나 static 키워드를 앞에 붙여서 선언하고 func만 붙으면 인스턴스 메서드이다.

(타입 메서드 또는 클래스 메서드는 클래스 레벨에서 동작한다)

 

인스턴스 초기화하기 : init()

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
   print("나이=\(age), 몸무게=\(weight)")
  }
  init(yourAge: Int, yourWeight : Double){
    age = yourAge
    weight = yourWeight
  } //designated initializer
}
var kim1 = Man()
var kim = Man(yourAge: 10, yourWeight: 30.5)
kim.display()

init() 하나라도 직접 만들면 default initializer가 사라져서 값을 줘야한다.

따라서 위의 코드에서 var kim1 = Man()은 오류가 발생하고 바로 밑의 줄처럼 값을 줘야한다.

 

**designated initializer : 모든 프로퍼티(age, weight)를 다 초기화시키는 생성자 

 

self - 현재 클래스 내 메서드나 프로퍼티를 가리킬 때 메서드나 프로퍼티 앞에 self. 을 붙인다

#c++, JAVA, C#, Javascript, Python, swift에서 스위프트와 파이썬을 제외한 언어는 self 대신  this를 쓴다.

 

method overloading : 생성자 중첩 ( 매개변수의 개수와 자료형이 다른 같은 이름의 함수를 여러 개 정의)

또한, 생성자는 여러개가 있는게 좋다.

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
   print("나이=\(age), 몸무게=\(weight)")
  }
  init(age: Int, weight : Double){
   self.age = age //프로퍼티 = 매개변수
   self.weight = weight
  }
}
var kim : Man = Man(age:10, weight:20.5)
var lee = Man(age:3, weight: 15)
kim.display()
lee.display()

오버라이딩

 

클래스와 상속

 

부모(상위)클래스 - 하위클래스가 상속받은 클래스

상속에서 :(콜론) 다음으로 부모 클래스가 오고, 부모 클래스가 없으면 프로토콜이 올 수 있다.

스위프트에서는 하나의 부모 클래스만 상속이 가능하고 , 프로토콜은 여러개가 올 수 있다.

 

class Man{
  var age : Int = 1
  var weight : Double = 3.5
  func display(){
   print("나이=\(age), 몸무게=\(weight)")
  }
  init(age: Int, weight : Double){
   self.age = age //프로퍼티 = 매개변수
   self.weight = 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: 20, weight: 70.5, name: "smile")
var kim = Man(age: 10, weight: 30.5)
kim.display()
lee.displayS()

위의 코드처럼 상속받고 name을 변수로 새로 생성하여 사용할 수 있다.

오류를 고치기 위해 func 앞에 override를 붙인다.(자식이 새로 만든 함수가 부모의 함수와 이름이 똑같을 경우 자식의 함수를 최우선으로 실행해주면서 부모의 함수를 무시한다.)

 

// Man 클래스 정의
class Man {
    // age 프로퍼티 선언 및 초기값 설정
    var age : Int = 1
    // weight 프로퍼티 선언 및 초기값 설정
    var weight : Double = 3.5
    
    // display 메서드 정의
    func display() {
        // age와 weight 값을 출력
        print("나이=\(age), 몸무게=\(weight)")
    }
    
    // 생성자(initializer) 정의
    init(age: Int, weight : Double) {
        // 매개변수로 받은 값을 프로퍼티에 할당
        self.age = age
        self.weight = weight
    }
}

// Man 클래스를 상속받는 Student 클래스 정의
class Student : Man {
    // name 프로퍼티 선언
    var name : String
    
    // Man 클래스의 display 메서드를 오버라이드
    override func display() {
        // name, age, weight 값을 출력
        print("이름=\(name), 나이=\(age), 몸무게=\(weight)")
    }
    
    // Student 클래스의 생성자 정의
    init(age: Int, weight: Double, name: String) {
        // name 프로퍼티 초기화
        self.name = name
        // 부모 클래스(Man)의 생성자 호출
        super.init(age: age, weight: weight)
        // 주석: 이 줄을 안 쓰면 에러 발생
        // 'super.init' isn't called on all paths before returning from initializer
    }
}

// Student 인스턴스 생성
var lee : Student = Student(age: 20, weight: 70.5, name: "smile")

// Man 인스턴스 생성
var kim = Man(age: 10, weight: 30.5)

// kim 객체의 display 메서드 호출
kim.display()

// lee 객체의 display 메서드 호출
lee.display()

가장 전형적인 스위프트 소스의 초급문법으로 총정리본

 

failable initializers(실패 가능한 생성자: init?) : 옵셔널형으로 만들어진 인스턴스라서 사용하려면 옵셔널을 언래핑해야한다.

- 오류 상황에 nil을 리턴하는 조건문이 있음 (return nil)

 

class Man{
var age : Int
var weight : Double
func display(){
print("나이=\(age), 몸무게=\(weight)")
}
init?(age: Int, weight : Double){
if age <= 0 {
return nil
}
else {
self.age = age
}
self.weight = weight
}
}
var kim : Man? = Man(age:1, weight:3.5)
//1-1.옵셔널 형으로 선언
if let kim1 = kim { //1-2.옵셔널 바인딩
kim1.display()
}
//2.인스턴스 생성과 동시에 옵셔널 바인딩
if let kim2 = Man(age:2, weight:5.5) {
kim2.display()
}
//3.인스턴스 생성하면서 바로 강제 언래핑
var kim3 : Man = Man(age:3, weight:7.5)!
kim3.display()
//4.옵셔널 인스턴스를 사용시 강제 언래핑
var kim4 : Man? = Man(age:4, weight:10.5)
kim4!.display()

failable initialize의 사용방법 4가지(밑의 두가지의 강제 언래핑은 크래쉬가 날 수 있어 좋은 방법은 아니다, 따라서 옵셔널 바인딩을 통해 푸는 것이 좋은 방법이다)

// Man 클래스 정의
class Man {
    // age 프로퍼티 선언 (정수형)
    var age : Int
    // weight 프로퍼티 선언 (실수형)
    var weight : Double
    
    // display 메서드 정의
    func display() {
        // age와 weight 값을 문자열로 포맷하여 출력
        print("나이=\(age), 몸무게=\(weight)")
    }
    
    // failable initializer 정의 (실패 가능한 초기화 메서드)
    init?(age: Int, weight : Double) {
        // age나 weight가 0 이하인 경우 초기화 실패
        if age <= 0 || weight <= 0.0 {
            // nil을 반환하여 초기화 실패를 나타냄
            return nil
        }
        else {
            // 유효한 값인 경우 프로퍼티 초기화
            self.age = age
            self.weight = weight
        }
    }
}

// Man 인스턴스 생성 (강제 언래핑 사용)
var kim : Man = Man(age:10, weight:20.5)!
// kim 객체의 display 메서드 호출
kim.display()

// 아래 코드는 주석 처리되어 있음 (초기화 실패 케이스)
//var lee : Man? = Man(age:0, weight:3.5)
//if let lee1 = lee {
//    lee1.display()
//}

// if let 구문을 사용한 옵셔널 바인딩
if let lee = Man(age:1, weight: 0.0) {
    // 이 블록은 실행되지 않음 (weight가 0.0이므로 초기화 실패)
    lee.display()
}

'IOS앱개발' 카테고리의 다른 글

iOS 앱개발 9주차  (2) 2024.10.31
iOS 프로그래밍 기초 7주차  (1) 2024.10.17
ios앱개발 5주차  (1) 2024.10.09
iOS 프로그래밍 기초 4주차(0926)  (0) 2024.09.30
2주차  (0) 2024.09.12