Swift 공부 3

Paul Mo·2023년 10월 23일
0
post-thumbnail

Objects and Classes

클래스를 생성하려면 'class' 다음에 클래스의 이름을 작성한다. 클래스 내의 속성 선언은 상수나 변수 선언과 동일한 방식으로 작성되지만 클래스의 문맥 내에서 이루어진다. 마찬가지로, 메서드와 함수 선언도 동일한 방식으로 작성한다.

class Shape {
    var numberOfSides = 0
    func simpleDescription() -> String {
        return "A shape with \(numberOfSides) sides."
    }
}

클래스의 인스턴스를 만들려면 클래스 이름 뒤에 괄호를 넣는데, 인스턴스의 속성과 메서드에 접근하려면 점 구문(dot syntax)을 사용한다.

var shape = Shape()
shape.numberOfSides = 7
var shapeDescription = shape.simpleDescription()

초기화 프로그램의 인수는 클래스의 인스턴스를 생성할 때 함수 호출처럼 전달된다. 각 속성은 값을 할당해야 하는데, 이 값은 선언에서(예: numberOfSides) 또는 초기화 프로그램에서(예: name) 지정할 수 있다.

객체가 해제되기 전에 어떤 정리 작업을 수행해야 하는 경우 디이니셜라이저(deinitializer)를 만들려면 'deinit'을 사용하면 된다.

서브클래스는 클래스 이름 뒤에 콜론으로 구분하여 슈퍼클래스 이름을 포함한다. 클래스는 표준 루트 클래스를 상속하도록 요구되지 않으므로 필요에 따라 슈퍼클래스를 포함하거나 생략할 수 있다.

슈퍼클래스의 구현을 재정의하는 서브클래스의 메서드는 'override'로 표시된다. 오버라이딩한 메서드가 실수로 'override' 없이 오버라이딩되는 경우 컴파일러는 오류로 감지한다. 컴파일러는 슈퍼클래스의 메서드를 실제로 오버라이드하지 않는 'override'가 있는 메서드도 감지한다.

class NamedShape {
    var numberOfSides: Int = 0
    var name: String


    init(name: String) {
       self.name = name
    }


    func simpleDescription() -> String {
       return "A shape with \(numberOfSides) sides."
    }
}

class Square: NamedShape {
    var sideLength: Double


    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 4
    }


    func area() -> Double {
        return sideLength * sideLength
    }


    override func simpleDescription() -> String {
        return "A square with sides of length \(sideLength)."
    }
}
let test = Square(sideLength: 5.2, name: "my test square")
test.area()
test.simpleDescription()

저장된 간단한 속성뿐만 아니라 속성은 getter와 setter를 가질 수 있다.

class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0


    init(sideLength: Double, name: String) {
        self.sideLength = sideLength
        super.init(name: name)
        numberOfSides = 3
    }


    var perimeter: Double {
        get {
             return 3.0 * sideLength
        }
        set {
            sideLength = newValue / 3.0
        }
    }


    override func simpleDescription() -> String {
        return "An equilateral triangle with sides of length \(sideLength)."
    }
}
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle")
print(triangle.perimeter)
// Prints "9.3"
triangle.perimeter = 9.9
print(triangle.sideLength)
// Prints "3.3000000000000003"

'perimeter'의 setter에서, 새 값은 암시적으로 'newValue'라는 이름을 가지게 된다. 'set' 다음에 괄호 안에 명시적인 이름을 제공할 수도 있다.

EquilateralTriangle 클래스의 initializer에는 세 가지 다른 단계가 있다.

  1. 서브클래스에서 선언한 속성의 값을 설정
  2. 슈퍼클래스의 이니셜라이저를 호출
  3. 슈퍼클래스에서 정의한 속성의 값을 변경. 또한 메서드, 게터 또는 세터를 사용하는 추가 설정 작업을 이 시점에서 수행할 수도 있다.

만약 속성을 계산할 필요는 없지만, 새 값을 설정하기 전후에 실행되는 코드를 제공해야 하는 경우 'willSet' 및 'didSet'을 사용한다. 제공한 코드는 초기화 이외의 경우에 값이 변경될 때마다 실행되는데, 아래의 클래스는 예를 들어, 삼각형의 변의 길이가 항상 사각형의 변의 길이와 동일하도록 보장한다. 이를 위해 didSet를 사용하여 sideLength 속성의 변경을 관찰하고, 변경될 때마다 사각형과 삼각형의 변의 길이를 동기화한다.

class TriangleAndSquare {
    var triangle: EquilateralTriangle {
        willSet {
            square.sideLength = newValue.sideLength
        }
    }
    var square: Square {
        willSet {
            triangle.sideLength = newValue.sideLength
        }
    }
    init(size: Double, name: String) {
        square = Square(sideLength: size, name: name)
        triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
// Prints "10.0"
print(triangleAndSquare.triangle.sideLength)
// Prints "10.0"
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.triangle.sideLength)
// Prints "50.0"

옵셔널 값을 작업할 때는 메서드, 속성 및 서브스크립트와 같은 연산 앞에 '?'를 작성할 수 있다. '?' 앞의 값이 nil인 경우, '?' 이후의 모든 것은 무시되고 전체 표현식의 값은 nil이 된다. 그렇지 않으면 옵셔널 값이 언래핑되고, '?' 이후의 모든 것은 언래핑된 값에 작용한다. ? 앞의 값이 nil인 경우와 nil이 아닌 경우 모두 전체 표현식의 값은 옵셔널 값이다. 자바스크립트의 옵셔널 체이닝과 비슷한 개념 같다. 옵셔널 체이닝을 사용하면 TypeError가 발생하지 않고 undefined를 반환하는 것처럼 swift는 nil을 반환한다.

let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square")
let sideLength = optionalSquare?.sideLength

참조: https://docs.swift.org/swift-book/documentation/the-swift-programming-language/guidedtour/#Objects-and-Classes

profile
프론트 엔드 개발자

0개의 댓글

관련 채용 정보