[Swift 기초] 클래스와 상속

2022. 4. 2. 16:55Swift 기초 정리

728x90

//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎

 

 

0. 참고

  • 함수: func 키워드로 생성하는 것
  • 메서드: 클래스, 구조체, 열거형 속에 포함되어 있는 함수
    • 인스턴스 메서드: 인스턴스를 생성해야만 호출 가능한 함수, 생성된 인스턴스에 .(dot)문법을 통해 접근
    • 타입 메서드: 인스턴스 생성 없이 타입의 이름만 알면 호출 가능, static 혹은 class가 붙으면 타입 메서드

 

1. 클래스

  • 클래스(class): 실제 세계의 객체를 우리의 앱에 나타내기 위해 설계된 코드 모듈이다. 앱의 구성 요소로 사용
    • 클래스를 사용하면 프로그램에서 사용할 수 있는 객체를 추상화 할 수 있다.
실제 세계) 실제 객체로 자동차 
		- 빨간색 차, 문이 4개, 최고 속도가 120마일, 2015년 생산
        - 가속한다, 감속한다, 회전한다 등의 액션을 수행
        - 자동차 구매
코드) 자동차의 의미를 나타내기 위해 자동차 클래스 생성 
		- 컬러 속성, 스타일 속성, 스피드 속성, 제작년도 속성
		- 가속한다(), 감속한다(), 회전한다() 등의 메서드로 갖는다
        - 자동차 클래스의 인스턴스(instance) 생성
  • 클래스를 통하여 인스턴스 속성(프로퍼티)와 메서드를 정의한다.
  • 객체를 초기상태로 설정하는 초기화 블록을 정의할 수 있다.
  • 객체의 기능을 확장, 클래스 상속, 인스턴스 소멸 시 해제 기능을 가진다.
  • 클래스를 사용하면 우리 코드에서 사용할 실제 세계 객체의 추상화된 표현을 만들 수 있다. 이러한 추상화는 객체지향 프로그래밍의 핵심이며, 모듈화 된 프로그램을 생성할 수 있게 해 준다.

1-1. 클래스 구조

class Dog{
    //속성
    //이니셜라이저
    //메서드
}
  • “Dog” 클래스는 코드로 표현된 멍멍이의 청사진 = “Dog” 클래스는 멍멍이의 모든 속성을 포함하며, 모든 행동을 정의한다.

1-2. 클래스 속성과 이니셜라이저

class Dog{
    //속성
    var Name: String
    var Breed: String
    var Age: Int
}
  • class Dog ‘Dog’라는 이름의 클래스를 생성
  • {} 클래스의 속성(property)과 메서드(method)를 포함하는 코드 블록을 정의
  • 속성 특정 클래스에 값을 연관시키는 수단, 실제 세계의 객체가 갖는 특성을 나타냄
    • 저장(stored) 속성: 상수나 변수의 값을 저장
    • 연산(computed) 속성
  • 클래스를 정의할 때, 속성에는 어떠한 값도 지정되지 않는다. 인스턴스로 만들(instantiate) 각 멍멍이는 향후에 서로 다른 name, breed, age 값을 가질 것이기 때문
    //Stored property 'Name' without initial value prevents synthesized initializers
    //Stored property 'Breed' without initial value prevents synthesized initializers
    //Stored property 'Age' without initial value prevents synthesized initializers
    • 속성에 값을 지정할 방법이 없다는 에러 메세지
    • 클래스 정의에서 모든 속성에 디폴트 값을 지정할 수 있지만 그 대신 이니셜라이저(initializer)를 생성해서 값을 지정한다.
      class Dog{
          //속성
          var Name: String
          var Breed: String
          var Age: Int
          
          //이니셜라이저(initializer)
          init(name: String, breed: String, age: Int){
              Name = name
              Breed = breed
              Age = age
          }
      }
      • init 이니셜라이저 키워드, 클래스의 인스턴스를 생성할 때마다 매번 실행된다.
      • 클래스의 속성을 초기화하며, 클래스의 인스턴스를 생성할 때 전달될 필요가 있는 인자를 받는다.
      • 이니셜라이저 내부에서는 인자(”name”, “breed”, “age”)로 전달된 값들을 각 속성(”Name”, “Breed”, “Age”)에 지정한다.

1-3. 클래스 메서드

class Dog{
    //속성
    //이니셜라이저(initializer)
    
	//메서드
    func sit(){
        print("\(Name) is sitting")
    }
    func bark(){
        print("\(Name) is barking")
    }
    func run(){
        print("\(Name) is running")
    }
    
    //클래스의 메서드를 통해서 속성을 액세스
    func getName() -> String{
        return Name
    }
    func getBreed() -> String {
        return Breed
    }
    func getAge() -> Int {
        return Age
    }
}
  • 클래스에 포함된 함수는 클래스와 연관되며 메서드(method)라고 한다.
  • 클래스 속성은 도트(.) 표기를 사용해서 직접 참조할 수 있지만, 클래스의 메서드를 통해서 속성을 액세스 하는 것이 더 안전하다.
    • 해당 속성의 값을 반환
//인스턴스 생성
let aDog = Dog(name:"까미", breed:"mola", age:8)
let bDog = Dog(name:"망고", breed:"mola", age:2)
let cDog = Dog(name:"초코", breed:"big", age:2)

aDog.bark()    //까미 is barking
bDog.run()     //망고 is running
cDog.sit()     //초코 is sitting

print(aDog.getAge())      //8
print(bDog.getBreed())    //mola
print(cDog.getName())     //초코
  • 클래스에 정의된 메서드를 액세스 할 때는 도트 표기를 사용

전체 코드

더보기
class Dog{
    //속성
    var Name: String
    var Breed: String
    var Age: Int
    
    //이니셜라이저(initializer)
    init(name: String, breed: String, age: Int){
        Name = name
        Breed = breed
        Age = age
    }
    
		//메서드
    func sit(){
        print("\(Name) is sitting")
    }
    func bark(){
        print("\(Name) is barking")
    }
    func run(){
        print("\(Name) is running")
    }
    
    //클래스의 메서드를 통해서 속성을 액세스
    func getName() -> String{
        return Name
    }
    func getBreed() -> String {
        return Breed
    }
    func getAge() -> Int {
        return Age
    }
}

 

2. 클래스의 상속과 재정의

2-1. 서브 클래스

  • 객체(object): 클래스의 인스턴스
  • 객체지향 프로그래밍(OOP, Object-Oriented-Programming)에서는 프로그램의 기반으로 객체와 그것의 메서드 및 속성을 사용한다.
    • OPP를 가장 효과적으로 하려면 잘 정의된 객체들로 추상화된 클래스 계층 구조 ⇒ 서브 클래스
  • 서브 클래스(subclass)
    • 부모 클래스의 계층적인 자식(계층의 레벨에 따라 직계이거나 더 아래 자손이 될 수도 있다)
    • 부모 클래스의 속성과 메서드를 공유한다,
    • 서브 클래스 자체로도 충분히 구체적인 클래스
    • 예) Vehicle - Car, Vehicle - Truck
      • 더 넓은 개념의 클래스인 Vehicle을 정의하여 Car과 Truck 클래스 모두에 공통적으로 속하는 메서드와 속성을 포함하게 하는 것이 좋다.
      • Vehicle: 더 일반화된 부모 클래스
      • Car, Truck: 더 특화된 자식 클래스,
    • 자식 클래스는 부모 클래스가 갖는 메서드와 속성을 상속받는다.
    • 부모 클래스는 자신의 자식으로부터 상속받지 않는다.
    • 계층 구조의 같은 레벨에 있는 형제 클래스 또한 상호 간에는 상속받지 않는다.
    • 자식 클래스는 자신만의 고유한 속성과 메서드를 추가로 가질 수 있다.
class 이름: 상속받을 클래스 이름 {
	/*코드 구현*/
}
  • 상속: 반복적친 코딩을 줄여주며 재사용성이 높아진다. 전체적으로 코딩의 효율성이 증대된다. 오버라이딩을 통해서 상위 클래스의 기능을 보완할 수 있다.

2-1. 기반 클래스(부모 클래스)

class Person{
    var name: String = ""
    func selfIntroduce() {
        print("original) 저는 \\(name)입니다.")
    }

    //final 키워드: 재정의 방지
    final func sayHello(){
        print("original) hello")
    }
    
    //타입 메서드 - 재정의 불가 타입 메서드: static
    static func staticTypeMethod() {
        print("original) type method - static")
    }
    
    //타입 메서드 - 재정의 가능 타입 메서드: class
    class func classTypeMethod() {
        print("original) type method - class")
        //서브 클래스를 생성할 때 자기 특유의 classTypeMethod() 메서드 버전을 구현
    }
    
    //재정의 가능한 class 메서드라도 final 키워드를 사용하면 제정의 할 수 없다.
    //static 역할 == final class 역할
    final class func finalCalssMethod(){
        print("original) type method - final class")
    }
}
  • override 오버라이딩: 부모 클래스의 메소드를 물려받아 추가적인 기능을 확장하는 기능
  • 재정의(override) 할 수 없음: final, static, final class
    • 보안상 필요한 경우나 상속을 목적으로 하지 않는 클래스의 경우에 사용
  • 재정의(override) 할 수 있음: class

2-2. 상속받는 클래스(서브 클래스)

//Person을 상속받는 Student
class Student: Person{
		
	//name 프로퍼티를 상속받아 온 것, 저장 프로퍼티는 override 할 수 없다.
	//Cannot override with a stored property 'name'
	//var name: String = ""
    var major: String = ""
    override func selfIntroduce() {
        print("override) 저는 \\(name)이고, 전공은 \\(major)입니다.")
				
		//부모클래스의 메서드 호출
		super.selfIntroduce()
    }
    
    override class func classTypeMethod(){
        print("override) overrien type method - class")
    }
    
    //static을 사용한 타입 메서드는 재정의 할 수 없습니다.
    //Cannot override static method
    //override static func staticTypeMethod() {}
    
    //final 키워드를 사용한 메서드, 프로퍼티는 재정의 할 수 없습니다
    //Instance method overrides a 'final' instance method
    //override func sayHello() {}
    
    //final 키워드를 사용한 메서드, 프로퍼티는 재정의 할 수 없습니다
    //Method does not override any method from its superclass
    //override class func finalClassMethod() {}
}
  • class 서브클래스명: 부모클래스명 부모 클래스로부터 상속받는 서브 클래스를 생성하라
  • override 부모 클래스로부터 상속받은 메서드를 변경하는 서브 클래스 메서드
    • 저장 프로퍼티는 override 할 수 없다.
  • super 현재 클래스의 부모 클래스를 참조하는 참조자
    • super.init() 초기화 블록이나, super.func() 메서드를 호출하여 부모 클래스의 메서드를 사용할 수 있다.
  • static을 사용한 타입 메서드는 재정의 할 수 없다.
  • final 키워드를 사용한 메서드, 프로퍼티는 재정의할 수 없다.

2-3. 결과 비교

//클래스의 객체 생성하기 - 일반 클래스의 객체 생성과 동일
let p: Person = Person()
let s: Student = Student()

p.name = "김정우"       
s.name = "최연준"    
//p는 major가 없다.
//p.major            
s.major = "handsome"

p.selfIntroduce()    //original) 저는 김정우입니다.
s.selfIntroduce()    //override) 저는 최연준이고, 전공은 handsome입니다.
                     //original) 저는 최연준입니다. - 부모클래스 호출

Person.classTypeMethod()    //original) type method - class
Person.staticTypeMethod()   //original) type method - static
Person.finalCalssMethod()   //original) type method - final class 

Student.classTypeMethod()    //override) overrien type method - calss
Student.staticTypeMethod()   //original) type method - static
Student.finalCalssMethod()   //original) type method - final calss

 

 

 

참고하였습니다. 감사합니다.

https://yagom.net/courses/swift-basic/lessons/타입-심화/topic/상속/

 

스위프트 기초 - 야곰닷넷

스위프트는 문법표현의 다양성이 매우 높은 언어입니다. 그래서 스위프트 문법의 모든 형태를 알기는 꽤 오랜 시간이 걸립니다. 그렇지만 최소한의 핵심 문법을 통해 무리없이 스위프트 문법을

yagom.net

https://www.inflearn.com/course/창원대학교-박동규-교수의-swift-기초-강좌/lecture/1901?tab=note 

 

학습 페이지

 

www.inflearn.com

23.07.06 수정) Swift 쉽게, 더 쉽게

https://www.yes24.com/Product/Goods/17652267

728x90