ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • swift - Inheritance and Polymorphism #1 (Inheritance, Final Class, override, Upcasting, Downcasting)
    swift 2021. 1. 12. 12:34

    Inheritance

    네 군데 모두 동일한 속성을 선언하면 매우 불합리한 코딩

     

    공유되는 속성을 하나 선언하고 네개의 클래스가 하나의 속성을 상속받아서 사용

     

    swift는 다중상속을 지원하지 않고 protocal을 사용해서 해결

     


    // BaseClass
    class Figure {
        var name = "Unknown"
        
        init(name: String) {
            self.name = name
        }
        
        func draw() {
            print("draw \(name)")
        }
    }
    
    class Cirlce: Figure {
        var radius = 0.0
        var diameter: Double {
            return radius
        }
        override func draw() {
            super.draw()
            print("radius \(radius)")
        }
    }
    
    
    let c = Cirlce(name: "jaeho") // 상속받은 init사용
    c.radius
    c.name // 상속받은 속성 사용
    c.draw() // 상속받은 메소드 override해서 사용
    
    
    // 속성 override 하는 방법
    // 1. computed property 방식
    class Oval: Cirlce {
        
        override var radius: Double {
            // 읽기, 쓰기 모두 되는 속성인 경우
            get {
                return super.radius
            }
            set {
                super.radius = newValue
            }
        }
        
        override var diameter: Double {
            get {
                return super.diameter
            }
            set {
                super.radius = newValue / 2
                // 읽기전용 속성에는 값을 set할수 없고 다른 속성에 set하게 만들 수 있음
                // super.diameter = 11
            }
        }
    }
    
    // 2. property observer 방식
    class Oval2: Cirlce {
        override var radius: Double {
            willSet {
                print(newValue)
            }
            didSet {
                print(oldValue)
            }
        }
        
        // read-only속성은 값을 감시할 수가 없다 -> 즉 읽기전용에서는 property observer방식 불가능
    //    override var diameter: Double {
    //        willSet {
    //            print(newValue)
    //        }
    //        didSet {
    //            print(oldValue)
    //        }
    //    }
    }
    
    // 클래스를 상속 하게 할 수 있고 특정 메소드를 override 금지시키기
    // 금지하고 싶은 변수, 메소드에 final 키워드 추가

     

    final class Rectangle: Figure {
        var width = 0.0
        var height = 0.0
    }
    
    // final class는 상속이 금지된 클래스임
    class Square: Rectangle {
        
    }

    Upcasting

     서브 클래스 인스턴스를 슈퍼 클래스 형식으로 저장

     

    class Rectangle: Figure {
        var width = 0.0
        var height = 0.0
        
        override func draw() {
            super.draw()
            print("😀 \(width) x \(height)")
        }
    }
    
    class Square: Rectangle {
        
    }
    
    let f = Figure(name: "Unknown")
    f.name
    
    let r = Rectangle(name: "Rect")
    r.width
    r.height
    r.name
    
    // Upcasting
    // 서브 클래스 인스턴스를 슈퍼클래스 형식으로 저장
    let s: Figure = Square(name: "Square")
    s.height
    s.name
    s.width
    s.draw()

    이 상태에서는 밑에 그림처럼 width, height도 메모리 공간에 생성되긴 하지만 Figure클래스의 name에만 접근 할 수 있는 형태이다.


    Downcasting

    // Downcasting
    // Upcasting된 인스턴스를 원래 형식으로 처리하기 위해 필요
    // 항상 성공하는게 아님
    let downcastedS = s as! Square
    downcastedS.name
    downcastedS.width
    downcastedS.height
    
    
    

    class Rhombus: Square {
        var angle = 45.0
    }
    
    let dr = s as! Rhombus

    s라는 Figure 클래스에는 name, width, height가 있는데 Rhombus로 downcasting하려면 err가 발생한다.

     

    왜? Rhombus에 선언된 angle이라는 변수는 Figure 클래스에 존재하지 않기 때문에

    댓글

Designed by Tistory.