이미 다들 알고 계시겠지만 특정 행위를 수행하는 코드를 하나로 묶어놓은 것을 메소드라 합니다. 그래서 그 행위가 필요할 때 그 메소드를 호출하기만 하면 다시 작성할 필요가 없습니다.
class 클래스이름
{
한정자 반환형식 메소드명(매개변수)
{
코드;
return 반환형식에 일치하는 결과;
}
}
의 구조를 갖습니다. 실제 예는 다음과 같습니다.
class Calculator
{
public static int Plus(int a, int b)
{
Console.WriteLine("Input : {0} {1}", a, b);
int result = a + b;
return result;
}
}
| cs |
여기서는 접근한정자로 public static이 쓰였습니다. static은 메소드가 클래스의 인스턴스가 아닌 클래스 자체에 속하도록 하는 한정자로서 인스턴스를 만들지 않고도 메소드를 사용할수 있도록 만듭니다. 앞으로 클래스를 공부할 때 자세히 알아보도록 하고 여러가지 형태를 구경만 해보고 넘어가겠습니다.
abstract class Motorcycle
{
// Anyone can call this.
public void StartEngine() {/* 코드; */ }
// Only derived classes can call this.
protected void AddGas(int gallons) { /* 코드; */ }
// Derived classes can override the base class implementation.
public virtual int Drive(int miles, int speed) { /* 코드; */ return 1; }
// Derived classes must implement this.
public abstract double GetTopSpeed();
}
| cs |
return은 일종의 점프문으로서 메소드에서 호출되면 결과값을 반환하고 메소드 코드블럭을 빠져나오도록 합니다. 반환형이 없는 void의 경우에도 return;문으로 메소드를 종결할 수 있습니다.
매개변수
우리가 어떤 메소드에 매개변수를 주어 작업을 수행했다고 해 봅시다.
Method(x,y) 처럼 말이죠.
Method에 우리는 x, y 두 변수를 대입해서 작업을 했지만 실제로는 x, y를 넘겨주는 것이 아니며 값을 복사해서 넘겨주게 되므로 원래의 x, y에는 아무런 영향이 없습니다.
이런 방식을 "Call by value"라고 부릅니다.
using System;
class Program
{
public static void SwapCallByValue(int a, int b)
{
int temp = b;
b = a;
a = temp;
}
static void Main(string[] args)
{
int x = 3, y = 4;
Console.WriteLine("x:{0}, y:{1}", x, y);
SwapCallByValue(x, y);
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
| cs |
SwapCallByValue라는 메소드를 작성했습니다. 정수 a,b를 받아서 내부적으로 값을 서로 바꿔주는 메소드입니다. 이 프로그램의 실행결과는 어떨까요?
결과)
x:3, y:4
x:3, y:4
x, y 값이 서로 바뀌지 않고 원래 그대로입니다.
그럼 매개변수로 주어진 변수에 직접 접근(Call By Reference)하려면 어떻게 할까요? C 언어에서 우린 포인터를 넘겨주어 저장된 주소에 직접 접근토록 했습니다. C#에서는 매개변수 앞에 "ref"키워드를 넘겨주면 간단히 해결됩니다(메소드 호출시에도 ref를 붙여줍니다).
using System;
class Program
{
public static void SwapCallByValue(ref int a, ref int b)
{
int temp = b;
b = a;
a = temp;
}
static void Main(string[] args)
{
int x = 3, y = 4;
Console.WriteLine("x:{0}, y:{1}", x, y);
SwapCallByValue(ref x, ref y);
Console.WriteLine("x:{0}, y:{1}", x, y);
}
}
| cs |
"ref"와 비슷한 것으로 "out" 키워드가 사용 가능합니다. ref의 경우에는 미리 그 변수가 초기화 되어야 하지만 out은 초기화 없는 변수 선언만으로 가능하고 메소드의 결과로서 그 변수에 반드시 그 변수에 값이 할당되어야 합니다(그렇지 않으면 에러가 납니다).
주로 메서드가 한개의 return값이 아닌 여러개의 값을 반환하도록 하는데 유용합니다.
out 키워드의 예를 들어 보겠습니다.
using System;
class Program
{
static void Calc(int a,int b,out int mul, out int add)
{
mul = a * b;
add = a + b;
}
static void Main()
{
int a = 10;
int b = 5;
int c, d;
Calc(a, b, out c, out d);
Console.WriteLine("a={0}, b={1}, a*b={2}, a+b={3}", a, b, c, d);
}
}
| cs |
결과) a=10, b=5, a*b=50, a+b=15
메소드 오버로딩
오버로딩이란 같은 함수명으로 매개변수가 다른 여러개의 함수를 정의할 수 있는 방법입니다. 오버로딩이 없었다면 라이브러리에 참고해야할 함수가 몇십배 늘어났을 겁니다. 우리가 여태 가장 많이 쓴 WriteLine()만 해도 사실 매개변수가 다른 19개 메소드의 집합입니다.
가변길이 매개변수
"params" 키워드를 사용해서 여러개의 매개변수를 처리할 수 있습니다.
public static void UseParams(params int[] list)
{
for (int i = 0; i < list.Length; i++)
{
Console.Write(list[i] + " ");
}
Console.WriteLine();
}
| cs |
정수 변수의 list를 받아 출력하는 메소드입니다.
UseParams(1, 2, 3, 4);
UseParams(1, 2, 3, 4, 5);
처럼 사용 가능합니다.
명명된 매개변수
Named parameter는 코드의 가독성을 높이기 위한 장치입니다. 매개변수가 많을 때 혼동이 되지 않도록 도와줍니다.
static int CalculateBMI(int weight, int height)
{
return (weight * 703) / (height * height);
}
| cs |
신체발달지수를 계산해주는 위와 같은 메소드를 생각해 봅시다.
여태까지 우리는 위의 함수를 호출할 때
CalculateBMI(123, 64)
와 같이 사용 했습니다. 그런데 순서가 기억나지 않는다던가 할때,
CalculateBMI(weight: 123, height: 64)
의 형태로 이름을 붙여줄 수 있습니다.
CalculateBMI(height: 64, weight: 123)
처럼 순서를 바꿔서도 가능하며,
CalculateBMI(123, height: 64)
처럼 하나에만 이름을 붙일 수도 있는데 이럴 경우 앞의 것만 생략가능하며 순서를 지켜야 합니다..
CalculateBMI(weight: 123, 64)
CalculateBMI(height: 64, 123)
는 에러를 발생시킵니다.
선택적 매개변수
메소드의 매개변수는 기본값을 지정할 수 있습니다. 기본값을 가질 경우 메소드를 호출 시 인자를 생략할 수 있으므로 선택적 매개변수(optional parameter)라고 부르며, 항상 반드시 값을 입력해야 하는 기본값이 없는 필수매개변수 뒤에 와야 합니다. 또한, 생략이 가능하여 입력한 인자가 무엇인지 혼동될 수 있으므로 명명된 매개 변수와 같이 사용하여 혼동을 줄일 수 있습니다.
using System;
class Program
{
static void Calc(string name, int weight ,int height=170)
{
Console.WriteLine("{0}, {1}, {2}", name, weight, height);
}
static void Main(string[] args)
{
Calc("Adam", 67, 180);
Calc("Bob", 55);
Calc(name: "Charles", weight: 78);
}
}
| cs |
결과)
Adam, 67, 180
Bob, 55, 170
Charles, 78, 170
댓글 없음:
댓글 쓰기