현대 언어의 경우, 그것은 단지 구문 설탕입니다. 완전히 언어에 구애받지 않는 방식으로, 그 이상입니다.
이전에이 답변은 단순히 그것이 설탕이라는 것이 아니라고 언급했지만, 주석에서 볼 수 있듯이, Falco는 현대 언어가 모두 누락 된 것으로 보이는 퍼즐 조각이 있다고 지적했습니다. 메소드 오버로드와 동일한 단계에서 호출 할 함수의 동적 결정을 혼합하지 않습니다. 이것은 나중에 설명 될 것입니다.
이 여기 왜 해야 더합니다.
메서드 오버로딩과 형식화되지 않은 변수를 모두 지원하는 언어를 고려하십시오. 다음과 같은 메소드 프로토 타입을 가질 수 있습니다.
bool someFunction(int arg);
bool someFunction(string arg);
일부 언어에서는 컴파일 타임에 주어진 코드 줄에 의해 호출되는 것을 아는 것으로 아마 사임 될 것입니다. 그러나 일부 언어에서는 모든 변수가 입력되는 것은 아니며 (또는 모두 암시 적으로 유형이 지정 Object
되거나 다른 것임) 키가 다른 유형의 값에 매핑되는 사전을 작성하는 것을 상상해보십시오.
dict roomNumber; // some hotels use numbers, some use letters, and some use
// alphanumerical strings. In some languages, built-in dictionary
// types automatically use untyped values for their keys to map to,
// so it makes more sense then to allow for both ints and strings in
// your code.
그렇다면 someFunction
그 방 번호 중 하나에 적용 하려면 어떻게해야 합니까? 당신은 이것을 호출합니다 :
someFunction(roomNumber[someSortOfKey]);
인가 someFunction(int)
라고, 또는 someFunction(string)
라고? 여기에 이들이 완전히 직교적인 방법이 아닌, 특히 고급 언어의 한 예가 있습니다. 언어는 런타임 중에 어떤 것을 호출해야하는지 파악해야하므로 여전히 적어도 동일한 방법으로 간주해야합니다.
단순히 템플릿을 사용하지 않는 이유는 무엇입니까? 왜 형식화되지 않은 인수를 사용하지 않습니까?
유연성과 세밀한 제어. 때로는 템플릿 / 형식화되지 않은 인수를 사용하는 것이 더 나은 방법이지만 때로는 그렇지 않습니다.
예를 들어, 각각 int
a와 a string
를 인수로 취하는 두 개의 메소드 서명이 있지만 각 서명에서 순서가 다른 경우를 고려해야합니다 . 각 서명의 구현이 거의 동일한 작업을 수행하지만 약간 다른 트위스트를 수행 할 수 있기 때문에이 작업을 수행 할 충분한 이유가있을 수 있습니다. 예를 들어 로깅이 다를 수 있습니다. 또는 그들이 똑같은 일을하더라도 인수가 지정된 순서대로 특정 정보를 자동으로 얻을 수 있습니다. 기술적으로 pseudo-switch 문을 사용하여 전달 된 각 인수의 유형을 결정할 수는 있지만 지저분합니다.
이 다음 예제는 나쁜 프로그래밍 연습입니까?
bool stringIsTrue(int arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
bool stringIsTrue(Object arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
bool stringIsTrue(string arg)
{
if (arg == "0")
{
return false;
}
else
{
return true;
}
}
그렇습니다. 이 특정 예제에서 누군가가 이것을 특정 기본 유형에 적용하려고 시도하지 않고 예기치 않은 동작 (좋은 일이 될 수 있음)을 되찾지 못하게 할 수 있습니다. 그러나 위의 코드를 축약하고 실제로 모든 기본 유형과 Object
s에 대한 과부하가 있다고 가정 해 봅시다 . 그런 다음 다음 코드 비트가 더 적합합니다.
bool stringIsTrue(untyped arg)
{
if (arg.toString() == "0")
{
return false;
}
else
{
return true;
}
}
그러나 이것을 int
s와 string
s에 대해서만 사용해야 한다면, 더 단순하거나 복잡한 조건에 따라 true를 반환하려면 어떻게해야합니까? 그런 다음 오버로드를 사용해야 할 합당한 이유가 있습니다.
bool appearsToBeFirstFloor(int arg)
{
if (arg.digitAt(0) == 1)
{
return true;
}
else
{
return false;
}
}
bool appearsToBeFirstFloor(string arg)
{
string firstCharacter = arg.characterAt(0);
if (firstCharacter.isDigit())
{
return appearsToBeFirstFloor(int(firstCharacter));
}
else if (firstCharacter.toUpper() == "A")
{
return true;
}
else
{
return false;
}
}
그런데 왜 그 함수에 두 개의 다른 이름을 부여하지 않습니까? 당신은 여전히 같은 양의 세밀한 컨트롤을 가지고 있습니까?
앞에서 언급했듯이 일부 호텔은 숫자를 사용하고 일부는 문자를 사용하며 일부는 숫자와 문자를 혼합하여 사용하기 때문입니다.
appearsToBeFirstFloor(roomNumber[someSortOfKey]);
// will treat ints and strings differently, without you having to write extra code
// every single spot where the function is being called
이것은 여전히 실제 생활에서 사용하는 것과 똑같은 정확한 코드는 아니지만, 내가 잘 만드는 요점을 설명해야합니다.
그러나 ... 이것이 현대 언어의 구문 설탕 이상이 아닌 이유입니다.
Falco는 현재 언어가 기본적으로 동일한 단계 내에서 메소드 오버로드와 동적 함수 선택을 혼합하지 않는다는 의견에서 요점을 제기했습니다. 이전에 특정 언어가 작동하는 것을 이해 한 방법은 appearsToBeFirstFloor
위의 예제에서 오버로드 할 수 있다는 것 입니다. 언어는 런타임에 유형이 지정되지 않은 변수의 런타임 값에 따라 호출 할 함수 버전을 결정합니다. 이러한 혼동은 부분적으로 ActionScript 3.0과 같은 ECMA 정렬 언어를 사용하여 런타임에 특정 코드 행에서 어떤 함수가 호출 될지를 쉽게 무작위화할 수있게함으로써 발생합니다.
아시다시피 ActionScript 3는 메서드 오버로드를 지원하지 않습니다. VB.NET의 경우 명시 적으로 형식을 할당하지 않고 변수를 선언하고 설정할 수 있지만 이러한 변수를 오버로드 된 메서드의 인수로 전달하려고 할 때 여전히 런타임 값을 읽고 호출 할 메서드를 결정하지는 않습니다. 대신 유형의 인수가 Object
있거나 유형이 없거나 이와 비슷한 다른 메소드를 찾고 싶습니다. 따라서 위 의 int
vs. string
예제는 해당 언어로 작동하지 않습니다. C ++에는 void 포인터 또는 이와 같은 다른 메커니즘을 사용할 때 비슷한 문제가 있지만 컴파일 타임에 유형을 수동으로 명확하게해야합니다.
첫 번째 헤더가 말한 것처럼 ...
현대 언어의 경우, 그것은 단지 구문 설탕입니다. 완전히 언어에 구애받지 않는 방식으로, 그 이상입니다. 위의 예에서와 같이 메소드 오버로드를보다 유용하고 관련성있게 만드는 것은 실제로 기존 언어에 추가하기에 좋은 기능 일 수도 있고 (AS3에 대해 광범위하게 요청 된 것처럼), 또는 새로운 절차 적 / 객체 지향 언어의 생성.