반응형

 

Method Overloading, 메서드 오버로딩.

메서드 오버로딩된 메서드가 있다면, 그 메서드들도 실행되는 우선순위가 존재한다.

 

여러 가지 상황을 코드로 구현하여, 오버로딩된 메서드 중에 어떠한 메서드가 우선 실행되는지 알아보자.

그전에, Method Overloading / Method Override(메서드 오버라이드)에 대한 차이점부터 알아보자.

차이점부터 알아보는 이유는 비슷한 네이밍을 가졌지만, 의미는 너무나 다르기 때문이다.

 

Method Override (메서드 오버라이드)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Program {
    public static void Main()
    {
        var logger = new Logger();
        logger.LogError();
        // Logger 출력
        
        var file = new FileLogger();
        file.LogError();
        // FileLogger 출력
        
        var xml = new XmlLogger();
        xml.LogError();
        // XmlLogger 출력
    }
}
 
 
public class Logger {
    public virtual void LogError() {
        Console.WriteLine("Logger");
    }
}
 
public class FileLogger : Logger {
    // Method Overriding
    public override void LogError() {
        Console.WriteLine("FileLogger");
    }
}
 
public class XmlLogger : FileLogger {
    // Method Overriding
    public override void LogError() {
        Console.WriteLine("XmlLogger");
    }
}
cs

Virtual Method (가상 메서드) / Abstract Method (추상 메서드)로 정의된 메서드가 존재한다.

해당 메서드를 파생클래스에서 재정의해서 사용하는 것을 메서드 오버라이딩라고 한다.

 

위 예제를 보면, 부모클래스에서 정의한 LogError 메서드를 파생클래스인 FileLogger / XmlLogger 에서 동일한 이름으로 재정의해서 사용하고 있다. 이것을 메서드 오버라이딩이라고 한다.

 

Method Overloading (메서드 오버로딩)

1
2
3
4
5
6
7
8
public class DB {
    public void Connect (string server) {
    }
    public void Connect (string ip, int port) {
    }
    public void Connect (string server, string login, string password) {
    }
}
cs

메서드 오버로딩은 동일한 이름의 메서드가 서로 다른 입력 파라미터를 가지는 메서드를 말한다.

DB라는 클래스 안에 Connect 이름으로 된 메서드가 여러 개 있지만, 서로 다른 입력 파라미터가 다르다. 이러한 것을 메서드 오버로딩이라고 한다.

 

메서드 오버라이딩과 메서드 오버로딩에 대한 간략하게 설명을 해보았다.

이번에는 여러 개로 선언된 메서드 오버로딩 중, 상황에 따라 호출되는 메서드가 있다.

즉, 메서드 중에서도 우선순위가 존재한다는 것이다. 아래 예제를 확인해보자.

 

1. 입력 파라미터의 타입이 가장 중요하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Program
{
    public static void Main()
    {
        var cal = new Calculator();
        Console.WriteLine(cal.Add(12));        // public int Add (int a, int b) 호출
        Console.WriteLine(cal.Add(1.22.2));    // public double Add (double a, double b) 호출
        
        var cal2 = new Calculator();
        Console.WriteLine(cal.Add(12));        // public double Add (double a, double b) 호출
    }
}
 
public class Calculator {
    public int Add (int a, int b) { return  a + b; }
    public double Add (double a, double b) { return a + b; }
}
public class Calculator2 {
    public double Add (double a, double b) { return a + b; }
    public string Add (string a, string b) { return ""; }
}
cs

오버로딩된 메서드들의 우선순위를 결정하는 요소는 입력 파라미터에 의해서 결정된다. 메서드의 리턴 타입은 1도 영향을 주지 않는다.

하지만 입력 파라미터가 정확하게 매칭 되는 메서드가 없다면, 호환되는 데이터 타입이 정의되어 있는 메서드를 호출하게 된다.

 

위 예제를 살펴보자. 2 가지 클래스를 만들었다.

  • Calculator Class : a, b 변수를 int / double 타입을 가진 Add 메서드 정의.
  • Calculator Class2 : a, b 변수를 double / string 타입을 가진 Add 메서드 정의.

Calculator 클래스 객체를 생성해서, 정수 1, 2를 Add 메서드에 넣어서 호출(6번째 라인)하면

우리가 생각하듯이 Calculator 클래스 안에 있는 int로 정의된(16번째 라인) 메서드가 호출된다.

실수 값인 1.2, 2.2를 Add 메서드를 호출(7번째 라인)하게 되면, double로 정의된(17번째 라인) 메서드가 호출된다.

 

하지만 여기서 눈여겨볼 만한 것은 Calculator2 클래스이다.

Calculator2 클래스 객체를 생성해서, 정수 1, 2를 Add 메서드에 넣어서 호출(10번째 라인)하면

int와 double 타입은 호환이 가능하기 때문에 double로 정의된(20번째 라인) 메서드가 호출된다.

 

2. 선택적 매개변수보다 정확한 입력 파라미터가 우선이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Program
{
    public static void Main()
    {
        var cal = new Calculator();
        cal.Print(1);       // public void Print (int a) 호출
        cal.Print(12);    // public void Print (int a, int b = 10)
    }
}
 
public class Calculator {
    public void Print (int a, int b = 10) {
        Console.WriteLine(a + "," + b);
    }
    public void Print (int a) {
        Console.WriteLine(a);
    }
}
cs

만약 public void Print (int a) (15번째 라인) 메서드가 존재하지 않는다고 가정하자.

정수 1을 넣고 Print 메서드를 호출하면,

a에는 10이 세팅되고 b는 선택적 매개변수로 인해 10이 세팅이 되어 13번째 라인이 실행될 것이다.

 

하지만 public void Print (int a) / public void Print (int a, int b = 10) 두 메서드가 동시에 존재할 때,

정수 1을 넣고 Print 메서드를 호출하면 위에와 다르게 16번째 라인이 실행된다.

 

여기서 알 수 있는 점은 선택적 매개변수가 포함된 메서드보다는 파라미터가 온전하게 정의되어 있는 메서드가 더 우선순위가 높다는 것을 알 수 있다.

 

3. 호출 시, 파라미터 이름을 지정하면 해당 파라미터가 우선이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Program
{
    public static void Main()
    {
        var cal = new Calculator();
        cal.PrintValue(b:1);    // public void PrintValue (double b) 호출
    }
}
 
public class Calculator {
    public void PrintValue (int a) {
        Console.WriteLine("int : " + a);
    }
    public void PrintValue (double b) {
        Console.WriteLine("double : " + b);
    }
}
cs

메서드를 호출할 때, 파라미터 이름을 지정해서 호출하면 해당 메서드가 우선적으로 호출된다.

6번째 라인에서 정수 1을 넣고 PrintValue 메서드를 호출하면,

파라미터 이름을 b로 지정해서 호출하였기 때문에 double 파라미터를 가진 메서드가 호출(14번째 라인)된다.

이것도 int와 double 사이 호환이 가능하기 때문에 호출이 가능한 것이지, double 타입이 아닌 string 타입이든 다른 타입이었으면 호출이 불가능했을 것이다.

 

반응형

+ Recent posts