메소드 오버로딩
오버로딩(Overloading)은 "과적하다" 라는 뜻을 갖고있습니다.
이미 많이들 아시겠지만 프로그래밍에서 오버로딩은 과적하다 라는 뜻처럼 하나의 메소드 이름에 여러가지 구현을 올리는 것을 뜻합니다.
코드로 예시를 들어보겠습니다.
class MainApp
{
static void Main(string[] args)
{
Console.WriteLine("{0}", Cal(10, 10));
Console.WriteLine("{0}", Cal(5.5f, 2.7f));
}
static int Cal(int a, int b)
{
return a+b;
}
static float Cal(float a, float b)
{
return a+b;
}
}
Cal 이라는 이름을 써서 매개변수를 int,float 으로 받는 메소드 2개를 만들었습니다.
오버로딩을 하면 컴파일러가 메소드 호출 코드에 사용되는 매개변수의 수와 형식을 분석해서 어떤 버전이 호출 될지를 찾아줍니다.(반환 형식은 따지지 않으며 매개 변수만 분석함)
이 작업은 컴파일 타임에 이루어지기 때문에 과적이라는 이름에 맞지않게 성능 저하는 없습니다.
가변 개수의 인수
만약 우리가 위에 만든 Cal 메소드를 이용해 잘 사용하다가, 2개의 덧셈이 아닌 3개의 덧셈을 하는 기능이 필요합니다.
그러면 어떻게 할까요?
아래의 코드처럼 함수 오버로딩을 통해 인수를 3개받는 메소드를 만들어야 할까요?
class MainApp
{
static void Main(string[] args)
{
Console.WriteLine("{0}", Cal(10, 10));
Console.WriteLine("{0}", Cal(10, 10,10));
}
static int Cal(int a, int b)
{
return a+b;
}
static int Cal(int a, int b, int c)
{
return a+b+c;
}
}
3개에서 끝이나면 다행이지만 4개..5개.. 인수가 더 많이 필요한 경우가 생길수도 있습니다.
이것을 대비해서 C#에서는 "가변 개수의 인수" 라는 기능을 제공합니다.
가변 개수의 인수는 개수가 유연하게 변할 수 있는 인수를 말합니다.
가변 개수의 인수는 params 키워드와 배열을 이용해 사용할 수 있습니다.
위의 코드를 params와 배열을 이용해 바꿨습니다.
class MainApp
{
static void Main(string[] args)
{
Console.WriteLine("{0}", Cal(10, 10));
Console.WriteLine("{0}", Cal(10, 10, 10));
Console.WriteLine("{0}", Cal(10, 10, 10, 10));
}
static int Cal(params int[] a)
{
int Sum = 0;
for (int i = 0; i < a.Length; i++)
Sum += a[i];
return Sum;
}
}
인수를 2개,3개,4개를 넣더라도 아래 사진과 같이 잘 작동하는것을 알 수 있습니다.
가변 개수의 인수는 계속 늘어나기 때문에 매개변수가 2개 이상일 경우 맨 끝에 위치해야합니다.
앞에 둔다면 오류가 납니다.
명명된 인수
우리는 메소드에 인수를 적어 호출할때 메소드에 선언된 매개변수의 순서대로 인수를 적어야 합니다.
public int Cal(int a,int b) 라는 메소드가 있다면 호출할때도 a와 b 순서대로 적어야 한다는 의미입니다.
명명된 인수는 순서대로 하지 않고 매개변수의 이름에 근거해서 데이터를 할당할 수 있는 기능입니다.
아래 코드로 예시를 들어 보겠습니다.
class MainApp
{
static void Main(string[] args)
{
Print_Profile(Age: 10, Name: "티모");
Print_Profile("샤코",20);
}
static void Print_Profile(string Name,int Age)
{
Console.WriteLine("이름 : "+Name+ "\t나이 : " + Age);
}
}
메소드의 매개변수는 Name,Age 순서입니다.
하지만 Main함수에서 첫번째 메소드를 호출할때 인수에 'Age:' 라고 이름을 명명하여 호출했습니다.
이런식으로 메소드를 호출하면 정의해놓은 매개변수의 순서에 상관없이 메소드를 호출 할 수 있습니다.
평소에는 굳이 쓰지 않아도 되는 기능이지만 , 인수가 많아 어느 매개변수에 어느 인수를 할당하고 있는지 분간이 어려울때에 사용하면 좋을것 같습니다.
생성자, this() 생성자
생성자는 클래스의 객체를 생성하는 임무를 가지고 있습니다.
class MainApp
{
static void Main(string[] args)
{
Dog myDog = new Dog();
}
}
class Dog
{
string name;
int Age;
}
이 처럼 Dog라는 클래스의 인스턴스를 생성하기 위해선 new 연산자와 Dog()라는 생성자를 통해 인스턴스를 생성합니다.
생성자는 '클래스명()' 의 형태를 가지고 있으며 우리가 생성자를 구현하지 않아도 컴파일러에서 생성자를 알아서 만들어줍니다.
하지만 클래스 안에있는 속성들을 초기화 시켜줄때도 생성자를 많이 사용합니다.
아래 코드처럼 생성과 동시에 안에 속성(변수)들을 입력한 인수로 초기화 시켜줄 수 있습니다.
class MainApp
{
static void Main(string[] args)
{
Dog myDog = new Dog("뽀삐",3);
}
}
class Dog
{
string name;
int Age;
public Dog(string name, int Age)
{
this.name = name;
this.Age = Age;
Console.WriteLine(this.name+"\n"+this.Age);
}
}
프로그래머가 생성자를 하나라도 직접 정의하면 C# 컴파일러는 매개변수가 없는 기본 생성자를 알아서 생성해주지 않습니다.
프로그래머의 의도와 다르게 동작하는 코드가 제공되는 것을 방지하고자 하는 이유라고 합니다.
class Dog
{
string name;
int Age;
string Bark;
public Dog() //첫번째 생성자
{
this.name = "뽀삐";
}
public Dog(int Age) //두번째 생성자
{
this.name = "뽀삐";
this.Age = Age;
}
public Dog(int Age,string Bark) //세번째 생성자
{
this.name = "뽀삐";
this.Age = Age;
this.Bark = Bark;
}
위와 같은 Dog클래스의 생성자를 3개 만들었습니다.
이대로 써도 별 문제는 없지만, 각각의 생성자에 겹치는 코드가 있습니다.
두번째 생성자를 쓸때는 중복코드를 없애기 위해 첫번째 생성자를 같이 호출하게 하고,
세번째 생성자를 쓸때는 중복코드를 없애기 위해 두번째 생성자를 같이 호출하게 하면 되지 않을까요?
아쉽게도 생성자는 new 연산자 없이 호출할 수 없습니다.
하지만 이 문제를 해결해주는것이 this() 입니다.
this()는 자기 자신의 생성자를 가리키며, 생성자에서만 사용될 수 있습니다.
또 코드 블록이 아닌 앞쪽에서만 사용이 가능합니다.
this()를 이용해 코드를 한번 바꿔 보겠습니다.
class Dog
{
string name;
int Age;
string Bark;
public Dog() //첫번째 생성자
{
this.name = "뽀삐";
}
public Dog(int Age) : this() //두번째 생성자
{
this.Age = Age;
}
public Dog(int Age,string Bark) : this(Age) //세번째 생성자
{
this.Bark = Bark;
}
public void PrintDog()
{
Console.WriteLine(this.name);
Console.WriteLine(this.Age);
Console.WriteLine(this.Bark);
}
}
두번째 생성자에 this()를 이용해 첫번째 생성자를 호출하게 만들었고,
세번째 생성자에도 두번째 생성자에 매개변수 Age를 넣어주어 호출하게 만들었습니다.
다른 클래스에서 Dog클래스의 인스턴스를 생성할때 인수를 2개 적어야하는 세번째 생성자를 이용해 생성했습니다.
그리고 PrintDog() 함수를 이용해 변수들을 출력해주는 코드를 작성했습니다.
class MainApp
{
static void Main(string[] args)
{
Dog myDog = new Dog(5,"멍멍!");
myDog.PrintDog();
}
}
설정해둔대로 변수들이 잘 초기화 된것을 볼 수 있습니다.
C++도 비슷한 기능이 있는데 참 편리한것 같습니다.
'프로그래밍 공부 > C# 프로그래밍' 카테고리의 다른 글
[C#] 예외처리 Try - Catch / Throw & Finally (0) | 2022.09.18 |
---|---|
[C#] 프로퍼티란? & 자동구현 프로퍼티와 public 변수와의 차이 찾아보기 (0) | 2022.08.24 |
[C#] ref 와 out 매개변수 한정자 (0) | 2022.08.24 |
[Unity_C#] Switch문 & Switch 식 (0) | 2022.08.21 |
클래스와 구조체 / 배열과 리스트 / awake와 start의 차이 (0) | 2022.08.11 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!