DEV - iOS/iOS

[Swift] 스위프트 기본 문법 공부(7) - Class(참조 & 상속)

베이비코더 2022. 2. 17. 11:24
반응형
class MyInfo {
    // Class 내부에는 변수, 함수, 열거형 등등 선언할 수 있음
    
    enum GenderType {
        case male
        case female
    }
    var genderType = GenderType.male
    
    var name = ""
    var age = 0
    
    func isAdult() -> Bool {
        if age > 19 {
            return true
        }
        return false
    }
    
}

 

나의 정보를 담는 class를 선언했다.

 

init 키워드를 사용하여 class를 인스턴스화 하여 사용할 때 초기값을 세팅할 수 있다.

class MyInfo {
    // class 초기화
    init(gender: GenderType) {
        self.genderType = gender
    }
    // Class 내부에는 변수, 함수, 열거형 등등 선언할 수 있음
    enum GenderType {
        case male
        case female
    }
    //var genderType = GenderType.male
    var genderType:GenderType?
    
    var name = ""
    var age = 0
    
    func isAdult() -> Bool {
        if age > 19 {
            return true
        }
        return false
    }
    
}

// class 인스턴스화
var myInfo = MyInfo(gender: .female)

init 키워드를 사용하지 않고 인스턴스화(생성)를 하면, 호출할 때 괄호 안에 아무것도 쓰지 않아도 되지만

init 키워드로 성별을 초기화하도록 클래스를 작성했기 때문에 인스턴스화 할 때 gender 초기값을 설정해야 된다.

 

myInfo.genderType = .male

클래스를 생성했을 때 초기화했던 값을 이후에도 변경이 가능하다.

하지만 처음 인스턴스화 했던 값을 이후에 변경하지 않도록 하려면

해당 변수에 private 키워드를 입력해주면 클래스 내부나 선언 이후의 접근은 막아준다.

class MyInfo {
    // class 초기화
    init(gender: GenderType) {
        self.genderType = gender
    }
    // Class 내부에는 변수, 함수, 열거형 등등 선언할 수 있음
    enum GenderType {
        case male
        case female
    }
    //var genderType = GenderType.male
    // private로 변경
    private var genderType:GenderType?
    
    var name = ""
    var age = 0
    
    func isAdult() -> Bool {
        if age > 19 {
            return true
        }
        return false
    }
    
}

// class 인스턴스화
var myInfo = MyInfo(gender: .female)

// 접근할 수 없기 때문에 오류가 남
myInfo.genderType = .male

인스턴스화 할 때 female로 지정된 후 male로 접근 불가능해져서 오류가 나게 된다.

 

참조형(Reference Type)

class의 특징 중 하나는 참조형(Reference Types)이라는 것이다.

// class 인스턴스화
var myInfo = MyInfo(gender: .female)

// 클래스는 참조형.
myInfo.age = 20

var myInfo2 = myInfo
myInfo2.age
myInfo2.age = 30

// 30
myInfo.age

myInfo2와 myInfo는 복제된 별개의 객체가 아닌 같은 메모리를 바라보는 참조형이다.

따라서 myInfo2에서 age 변수의 값을 새롭게 대입하면 myInfo에서도 값이 바뀌게 된다.

 

상속(Ingeritance)

class Soccer {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

let soccerPlay = Soccer()
soccerPlay.teamAScore = 1
soccerPlay.teamBScore = 2
soccerPlay.displayScore()

 

A팀과 B팀의 축구 경기 점수를 보여주는 클래스를 생성했다.

 

만약 비슷한 로직을 갖는 야구, 배구, 농구 등등 경기의 점수를 클래스로 표현한다면

class Soccer {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

class Baseball {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

class Volleyball {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

같은 코드를 반복해서 효율이 떨어질 수 있다.

비슷한 로직을 갖는 코드를 상속을 받는다면 코드가 좀 더 간결해질 수 있다.

class SportsScore {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

class Soccer : SportsScore {

}

class Baseball : SportsScore {

}

class Volleyball : SportsScore {

}

다양한 스포츠 경기의 점수를 보여주는 SportsScore 클래스를 새로 작성하고, 

위에서 만들었던 축구, 야구, 배구 클래스는 SportsScore 클래스를 상속받게 했다.

각 스포츠 종목에 대한 클래스 안에는 아무런 코드들을 작성하지 않아도

인스턴스화하여 SportsScore 클래스 내부에 있는 변수와 함수를 사용할 수 있게 되었다.

class SportsScore {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

class Soccer : SportsScore {

}

class Baseball : SportsScore {

}

class Volleyball : SportsScore {

}

let soccerPlay = Soccer()
soccerPlay.teamAScore = 1
soccerPlay.teamBScore = 2
soccerPlay.displayScore()

let baseballPlay = Baseball()
baseballPlay.teamAScore = 1
baseballPlay.teamBScore = 1
baseballPlay.displayScore()

let volleyballPlay = Volleyball()
volleyballPlay.teamAScore = 10
volleyballPlay.teamBScore = 11
volleyballPlay.displayScore()

정상적으로 작동됨을 볼 수 있다.

 

Soccer, Baseball, Volleyball 클래스는 부모 클래스인 SportsScore 클래스를 상속받아

SportsScore 클래스에 작성된 변수와 함수 등등 사용하거나 기능을 변경(Override)할 수 있고,

각 클래스에서 새롭게 기능들을 추가할 수 있다.

class SportsScore {
    var teamAScore = 0
    var teamBScore = 0
    
    func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

class Soccer : SportsScore {
    var half = "전반전"
    override func displayScore() -> String {
        return half+" "+teamAScore.description + " : " + teamBScore.description
    }
}

class Baseball : SportsScore {
    var round = 1
    override func displayScore() -> String {
        return round.description+"회차 "+teamAScore.description + " : " + teamBScore.description
    }
}

class Volleyball : SportsScore {
    var set = 1
    override func displayScore() -> String {
        return set.description+"세트 "+teamAScore.description + " : " + teamBScore.description
    }
}

let soccerPlay = Soccer()
soccerPlay.teamAScore = 1
soccerPlay.teamBScore = 2
soccerPlay.half = "후반전"
soccerPlay.displayScore()

let baseballPlay = Baseball()
baseballPlay.teamAScore = 1
baseballPlay.teamBScore = 1
baseballPlay.round = 7
baseballPlay.displayScore()

let volleyballPlay = Volleyball()
volleyballPlay.teamAScore = 10
volleyballPlay.teamBScore = 11
volleyballPlay.set = 3
volleyballPlay.displayScore()

 

부모 클래스를 상속받아 자식 클래스는 기능들을 재정의하여 사용했는데

재정의를 막고 원래의 기능 그대로의 사용만 허용되는 경우,

class SportsScore {
    var teamAScore = 0
    var teamBScore = 0
    
    // final 키워드를 입력하면 상속받고 수정 불가능
    final func displayScore() -> String {
        return teamAScore.description + " : " + teamBScore.description
    }
}

displayScore 함수 앞에 final 키워드를 추가하면

override가 불가능해져서 재정의 했던 코드들에 오류가 나게 되고 기능의 추가, 변경 없이 displayScore 함수를 사용할 수 있다.

반응형