본문 바로가기
모바일앱/Swift

상속 개념을 코드로 익히기

by GeekCode 2021. 10. 18.
반응형

기본적인 형태

class Parent

class Child : Parent

 

Person : Super Class

Student: Sub Class (Child Class)

 

 

 

아래 코드를 보자 

 

Person과 Student라는 클래스가 두개 있다.  자세히보면 같은 내용의 코드들이 중복되어있는 것을 알수있다. 

이럴때 상속이라는 개념을 적용할 수 있다. 

struct Grade {
    var letter: Character
    var points: Double
    var credits: Double
}

class Person {
    var firstName: String
    var lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func printMyName() {
        print("My name is \(firstName) \(lastName)")
    }
}

class Student {
    var grades: [Grade] = []

    var firstName: String
    var lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func printMyName() {
        print("My name is \(firstName) \(lastName)")
    }
}

저 관계를 생각해보자

학생은 사람인가?

사람은 학생인가?

사람 이라는 개념 안에 학생이라는 개념이 들어가게 된다. 그러면 학생이라는 특징은 사람에게 나올수 없지만

사람이라는 특징은 학생이 가질 수 있게된다.

class Student: Person {
    var grades: [Grade] = []
//
//    var firstName: String
//    var lastName: String
//
//    init(firstName: String, lastName: String) {
//        self.firstName = firstName
//        self.lastName = lastName
//    }
//
//    func printMyName() {
//        print("My name is \(firstName) \(lastName)")
//    }
}

 

// 처음 주어진 코드
struct Grade {
    var letter: Character
    var points: Double
    var credits: Double
}

class Person {
    var firstName: String
    var lastName: String

    init(firstName: String, lastName: String) {
        self.firstName = firstName
        self.lastName = lastName
    }

    func printMyName() {
        print("My name is \(firstName) \(lastName)")
    }
}

class Student: Person {
    var grades: [Grade] = []
//
//    var firstName: String
//    var lastName: String
//
//    init(firstName: String, lastName: String) {
//        self.firstName = firstName
//        self.lastName = lastName
//    }
//
//    func printMyName() {
//        print("My name is \(firstName) \(lastName)")
//    }
}

let jay = Person(firstName: "Jay", lastName: "Kim")
let jason = Student(firstName: "Jason", lastName: "Lee")

jay.firstName  //jay
jason.firstName  //jason

jay.printMyName() // My name is Jay Kim
jason.printMyName()  // My name is Jason Lee

let math = Grade(letter: "B", points: 8.5, credits: 3)
jason.grades.append(math) //[{letter "B", points 8.5, credits 3}]

jay.grades //!! Value of type 'Person' has no member 'grades'
//---> Jay는 Person으로 만들어진 인스턴스 이므로 Student의 내용을 가질 수 없다.
// 사람이긴 하지만 학생은 아니다

let history = Grade(letter: "A", points: 10.0, credits: 3)
jason.grades.append(history)

jason.grades
//[{letter "B", points 8.5, credits 3}, {letter "A", points 10, credits 3}]
jason.grades.count //2

 

 

상속의 규칙

1. 자식은 한개의 superclass만 상속받을 수 있다.

2. 부모는 여러자식들을 가질수 있다.

3. 상속의 깊이는 상관이 없다.

 

 

// 학생인데 운동선수

// 운동선수인데 축구선수

// Person > Student > Athelete > Football Player

 

// 학생인데 운동선수
class StudentAthlete: Student {
    var minimumTrainingTime: Int = 2
    var trainedTime: Int = 0
    
    func train() {
        trainedTime += 1
    }
}

// 운동선수인데 축구선수
class FootballPlayer: StudentAthlete {
    var footballTeam = "FC Swift"
    
    override func train() {
        trainedTime += 2
    }
}

// Person > Student > Athelete > Football Player

var athelete1 = StudentAthlete(firstName: "Yuna", lastName: "Kim")
var athelete2 = FootballPlayer(firstName: "Heung", lastName: "Son")

athelete1.firstName
athelete2.firstName

athelete1.grades.append(math)
athelete2.grades.append(math)

athelete1.minimumTrainingTime
athelete2.minimumTrainingTime

//athelete1.footballTeam
athelete2.footballTeam

athelete1.train()
athelete1.trainedTime

athelete2.train()
athelete2.trainedTime



athelete1 = athelete2 as StudentAthlete
athelete1.train()
athelete1.trainedTime



//다운캐스팅
if let son = athelete1 as? FootballPlayer {
    print("--> team:\(son.footballTeam)")
}

 

 

반응형