iOS Swift - Inheritance

longlivedrgn·2022년 9월 3일
0

swift문법

목록 보기
16/36
post-thumbnail

Inheritance

  • 기본 꼴
lass Figure {
    var name = "Unknown"
    
    init(name: String) {
        self.name = name
    }
    
    func draw() {
        print("draw \(name)")
    }
}

// Circle은 Figure에게 상속을 받는다.
class Circle: Figure {
    var radius = 0.0
}

let c = Circle(name: "Circle")
c.radius //0
c.name // "Circle"
c.draw() // draw Circle

final class

  • final Class는 상속이 불가능하다.
// final class는 상속이 불가하다.
final class Rectangle: Figure {
    var width = 0.0
    var height = 0.0
}


class Square: Rectangle {
// 에러!
}

Overriding

  • super class에 있는 것 상속받아 다시 정의해주는 것이다.
class Figure {
   var name = "Unknown"

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

   func draw() {
      print("draw \(name)")
   }
}

// circle에도 draw가 있다 -> override
class Circle: Figure {
    var radius = 0.0
    override func draw() {
       print("🌻")
    }
}

let c = Circle(name: "Circle")
c.draw() //🌻

Upcasting & Download Casting

  • Upcasting -> 상위 클래스의 Property에만 접근할 수 있다.
class Figure {
    let name: String
    
    init(name: String) {
        self.name = name
    }
    
    func draw() {
        print("draw \(name)")
    }
}

class Rectangle: Figure {
    var width = 0.0
    var height = 0.0
    
    override func draw() {
        // Figure의 draw도 사용하고 싶다면!
        super.draw()
        print("⬛️ \(width) x \(height)")
    }
}

class Square: Rectangle {
}
  • 위와 같이 class를 정의해보자

Upcasting

let s: Figure = Square(name: "Square")
//s.width // 에러
//s.height // 에러
s.name // "Square"

-> s는 Square이지만, Figure로 Upcasting을 하였기에 Figure의 Property에만 접근을 할 수 있다.

Downcasting

  • Upcasting된 것을 원상복구하기
// s는 s: Figure = Square(name: "Square")로 upcasting이 되어있다.
let downcastedS = s as! Square
downcastedS.width // 0
downcastedS.height // 0
downcastedS.height // 0

단, 원본 클래스보다 아래인 클래스로 downcasting하는 것은 불 가능하다.

class Rhombus: Square {
    var angle = 45.0
}

// 원본 클래스보다 아래인 클래스로 downcasting하는 것은 불 가능하다.
let dr = s as! Rhombus // 에러

Type casting

  • 인스턴스의 타입을 검사하는 방법

아래와 같이 class들을 설정해주자.

class Figure {
   let name: String
   
   init(name: String) {
      self.name = name
   }
   
   func draw() {
      print("draw \(name)")
   }
}

class Triangle: Figure {
   override func draw() {
      super.draw()
      print("🔺")
   }
}

class Rectangle: Figure {
   var width = 0.0
   var height = 0.0
   
   override func draw() {
      super.draw()
      print("⬛️ \(width) x \(height)")
   }
}

class Square: Rectangle {
   
}

class Circle: Figure {
   var radius = 0.0
   
   override func draw() {
      super.draw()
      print("🔴, \(radius)")
   }
}

Type Check Operator

기본 꼴

expression is Type
  • 아래와 같이 판단을 할 수 있다.
let  num = 123
num is Int // true
num is Double // false
num is String // false

let t = Triangle(name: "Triangle")
let r = Rectangle(name: "Rect")
let s = Square(name: "Square")
let c = Circle(name: "Circle")

r is Rectangle // true
r is Figure // true
r is Square // false

Type Casting Operator

-> as?/ as!로 할 수 있다(Down Casting)

  • 아래와 같이 상수를 생성해보자
let t = Triangle(name: "Triangle")
let r = Rectangle(name: "Rect")
let s = Square(name: "Square")
let c = Circle(name: "Circle")
// 원래 형식으로 casting
t as? Triangle
t as! Triangle
  • Upcasting을 해보자
// upcasting
var upcasted: Figure = s
  • as를 사용하여 DownCasting을 해보자
// downcasting -> 아래 코드들은 에러가 나지 않는다.
upcasted as? Square
upcasted as! Square
upcasted as? Rectangle
upcasted as! Rectangle
  • 근데 만약 Circle로 다운캐스팅을 시도한다면?
upcasted as? Circle // nil
upcasted as! Circle // error
  • if let을 통하여 downcasting을 할 수 있다.
// Circle로 다운캐스팅이 되지않기에 아무일도 일어나지 않는다.
if let c = upcasted as? Circle {
    print("text")
}

또 다른 예)

// [배열] 안에서는 가장 인접한 superclass로 다 upcasting된다. 즉 list는 Figure이다.
let list = [t, r, s, c]

// polymorphism -> 현재 figure로 upcastinge되어있다.
for item in list{
    // 비록 figure로 되어있지만, 각자 override된 method가 실행이된다.
    item.draw()
    // radius를 가져오고싶다면? -> Circle로 downcasting을 하자.(optional로)
    if let c = item as? Circle {
        print(c.radius)
    }
}

참고 및 출처자료 - https://zeddios.tistory.com/265

Any, AnyObject

--> 다시 공부해보기

// Any를 사용하면 형식에 관계없이 모든 데이터를 저장할 수 있음
var data: Any = 1
data = 2.3
data = "str"
data = [1, 2, 3]
data = NSString()

var obj: AnyObject = NSString()
//obj = 1 // error

// Any, AnyObject를 사용할 경우, typecasting을 사용해주어야된다.
if let str = data as? String {
    print(str.count)
} else if let list = data as? [Int]{
    
}

Type Casting Pattern

switch data{
case let str as String:
    print(str.count)
case let list as [Int]:
    print(list.count)
case is Double:
    print("Double Value")
default:
    break
}

0개의 댓글