iOS/Swift

Swift) 오버로딩(Overloading) vs 오버라이딩(Overriding)

소들이 2021. 3. 29. 18:53

 

 

 

안녕하세요 :)))) 소들입니다

오늘은 음... 가볍게?? 가끔 헷갈리기 쉬운 용어인

 

오버로딩(Overloading)

오버라이딩(Overriding)

 

에 대해 정리해보고 가려고 해요!!!

용어가 비슷하다고 해서 개념도 비슷할 것 같지만, 전혀 다르고요..

 

Swift에서 오버라이딩은 이전 포스팅에서 아~~주 자세하게 공부 했었죠!?

따라서 이번 포스팅에선 가볍게만 알아볼 거예영 :D

절대 프로퍼티 포스팅 쓰다가 지쳐서 쉴라고 쓰는 거 아님. 아무튼 아님.

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1.  오버라이딩(Overriding)이란?

 

서브 클래스는 슈퍼 클래스에서 상속할 메서드, 프로퍼티, 서브스크립트를 

서브 클래스에서 원하는대로 구현(재정의) 할 수 있는데,

이것을 "오버라이딩(overriding)"이라 라고 한다

 

오버라이딩을 한 단어로 정의하자면 "재정의" 라구 했었음!

슈퍼클래스에서 상속할 메서드나 프로퍼티, 서브스크립트를 서브클래스에서 내맛대로 재정의 하는 것!

 

물론, Swift에서 이 오버라이딩에 대한 제한 조건은 꽤 있었음

프로퍼티의 경우 저장 속성만 추가할 수 있고, 이름과 타입을 반드시 명시해야하고,

final을 붙이면 더이상 상속이 불가능하거나 오버라이딩이 불가능하고 어쩌고 저쩌고

이 포스팅에선 그렇게 자세하겐 다루지 않을 것임!! 궁금하다면 이 포스팅을 봐주시길..

 

쨌든 만약 Human이란 기본 클래스가 있고,

 

 

class Human {
    func description() {
        print("나는 사람입니다")
    }
}
 
class Teacher: Human {
}

 

 

Teacher이란 클래스가 Human 클래스를 상속받을 경우

 

 

let sodeulTeacher = .init()
sodeul.description()

 

 

우린 ㅣㅇ렇게 Teacher 클래스 인스턴스로

description이란 메서드에 접근할 수 있음!! 왜냐?? 상속 받았으니까!

 

Teacher이란 클래스가 Human이란 클래스를 상속받기 때문에,

슈퍼클래스인 Human 클래스의 멤버들에 모두 접근 가능하기 때문!!!!

 

따라서 결과는 다음과 같이

 

 

 

 

Human에서 구현한 메서드가 제대로 실행 됨

근데 있잖음 Teacher이란 클래스가 까탈스러워서 description이란 메서드르 실행하면

"나는 선생입니다" 라는 출력을 하고 싶음..

 

그럼 이럴 때 쓰는 것이 바로 무엇????? 오버라이딩!! 재정의 ༼⁰o⁰;༽

 

 

class TeacherHuman {
    override func description() {
        print("나는 선생입니다")
    }
}

 

 

따라서 이렇게 override 키워드를 붙이고, 해당 메서드를 재정의 하면

이제 Teacher이란 클래스에 한해서, description 메서드는

 

 

 

 

이렇게 내가 재정의한 메서드로 불린다고 했음 :)

이것이 바로 오버라이딩!!!!! 그렇다면 이름도 비슷한 오버로딩은 뭘까 :)

 

 

 

 

2.  오버로딩(Overloading)이란?

 

함수 이름은 같으나 매개변수, 리턴타입 등을 다르게 하여 함수를 중복으로 선언할 수 있다

Swift는 오버로딩을 허용하며, 함수 & 서브스크립트 & 생성자에서 사용할 수 있다

 

사실 오버라이딩, 오버로딩은 Swift에 국한된 게 아니라, 객체지향 프로그래밍에서 쓰이는 개념임!!!

자, 만약에 우리가 육안으로 보기에도 모양새가 똑같은 함수를 동시에 선언 했음

 

 

func sum() { }
func sum() { }      // Invalid redeclaration of 'sum()'

 

 

이렇게! 그럼 이것은 에러가 뜸! 왜냐??

sum()이란 함수랑 똑~~같이 생긴 함수가 이미 정의되어 있기 때문에 에러가 뜸!!!!

 

자, 그럼 이렇게 똑같이 생긴 함수에다가,

파라미터를 추가한 함수와, 리턴타입을 추가한 함수를 각각 만들어 보겠음

 

 

func sum() { }
func sum(n: Int) { }
func sum() -> Int { return 0 }

 

 

오잉?? 세 함수의 이름이 sum으로 모두 동일하지만, 에러는 나지 않음!!

그말인 즉,  위 세 함수는 서로 다른 함수다!! 라는 것임

이것이 의미하는 것이 무엇일까??

 

함수를 식별할 땐 단순히 함수 이름을 보고 하는 게 아니라,

함수 이름, 파라미터(타입, 갯수, Argument Label), 리턴타입을 모두 종합해서 함수를 식별하는구나!!

 

라는 것임 :)

물론 위 함수 타입 또한 모두 각각 다를 것임!!

따라서 이름이 같은 함수라도 파라미터의 타입, 혹은 파라미터의 갯수, 혹은 파라미터의 Argument Label,

혹은 리턴타입 중 단 하나라도 다르다면, 그들은 모두 각기 다른 함수가 되는 것임!!!

 

자, 이렇게 오버로딩이 되는 것의 장점이 무엇이냐...

만약, 내가 파라미터로 두 개의 값을 받아서 더한 값을 리턴하고 싶음

이때, 파라미터로 받는 값은 Int, String, Double 타입을 받고 싶음!!

 

그러면, 만약 오버로딩이 불가능 했다면, 

다음과 같이 함수 이름으로 식별을 했어야 했을지도 모름

 

 

func sumInt(_ a: Int, _ b: Int-> Int {
    return a + b
}
 
func sumDouble(_ a: Double, _ b: Double-> Double {
    return a + b
}
 
func sumString(_ a: String, _ b: String-> String {
    return a + b
}

 

 

이렇게!!! 근데 함수 이름이 길어지고요....

실제로 호출할 때도, 필요로 하는 함수 이름 별로 호출해줘야 할 것임

 

 

sumInt(1, 2)
sumDouble(1.0, 2.0)
sumString("a", "b")

 

 

이렇게!!!! 흠 이게 물론 잘못된 코드는 아님!!!!

근데 Swift는 뭐닷?? 오버로딩이 가능하다!!!

따라서 다음과 같이 좀 더 함수를 🌸예쁘게🌸 짜줄 수 있음

 

 

func sum(_ a: Int, _ b: Int-> Int {
    return a + b
}
 
func sum(_ a: Double, _ b: Double-> Double {
    return a + b
}
 
func sum(_ a: String, _ b: String-> String {
    return a + b
}

 

 

이렇게 오버로딩을 이용하면, sum이란 함수 이름은 같지만

각각의 파라미터의 타입이 다르기 때문에 서로 다른 함수로 식별되어 위와 같이 선언할 수 있는 것임!!

 

이렇게 오버로딩 하여 선언할 경우, 실제 호출할 때 어떻게 하냐면

 

 

sum(1, 2)
sum(1.0, 2.0)
sum("a", "b")

 

 

이렇게 할 수있음! 이게 가능한 이유는, 함수를 호출할 때

오버로딩 된 함수 중, 모든 조건(파라미터 갯수, 타입, Argument Label, Return Type)에

알맞는 함수로 알아서 찾아가기 때문임!!

 

이것이 바로 오버로딩 :)

오버라이딩과는 정말 아예 다른 개념임!!!!

 

 

 

 

 

 

.

.

.

 

나는 헷갈리지 않지만 헷갈릴 누군가를 위해 포스팅 합니다 :)

(이래놓고 미래의 내가 헷갈릴 수도 있는 거고 ... )

오버라이딩과 오버로딩의 차이점!

혹시 잘못된 점이나 피드백, 궁금증은 언제든 댓글 주세요!