처음부터 차근차근

Swift 실습 5 본문

프로그래밍/Swift

Swift 실습 5

_soyoung 2021. 10. 7. 21:27
반응형
class Animal{
    // stored property
    // 반드시 직접 초기화를 하거나 옵셔널 변수로 만들거나 생성자를 이용해서 초기화를 해야한다. 
    var name : String = "sunny"
    var age : Int = 3
    var weight : Float = 2.12
    var favorite : String?
    // 인스턴스 메서드 : 인스턴스가 호출하는 메서드
    func cry(sound: String) -> String{
        return sound + "~~~!!"
    }
    func printAnimalInformation() { 
        print("이름 : \(name)")
        print("나이 : \(age)")
        print("몸무게 : \(weight)")
        if let catFavorite = favorite {
            print("좋아하는 것 : \(catFavorite)") // 강제 언래핑
        }
    }
}
// Animal 클래스 인스턴스 생성, Animal()은 생략 가능
var animal : Animal = Animal() 
// 옵셔널 변수에 값 대입, 프로퍼티 접근. animal.favorite type : Optional<String>
animal.favorite = "fish"
// 인스턴스 메서드 호출
var crySound = animal.cry(sound: "Meooooooow")
print(crySound)
animal.printAnimalInformation()
//결과 : Meooooooow~~~!!
//이름 : sunny
//나이 : 3
//몸무게 : 2.12
//좋아하는 것 : fish






class Plant {
    var name = "rose"
    var isblossom = true
    var color = "red"
    // 인스턴스 메서드
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    // 클래스(타입) 메서드
    // 클래스가 호출하는 메서드
    // 차이점 : class 키워드로 만든 클래스 메서드는 자식 클래스에서 override가 가능하다.
    class func whatAboutPlants() {
        print("It is beutiful.")
    }
    static func doYouLikeThis() { 
        print("yes!")
    }
}
var plant = Plant()
// 인스턴스 메서드는 인스턴스가 호출
plant.printPlantInformation()
// 클래스 메서드는 클래스가 호출
Plant.whatAboutPlants()
Plant.doYouLikeThis()
//결과 : 이름 : rose
//꽃이 피는가 : true
//색깔 : red
//It is beutiful.
//yes!






class Plant {
    // 생성자(initializer)가 있으면 초기 값을 생략해도 된다.
    // 대신 옆에 자료형을 꼭 적어줘야 한다.
    var name : String
    var isblossom = true
    var color = "red"
    // 인스턴스 메서드
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    // designated initializer : 모든 프로퍼티를 초기화 시키는 생성자
    init(plantName: String, isPlantBlossom: Bool, plantColor: String) {
        name = plantName
        isblossom = isPlantBlossom
        color = plantColor
    }
    // deinitializer(소멸자)
    // 소멸자는 매개변수가 없다.
    deinit {
        print("instance remove...")
    }
}
// 생성자(initializer)이용하여 인스턴스 생성
// name이 sunflower로 초기화되고, color가 red에서 yellow로 바뀐다.
var plant : Plant? = Plant(plantName: "sunflower", isPlantBlossom: true, plantColor: "yellow")
plant?.printPlantInformation()
// 소멸자 호출됨
plant = nil
//결과 : 이름 : sunflower
//꽃이 피는가 : true
//색깔 : yellow
// instance remove...






class Plant {
    var name = "cactus" // 선인장
    var isblossom = true
    var color = "green"
    // 인스턴스 메서드
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    init(plantName: String, isPlantBlossom: Bool, plantColor: String) {
        name = plantName
        isblossom = isPlantBlossom
        color = plantColor
    }
    // 기본 생성자(default initializer)를 직접 만드는 이유 : 
    // 생성자를 하나라도 직접 생성하면 기본 생성자를 사용하지 못한다(사라진다).
    // 그래서 생성자를 이미 만들고 기본 생성자를 사용하고 싶으면 밑에 처럼 직접 만들어줘야 한다.
    init() {
    }
}
// 기본 생성자를 사용한 인스턴스 생성
var plant = Plant()
plant.printPlantInformation()
//결과 : 이름 : cactus
//꽃이 피는가 : true
//색깔 : green






class Plant {
    var name : String
    var isblossom : Bool
    var color : String
    // 인스턴스 메서드
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    // 사용자 정의 생성자, designated initializer
    // self : 현재 클래스의 프로퍼티나 메서드를 가리킬 때 사용하는 키워드
    init(name: String, isblossom: Bool, color: String) {
        self.name = name
        self.isblossom = isblossom
        self.color = color
    }
}
var plant = Plant(name: "catus", isblossom: true, color: "green")
plant.printPlantInformation()
// 결과 : 이름 : catus
//꽃이 피는가 : true
//색깔 : green






class Plant {
    var name : String
    var isblossom : Bool
    var color : String
    // computed property(계산(연산) 프로퍼티) : 
    // stored property(저장 프로퍼티)의 값을 바꾸거나(set), stored property를 이용하여 자신의 값을 초기화하는(get) 프로퍼티
    var isNotBlossom : Bool {
        // getter : 값을 리턴하는 역할
	// setter가 없으므로 get{} 생략 가능
	// isblossom 프로퍼티의 반대 값을 리턴한다.
        get {
            return !isblossom
        }
    }
    // 인스턴스 메서드
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("꽃이 피지 않는가 : \(isNotBlossom)")
        print("색깔 : \(color)")
    }
    // designated initializer
    init(name: String, isblossom: Bool, color: String) {
        self.name = name
        self.isblossom = isblossom
        self.color = color
    }
}
var plant = Plant(name: "catus", isblossom: true, color: "green")
plant.printPlantInformation()
//결과 : 이름 : catus
//꽃이 피는가 : true
//꽃이 피지 않는가 : false
//색깔 : green






class Plant {
    var name : String
    var isblossom : Bool
    var color : String
    // computed property(계산(연산) 프로퍼티)
    var isNotBlossom : Bool {
        // getter
        get {
            return !isblossom
        }
        // setter : stored property의 값을 바꾸는(새로운 값을 대입하는) 역할
        // 매개변수 명은 newValue을 기본으로 사용한다.
        // 매개변수 명이 newValue면 (newValue)를 생략할 수 있다.
        set(newValue) {
            isblossom = newValue
        }
    }
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("꽃이 피지 않는가 : \(isNotBlossom)")
        print("색깔 : \(color)")
    }
    // designated initializer
    init(name: String, isblossom: Bool, color: String) {
        self.name = name
        self.isblossom = isblossom
        self.color = color  
    }
}
var plant = Plant(name: "catus", isblossom: true, color: "green")
plant.printPlantInformation()
// isblossom에 false를 대입한다(setter에 매개변수로 false가 들어간다).
plant.isNotBlossom = false
print("\n")
// isblossom이 먼저 false가 되었기 때문에 그 반댓값을 가지는 isNotBlossom은 true값을 가지게 된다.
plant.printPlantInformation()
// 결과 : 이름 : catus
//꽃이 피는가 : true
//꽃이 피지 않는가 : false
//색깔 : green
//
//이름 : catus
//꽃이 피는가 : false
//꽃이 피지 않는가 : true
//색깔 : green






class Plant {
    var name : String
    var isblossom : Bool
    var color : String
    
    var isNotBlossom : Bool {
        //setter의 매개변수명을 없애고, 코드를 깔끔하게 정리했다.
        get { return !isblossom }
        set { isblossom = newValue }
    }
    
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("꽃이 피지 않는가 : \(isNotBlossom)")
        print("색깔 : \(color)")
    }
    
    init(name: String, isblossom: Bool, color: String) {
        self.name = name
        self.isblossom = isblossom
        self.color = color  
    }
}
var plant = Plant(name: "catus", isblossom: true, color: "green")
plant.isNotBlossom = false
plant.printPlantInformation()
//결과 : 이름 : catus
//꽃이 피는가 : false
//꽃이 피지 않는가 : true
//색깔 : green






class Plant {
    var name : String 
    var isblossom : Bool = true
    var color : String = "yellow"
    
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    
    init(name: String, isblossom: Bool, color: String) {
        self.name = name
        self.isblossom = isblossom
        self.color = color  
    }
    // method overloading
    // 이름이 같은 함수를 만드는 것이다. 
    // 대신 매개변수의 개수, 자료형이나 리턴형을 다르게 해야한다.
    // 생성자 중첩
    init(name: String) {
        self.name = name
    }
}
var plant1 = Plant(name: "catus", isblossom: true, color: "green")
var plant2 = Plant(name: "dandelion")
plant1.printPlantInformation()
print("----------")
plant2.printPlantInformation()
//결과 : 이름 : catus
//꽃이 피는가 : true
//색깔 : green
//----------
//이름 : dandelion
//꽃이 피는가 : true
//색깔 : yellow






class Plant {
    var name : String
    var isblossom : Bool
    var color : String
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    // failable initializer(실패 가능한 생성자)
    // 인스턴스를 만들 때 오류가 생기면 인스턴스를 만들지 않고 nil을 반환하는 생성자
    // 이 생성자를 통해 만들어지 인스턴스는 옵셔널형이다.
    init? (name: String, isblossom: Bool, color: String) {
        if name == "" || color == "" {
            return nil
        }
        else {
            self.name = name
            self.isblossom = isblossom
            self.color = color  
        }
    }
}
// failable initializer를 사용해 인스턴스 생성하는 방법
// 1. 옵셔널 형으로 객체를 생성한 다음 옵셔널 바인딩
var plant : Plant? = Plant(name: "dandelion", isblossom: true, color: "yellow")
if let plantIns1 = plant {
    plantIns1.printPlantInformation()
    print("------------")
}
else {
    print("인스턴스를 만드는 데 실패했습니다.")
}
// 2. 인스턴스를 생성함과 동시에 옵셔널 바인딩
if let plantIns2 = Plant(name: "rose", isblossom: true, color: "red") {
    plantIns2.printPlantInformation()
    print("------------")
}
else {
    print("인스턴스를 만드는 데 실패했습니다.")
}
// 3. 인스턴스를 생성함과 동시에 강제 언래핑
// 이 방법은 위험한 방법이다. 생성자가 nil을 반환하면 오류가 생긴다.
var plant1 = Plant(name: "catus", isblossom: true, color: "green")!
plant1.printPlantInformation()
print("------------")
// 4. 인스턴스를 사용할 때 강제 언래핑
// 윗 방법과 마찬가지로 위험한 방법이다.
var plant2 : Plant? = Plant(name: "sunflower", isblossom: true, color: "yellow")
plant2!.printPlantInformation()
//결과 : 이름 : dandelion
//꽃이 피는가 : true
//색깔 : yellow
//------------
//이름 : rose
//꽃이 피는가 : true
//색깔 : red
//------------
//이름 : catus
//꽃이 피는가 : true
//색깔 : green
//------------
//이름 : sunflower
//꽃이 피는가 : true
//색깔 : yellow






lass Plant {
    var name : String
    var isblossom : Bool
    var color : String
    func printPlantInformation() { 
        print("이름 : \(name)")
        print("꽃이 피는가 : \(isblossom)")
        print("색깔 : \(color)")
    }
    // failable initializer
    init? (name: String, isblossom: Bool, color: String) {
        if name == "" || color == "" {
            return nil
        }
        else {
            self.name = name
            self.isblossom = isblossom
            self.color = color  
        }
    }
}
// 생성자에서 nil을 반환할 시 "인스턴스를 만드는 데 실패했습니다." 출력
var plant : Plant? = Plant(name: "", isblossom: true, color: "yellow")
if let plantIns1 = plant {
    plantIns1.printPlantInformation()
    print("------------")
}
else {
    print("인스턴스를 만드는 데 실패했습니다.")
}
// 위와 마찬가지로 인스턴스 생성에 실패 할 시 else에 있는 문장 출력
if let plantIns2 = Plant(name: "", isblossom: true, color: "red") {
    plantIns2.printPlantInformation()
    print("------------")
}
else {
    print("인스턴스를 만드는 데 실패했습니다.")
}
// error(crash)
var plant1 = Plant(name: "catus", isblossom: true, color: "")!
plant1.printPlantInformation()
print("------------")
// error(crash)
var plant2 : Plant? = Plant(name: "sunflower", isblossom: true, color: "")
plant2!.printPlantInformation()
//결과 : 인스턴스를 만드는 데 실패했습니다.
//인스턴스를 만드는 데 실패했습니다.
//error
//error






// 과제 : 나이와 몸무게가 음수이면 nil을 반환하는 failable initialize 구현
class Man{
    var age : Int
    var weight : Double
    func display(){
        print("나이=\(age), 몸무게=\(weight)")
    }
    // failable initialize
    init?(age: Int, weight : Double){
        // 나이와 몸무게가 음수이면 nil을 반환
        if age < 0, weight < 0 {
            return nil
        }
        else {
            self.age = age
            self.weight = weight
        }
    } 
}
var man : Man? = Man(age:-1, weight: -5) 
//옵셔널 바인딩
if let manIns = man { 
    manIns.display()
}
else {
    print("인스턴스 생성 실패")
}
//결과 : 인스턴스 생성 실패






class Animal{
    var name : String
    var age : Int
    var weight : Float
    
    func printAnimalInformation() { 
        print("이름 : \(name)")
        print("나이 : \(age)")
        print("몸무게 : \(weight)")
    }
    
    init(name: String, age: Int, weight: Float) {
        self.name = name
        self.age = age
        self.weight = weight
    }
}
// Animal class를 상속받은 Cat class
class Cat : Animal {
    // 아무것도 없지만 부모 클래스의 모든 것을 가지고 있음
}
var animal : Animal = Animal(name: "mimi", age: 2, weight: 2.3)
animal.printAnimalInformation()
print("****")
// 부모 클래스를 상속받아서 생성자와 메서드를 가지고 있기 때문에 사용 가능
var cat : Cat = Cat(name: "coco", age: 3, weight: 3.1)
cat.printAnimalInformation()
//결과 : 이름 : mimi
//나이 : 2
//몸무게 : 2.3
//****
//이름 : coco
//나이 : 3
//몸무게 : 3.1






class Animal{
    var name : String
    var age : Int
    var weight : Float
    
    func printAnimalInformation() { 
        print("이름 : \(name)")
        print("나이 : \(age)")
        print("몸무게 : \(weight)")
    }
    
    init(name: String, age: Int, weight: Float) {
        self.name = name
        self.age = age
        self.weight = weight
    }
}
class Cat : Animal {
    var favorite : String
    func printCatInformation() {
        print("이름 : \(name)")
        print("나이 : \(age)살")
        print("몸무게 : \(weight)kg")
        print("좋아하는 것 : \(favorite)")
    }
    init(favorite: String, name: String, age: Int, weight: Float) {
        self.favorite = favorite
        // 부모 클래스를 상속받았다면 인스턴스를 생성할 때 부모 클래스의 생성자도 호출해줘야 한다.
        // 만약 부모 클래스의 생성자를 호출하지 않으면 오류가 난다.
        // 매개변수로 받은 name, age, weight를 부모 클래스 생성자의 매개변수로 넣어주고 있다.
        super.init(name: name, age: age, weight: weight)
    }
}
var cat : Cat = Cat(favorite: "츄르", name: "coco", age: 3, weight: 3.1)
cat.printCatInformation()
//결과 : 이름 : coco
//나이 : 3살
//몸무게 : 3.1kg
//좋아하는 것 : 츄르






class Animal{
    var name : String
    var age : Int
    var weight : Float
    
    func printAnimalInformation() { 
        print("이름 : \(name)")
        print("나이 : \(age)")
        print("몸무게 : \(weight)")
    }
    
    init(name: String, age: Int, weight: Float) {
        self.name = name
        self.age = age
        self.weight = weight
    }
}
class Cat : Animal {
    var favorite : String
    // override : 부모의 함수를 재정의 하는 것
    // 부모 클래스와 자식 클래스가 똑같은 메서드를 가지고 있으면 자식 클래스 메서드를 우선으로 한다.
    // 부모의 함수를 재정의하고 싶으면 func 앞에 override 키워드를 꼭 써야한다.
    override func printAnimalInformation() {
        print("이름 : \(name)")
        print("나이 : \(age)살")
        print("몸무게 : \(weight)kg")
        print("좋아하는 것 : \(favorite)")
    }
    
    init(favorite: String, name: String, age: Int, weight: Float) {
        self.favorite = favorite
        super.init(name: name, age: age, weight: weight)
    }
}
var cat : Cat = Cat(favorite: "츄르", name: "coco", age: 3, weight: 3.1)
// 자식 클래스의 printAnimalInformation()가 호출됨
cat.printAnimalInformation()
//결과 : 이름 : coco
//나이 : 3살
//몸무게 : 3.1kg
//좋아하는 것 : 츄르

 

 

 

 

<iOS UIKit class hierarchy에서 init() 찾아 간단 사용 예>

선정한 class : UIButton

 

Method overloading이란, 같은 이름의 함수를 여러 개 만드는 것이다.

, 매개변수의 자료형이나 매개변수의 개수, 리턴형을 달리해야 한다.

, Init()메서드 overloading은 매개변수의 개수나 자료형을 다르게 하여 여러 개의 생성자를 만드는 것이다.

 

Failable initializer이란, 실패 가능한 생성자이다.

인스턴스를 만드는 것에 실패하면 nil을 반환한다(return nil).

Failable initializer로 만든 인스턴스는 nil이 대입될 수 있기 때문에 옵셔널형이다.

그래서 꼭 옵셔널 바인딩이나 강제 언래핑을 하여 옵셔널형을 풀어줘야 한다.

 

UIButton class 인스턴스 만드는 코드

var button1 : UIButton = UIButton(frame: CGRect(x: Double, y: Double, width: Double, height: Double))

var button2 = UIButton(type: .infoDark)

 

 

 

 

 

 

 

 

출처 : iOS프로그래밍기초(21-2학기)한성현교수 강의 내용 변형 및 요약

반응형

'프로그래밍 > Swift' 카테고리의 다른 글

Swift 실습 6  (0) 2021.10.15
Swift 문법 정리 5  (0) 2021.10.08
Swift 문법 정리 4  (0) 2021.09.30
Switf 실습 4  (0) 2021.09.30
Swift 문법 정리 3  (0) 2021.09.26
Comments