Swift 문법 6

이나래·2022년 10월 31일
  • 클래스

    class Man{
    var age : Int = 21
    var weight : Double = 33.5
    func display(){
    print("나이=(age), 몸무게=(weight)")
    }
    class func cM(){
    print("cM은 클래스 메서드입니다.")
    }
    static func scM(){
    print("scM은 클래스 메서드(static)")
    }
    }
    var kim : Man = Man()
    kim.display() //인스턴스 메서드는 인스턴스가 호출
    Man.cM() //클래스 메서드는 클래스가 호출
    Man.scM() //클래스 메서드는 클래스가 호출

  • self

    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)
    kim.display()

  • computed property

    class Man{
    var age : Int = 1 // stored property
    var weight : Double = 3.5 // stored property
    var manAge : Int{ //메서드 같지만 computed property임
    get{
    return age-1 // age에서 1을 빼겠다
    }
    }
    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)
    kim.display()
    print(kim.manAge)

/ 나이=10, 몸무게=20.5
9
/

  • computed property의 getter
    setter가 없으면 get{}은 생략할 수 있으며 변경하지 않더라도 var로 선언해야 함

class Man{
var age : Int = 1 // stored property
var weight : Double = 3.5 // stored property
var manAge : Int{ //메서드 같지만 computed property임
// get{
return age-1 // age에서 1을 빼겠다
// }
}
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)
kim.display()
print(kim.manAge)

/ 나이=10, 몸무게=20.5
9
/

  • computed property의 setter
    setter가 있으면 get{}은 생략할 수 없음

class Man{
var age : Int = 1
var weight : Double = 3.5
var manAge : Int{ // computed property
get{
return age-1
}
set(USAAge){
age = USAAge + 1
}
}
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)
kim.display()
print(kim.manAge) //9, getter호출
print(kim.age) //10
kim.manAge = 3 //setter호출
print(kim.age) //4

/ 9
10
4
/

  • computed property의 getter, setter
    setter의 매개변수명이 newValue인 경우에만 이렇게 "(newValue)" 생략 가능

class Man{
var age : Int = 1
var weight : Double = 3.5
var manAge : Int{
get{ return age-1 }
set{ age = newValue + 1 }
}
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)
kim.display()
print(kim.manAge) //9, getter호출
print(kim.age) //10
kim.manAge = 3 //setter호출
print(kim.age) //4

/
9
10
4
/

  • 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
}
init(age: Int){ //두번째
self.age = age
}
}
var kim : Man = Man(age:10, weight:20.5) //첫번째
var kim1 : Man = Man(age:20) //두번째
//var kim2 : Man = Man()
//init가 없다면 인스턴스 만드는 방법
kim.display()
kim1.display()

/ 나이=10, 몸무게=20.5
나이=20, 몸무게=3.5
/

  • crash 발생하는 오류와 .so 파일
    .so 나 .dvlib
    - shared object
    - shared library
    - 윈도우의 dll
    - 동적 링크 라이브러리 (프로그래미 실행 시 필요할 때 연결)

    .a
    - archive library
    - 정적 링크 라이브러리
    - 컴파일 시 포함됨

  • superclass와 subclass

  • 부모 클래스와 자식 클래스
    상속된 클래스는 부모 클래스의 모든 기능을 상속 받으며 자신만의 기능을 추가
    상속 받은 클래스들을 하위 클래스 또는 자식 클래스
    하위 클래스가 상속 받은 클래스는 부모 클래스 또는 상위 클래스
    단일 상속

  • swift에서 하위 클래스는 단 하나의 부모 클래스만 상속 받을 수 있음

  • 상속 : 부모가 가진 것을 물려 받기

    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 {
    //비어있지만 Man의 모든 것을 가지고 있음
    }

    var kim : Man = Man(age:21, weight:40.5)
    kim.display()
    var lee : Student = Student(age:20,weight:45.2)
    lee.display()
    print(lee.age)

/ 나이=21, 몸무게=40.5
나이=20, 몸무게=45.2
20
/

  • super : 부모 메서드 호출 시 사용

    class Man{
    var age : Int
    var weight : Double
    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:65.2,name:"홍길동")
    lee.displayS()
    lee.display()

/ 이름=홍길동, 나이=20, 몸무게=65.2
나이=20, 몸무게=65.20
/

  • override : 부모와 자식에 같은 메서드가 있으면 자식 우선
    부모와 자식에 display()라는 메서드가 있어서 Student 클래스는 display() 메서드가 두개임
    Student 클래스의 인스턴스 lee가 display()를 호출할 때 자식클래스가 새로 만든 display() 메서드가 우선적으로 호출되려면 func 앞에 override 키워드를 씀

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 = "김소프"
override func display() {
print("이름=(name), 나이=(age), 몸무게=(weight)")
}
init(age: Int, weight : Double, name : String){
super.init(age:age, weight:weight)
self.name = name
}
}
var lee : Student = Student(age:20,weight:65.2,name:"홍길동")
lee.display()

// 이름=홍길동, 나이=20, 몸무게=65.2

  • extension

    extension Double {
    var squared : Double { //기존 Double형 구조체에 계산 프로퍼티 추가
    return self * self
    }
    }
    let myValue: Double = 5.0
    print(myValue.squared) //과제
    print(2.0.squared) //Double형 값에도 .으로 바로 사용 가능, 과제

/ 25.0
4.0
/

  • Swift의 access control

public class MyClass{
// 모듈의 모든 소스 파일 내에서 접근 + 정의한 모듈은 가져오는 다른 모듈의 소스파일에서도 접근 가능
fileprivate var name : String = "kim"
// 현재 소스 파일 내에서만 사용 가능
private func play() {]
// 현재 블럭 내에서만 사용 가능
func display(){} // internal은 디폴트 속성으로 생략됨
// 해당 모듈의 모든 소스 파일 내에서 사용
}

  • 접근 제어
    모듈은 코드 베포(code distribution)의 단일 유닛
    open 접근 및 public 접근을 통해 모듈의 모든 소스 파일 내에서 사용할 수 있으며 정의한 모듈을 가져오는 다른 모듈의 소스파일에서도 사용할 수 있음
    internal 접근은 해당 모듈의 모든 소스 파일 내에서 사용되지만 해당 모듈 외부의 소스파일에서는 사용되지 않도록 함
    fileprivate 접근은 해당 소스 파일 내에서만 사용 가능
    private 접근은 블록과 동일한 파일에 있는 해당 선언의 extension으로 제한

  • Type Property

    class SClass {
    var storedProperty = 2
    static var storedTypeProperty = 1
    static var computedTypeProperty: Int {
    return 10
    }
    class var overrideableComputedTypeProperty: Int {
    return 100
    }
    }
    var x = SClass()
    print(x.storedProperty) //2
    print(SClass.storedTypeProperty) //1
    print(SClass.computedTypeProperty) //10
    print(SClass.overrideableComputedTypeProperty) //100

  • 프로토콜(protocol) 정의, 채택, 준수
    특정 클래스와 관련 없는 함수(메서드)들의 선언 집합

protocol Runnable { //대리하고 싶은 함수 목록 작성
var x : Int {get set} //읽기와 쓰기 가능 프로퍼티,{get}은 읽기 전용
//property in protocol must have explicit { get } or { get set } specifier
func run() //메서드는 선언만 있음
}
class Man : Runnable { //채택, adopt
var x : Int = 1 //준수, conform
func run(){print("달린다~")} //준수, conform
}

  • delegate
    대리자, 조력자
    델리게이트로 선언된 객체는 자신을 임명한 객체(테이블 뷰, 피커뷰 등) 일을 도와달라고 하면 지정된 메서드를 통해 처리해 줌
    델리게이트 패턴
    - 하나의 객체가 모든 일을 처리하는 것이 아니라 처리 해야할 일 중 일부를 다른 객체에 넘기는 것
  • 과제

    protocol B{ // bb라는 메소드가 있는 프로토콜 B
    func bb(x:Int) -> Int // Int 값을 매개변수로 받고 Int형으로 리턴
    }
    class C{} // 상속을 위한 클래스 C 선언
    class A : C, B{ // 클래스 C로부터 상속 받음, A에서 프로토콜 B를 채택
    func bb(x:Int) -> Int { // 준수
    return x*2
    }
    }
    let a : A = A() // 클래스 A의 인스턴스 a
    print(a.bb(x:3)) // bb를 호출 (argument 3)

< 인덕대학교 iOS 앱 프로그래밍 한성현 교수님 강의 자료 참고 >

0개의 댓글