C ++에서 Java로 올 때 대답이 분명하지 않은 질문은 Java에 연산자 오버로드가 포함되지 않은 이유는 무엇입니까?
아닌가 Complex a, b, c; a = b + c;
보다 훨씬 간단 Complex a, b, c; a = b.add(c);
?
연산자 오버로드를 허용 하지 않는 유효한 인수가 알려진 이유가 있습니까? 그 이유는 임의적입니까, 아니면 시간을 잃었습니까?
C ++에서 Java로 올 때 대답이 분명하지 않은 질문은 Java에 연산자 오버로드가 포함되지 않은 이유는 무엇입니까?
아닌가 Complex a, b, c; a = b + c;
보다 훨씬 간단 Complex a, b, c; a = b.add(c);
?
연산자 오버로드를 허용 하지 않는 유효한 인수가 알려진 이유가 있습니까? 그 이유는 임의적입니까, 아니면 시간을 잃었습니까?
답변:
에서 참조하는 객체의 이전 값을 덮어 쓰려면 a
멤버 함수를 호출해야합니다.
Complex a, b, c;
// ...
a = b.add(c);
C ++에서이 표현식은 컴파일러에게 스택에 3 개의 객체를 만들고 추가를 수행 하고 결과 값을 임시 객체에서 기존 객체로 복사 하도록 지시 합니다 a
.
그러나 Java에서는 operator=
참조 유형에 대한 값 복사를 수행하지 않으며 사용자는 값 유형이 아닌 새 참조 유형 만 작성할 수 있습니다. 따라서이라는 사용자 정의 유형의 Complex
경우 할당은 기존 값에 대한 참조를 복사하는 것을 의미합니다.
대신 고려하십시오 :
b.set(1, 0); // initialize to real number '1'
a = b;
b.set(2, 0);
assert( !a.equals(b) ); // this assertion will fail
C ++에서는 값이 복사되므로 비교 결과가 동일하지 않습니다. 자바에서 operator=
수행 그래서, 복사를 참조 a
하고 b
현재 동일한 값을 참조한다. 결과적으로 객체는 자신과 동일하게 비교되므로 비교는 '동일'을 생성합니다.
사본과 참조의 차이점은 운영자 과부하의 혼란을 추가합니다. @Sebastian이 언급했듯이 Java와 C #은 모두 값과 참조 평등을 개별적으로 operator+
처리해야합니다. 값과 객체를 처리 할 가능성이 있지만 operator=
참조를 처리하기 위해 이미 구현되었습니다.
C ++에서는 한 번에 한 종류의 비교 만 처리해야하므로 혼동이 줄어 듭니다. 예를 들어,에 Complex
, operator=
그리고 operator==
두 값 작업입니다 - 값을 복사하여 각각 값을 비교.
연산자 오버로드에 대해 불평하는 게시물이 많이 있습니다.
나는 "운영자 과부하"개념을 명확히해야한다고 생각하여이 개념에 대한 대안적인 견해를 제시했다.
이 주장은 잘못된 것입니다.
연산자 오버로드를 통해 C ++ 에서처럼 함수 / 메소드를 통해 C 또는 Java로 코드를 난독 처리하는 것이 쉽습니다.
// C++
T operator + (const T & a, const T & b) // add ?
{
T c ;
c.value = a.value - b.value ; // subtract !!!
return c ;
}
// Java
static T add (T a, T b) // add ?
{
T c = new T() ;
c.value = a.value - b.value ; // subtract !!!
return c ;
}
/* C */
T add (T a, T b) /* add ? */
{
T c ;
c.value = a.value - b.value ; /* subtract !!! */
return c ;
}
또 다른 예를 들어, 자바로 Cloneable
인터페이스 를 보자 :
이 인터페이스를 구현하는 객체를 복제해야합니다. 그러나 당신은 거짓말을 할 수 있습니다. 그리고 다른 객체를 만듭니다. 실제로이 인터페이스는 너무 약해서 재미를 위해 다른 유형의 객체를 모두 반환 할 수 있습니다.
class MySincereHandShake implements Cloneable
{
public Object clone()
{
return new MyVengefulKickInYourHead() ;
}
}
애즈 Cloneable
인터페이스 남용 될 수 / 난독, 이는 C ++ 연산자 오버로딩이 있어야하는데 동일한 이유로 금지되어야 하는가?
우리 toString()
는 MyComplexNumber
클래스 의 메소드를 오버로드하여 문자열 화 된 시간을 반환하도록 할 수 있습니다. toString()
과부하도 금지 해야합니까 ? 우리 MyComplexNumber.equals
는 임의의 값을 반환하고 피연산자 등을 수정하도록 방해 할 수 있습니다.
Java에서 C ++ 또는 다른 언어와 마찬가지로 프로그래머는 코드를 작성할 때 최소한의 의미를 존중해야합니다. 즉 add
, 추가 하는 기능과 Cloneable
복제하는 구현 방법 및 ++
증분보다 연산자를 구현 해야합니다 .
이제 원시 Java 메소드를 통해서도 코드가 파괴 될 수 있음을 알았으므로 C ++에서 연산자 오버로드의 실제 사용에 대해 스스로에게 물어볼 수 있습니까?
Java와 C ++의 "동일한"코드를 아래에서 비교하여 어떤 코딩 스타일이 더 명확한 지 알 수 있습니다.
// C++ comparison for built-ins and user-defined types
bool isEqual = A == B ;
bool isNotEqual = A != B ;
bool isLesser = A < B ;
bool isLesserOrEqual = A <= B ;
// Java comparison for user-defined types
boolean isEqual = A.equals(B) ;
boolean isNotEqual = ! A.equals(B) ;
boolean isLesser = A.comparesTo(B) < 0 ;
boolean isLesserOrEqual = A.comparesTo(B) <= 0 ;
연산자 오버로드가 제공되는 한 A 및 B는 C ++에서 모든 유형이 될 수 있습니다. Java에서 A와 B가 프리미티브가 아닌 경우 프리미티브와 유사한 객체 (BigInteger 등)의 경우에도 코드가 매우 혼란 스러울 수 있습니다 ...
// C++ container accessors, more natural
value = myArray[25] ; // subscript operator
value = myVector[25] ; // subscript operator
value = myString[25] ; // subscript operator
value = myMap["25"] ; // subscript operator
myArray[25] = value ; // subscript operator
myVector[25] = value ; // subscript operator
myString[25] = value ; // subscript operator
myMap["25"] = value ; // subscript operator
// Java container accessors, each one has its special notation
value = myArray[25] ; // subscript operator
value = myVector.get(25) ; // method get
value = myString.charAt(25) ; // method charAt
value = myMap.get("25") ; // method get
myArray[25] = value ; // subscript operator
myVector.set(25, value) ; // method set
myMap.put("25", value) ; // method put
Java에서는 각 컨테이너가 동일한 작업을 수행하기 위해 (인덱스 또는 식별자를 통해 내용에 액세스) 다른 방법으로 수행하는 것이 혼란 스럽습니다.
C ++에서 연산자 오버로드 덕분에 각 컨테이너는 동일한 방식으로 콘텐츠에 액세스합니다.
아래 예 Matrix
는 Google에서 " Java Matrix object "및 " C ++ Matrix object " 에 대한 첫 번째 링크를 사용하여 찾은 객체를 사용합니다 .
// C++ YMatrix matrix implementation on CodeProject
// http://www.codeproject.com/KB/architecture/ymatrix.aspx
// A, B, C, D, E, F are Matrix objects;
E = A * (B / 2) ;
E += (A - B) * (C + D) ;
F = E ; // deep copy of the matrix
// Java JAMA matrix implementation (seriously...)
// http://math.nist.gov/javanumerics/jama/doc/
// A, B, C, D, E, F are Matrix objects;
E = A.times(B.times(0.5)) ;
E.plusEquals(A.minus(B).times(C.plus(D))) ;
F = E.copy() ; // deep copy of the matrix
그리고 이것은 행렬에만 국한되지 않습니다. BigInteger
와 BigDecimal
자바의 클래스는 C에서 자신의 등가물 ++로 반면, 같은 혼란 상세 고통 내장의 유형으로 취소합니다.
// C++ Random Access iterators
++it ; // move to the next item
--it ; // move to the previous item
it += 5 ; // move to the next 5th item (random access)
value = *it ; // gets the value of the current item
*it = 3.1415 ; // sets the value 3.1415 to the current item
(*it).foo() ; // call method foo() of the current item
// Java ListIterator<E> "bi-directional" iterators
value = it.next() ; // move to the next item & return the value
value = it.previous() ; // move to the previous item & return the value
it.set(3.1415) ; // sets the value 3.1415 to the current item
// C++ Functors
myFunctorObject("Hello World", 42) ;
// Java Functors ???
myFunctorObject.execute("Hello World", 42) ;
// C++ stream handling (with the << operator)
stringStream << "Hello " << 25 << " World" ;
fileStream << "Hello " << 25 << " World" ;
outputStream << "Hello " << 25 << " World" ;
networkStream << "Hello " << 25 << " World" ;
anythingThatOverloadsShiftOperator << "Hello " << 25 << " World" ;
// Java concatenation
myStringBuffer.append("Hello ").append(25).append(" World") ;
자, Java MyString = "Hello " + 25 + " World" ;
에서도 사용할 수 있습니다 ... 그러나 잠시만 기다리십시오. 이것은 연산자 오버로드입니다. 그렇지 않습니까? 부정 행위 아닌가요 ???
:-디
내장 / 프리미티브 (Java에 인터페이스가없는), 표준 객체 (올바른 인터페이스를 가질 수 없음) 및 사용자 정의 객체 모두에 동일한 일반 코드 수정 피연산자를 사용할 수 있습니다.
예를 들어, 임의 유형의 두 값의 평균값을 계산합니다.
// C++ primitive/advanced types
template<typename T>
T getAverage(const T & p_lhs, const T & p_rhs)
{
return (p_lhs + p_rhs) / 2 ;
}
int intValue = getAverage(25, 42) ;
double doubleValue = getAverage(25.25, 42.42) ;
complex complexValue = getAverage(cA, cB) ; // cA, cB are complex
Matrix matrixValue = getAverage(mA, mB) ; // mA, mB are Matrix
// Java primitive/advanced types
// It won't really work in Java, even with generics. Sorry.
이제 연산자 오버로딩을 사용하는 C ++ 코드와 Java의 동일한 코드를 공정하게 비교 했으므로 이제 "오퍼레이터 오버로드"를 개념으로 설명 할 수 있습니다.
심지어 외부 컴퓨터 과학, 연산자 오버로딩이있다 : 예를 들어, 수학, 사업자 좋아 +
, -
, *
오버로드, 등.
실제로,의 의미 +
, -
,*
등의 변화 피연산자의 종류 (수치 등, 벡터 양자 파동 함수, 행렬)에 따라.
우리 대부분은 과학 과정의 일부로서 피연산자의 유형에 따라 연산자에 대한 여러 가지 의미를 배웠습니다. 혼란 스러웠습니까?
이것은 연산자 오버로딩의 가장 중요한 부분입니다. 수학이나 물리학 에서처럼 연산은 피연산자의 유형에 따라 다릅니다.
따라서 피연산자의 유형을 알고 작업의 효과를 알게됩니다.
C에서 연산자의 실제 동작은 피연산자에 따라 변경됩니다. 예를 들어, 두 개의 정수를 추가하는 것은 두 개의 double을 추가하거나 하나의 정수와 double을 추가하는 것과 다릅니다. 전체 포인터 산술 도메인도 있습니다 (캐스팅하지 않고 포인터에 정수를 추가 할 수는 있지만 두 개의 포인터를 추가 할 수는 없습니다 ...).
Java에서는 포인터 산술이 없지만 +
"연산자 오버로드가 악의적"이라는 신념에서 예외를 정당화 할만큼 조작자가 없는 문자열 연결은 여전히 우스운 것으로 판명되었습니다 .
C (역사적 이유로) 또는 Java ( 개인적 이유로 아래 참조) 코더 로서 자신만을 제공 할 수는 없습니다.
C ++에서는 내장 유형에 대한 연산자 오버로드가 불가능하지만 (이것은 좋습니다) 사용자 정의 유형에는 사용자 정의 유형이있을 수 있습니다 연산자 오버로드 .
앞서 언급했듯이 C ++ 및 Java와 달리 사용자 유형은 내장 유형과 비교할 때 언어의 2 급 시민으로 간주되지 않습니다. 따라서 내장 유형에 연산자가 있으면 사용자 유형도 연산자를 가질 수 있어야합니다.
진실은 저를 인처럼 toString()
, clone()
, equals()
방법은 자바위한 것입니다 ( 즉, 준 표준 등 ), C ++ 연산자 오버로딩이 언급 Java 메소드 전에 원래 C 사업자 등의 자연, 또는으로 될 것으로 ++ C의 너무 많은 부분입니다.
템플릿 프로그래밍과 결합 된 연산자 오버로딩은 잘 알려진 디자인 패턴이됩니다. 실제로 오버로드 된 연산자를 사용하지 않고 자신의 클래스에 대한 오버로드 연산자를 사용하지 않으면 STL에서 멀리 갈 수 없습니다.
연산자 과부하는 연산자의 의미를 존중하기 위해 노력해야합니다. +
연산자 에서 빼지 마십시오 ( " add
함수 에서 빼지 마십시오 "또는 " clone
메소드 에서 크랩 반환 ").
캐스트 과부하는 모호성을 유발할 수 있으므로 매우 위험 할 수 있습니다. 따라서 실제로 정의 된 사례를 위해 예약해야합니다. 에 관해서 &&
그리고 ||
당신이 정말로 당신이 무슨 일을하는지 알지 못한다면 당신은 기본 운영자 그 단락 회로 평가를 잃게됩니다로서, 지금까지 그들을 과부하가 걸리지 않도록 &&
하고 ||
즐길 수 있습니다.
제임스 고슬링이 그렇게 말했기 때문에 :
C ++에서 너무 많은 사람들이 그것을 남용하는 것을 보았 기 때문에 연산자 오버로드를 상당히 개인적인 선택으로 제외 했습니다.
제임스 고슬링 출처 : http://www.gotw.ca/publications/c_family_interview.htm
위의 Gosling의 텍스트를 Stroustrup의 아래 텍스트와 비교하십시오.
많은 C ++ 디자인 결정은 사람들이 특정한 방식으로 일을하도록 강요하는 것에 대해 싫어하는 데 뿌리를두고있다. [...] 종종, 나는 개인적으로 싫어하는 기능을 불법화하려는 유혹을 받았다. 다른 사람에 대한 나의 견해를 강요 할 권리 .
Bjarne Stroustrup. 출처 : C ++의 디자인과 진화 (1.3 일반 배경)
일부 객체는 연산자 오버로드 (BigDecimal, 복소수, 행렬, 컨테이너, 반복자, 비교기, 파서 등과 같은 콘크리트 또는 숫자 유형)의 이점을 크게 누릴 수 있습니다.
C ++에서는 Stroustrup의 겸손으로 인해이 혜택을 누릴 수 있습니다. Java에서는 Gosling이 개인적으로 선택 했기 때문에 문제가 발생했습니다 .
현재 Java에 운영자 과부하를 추가하지 않는 이유는 내부 정치, 기능에 대한 알레르기, 개발자에 대한 불신 (Java 팀을 괴롭히는 것처럼 보이는 파괴자), 이전 JVM과의 호환성, 정확한 사양 작성 시간 등
따라서이 기능을 기다리는 숨을 참지 마십시오 ...
네...
이것이 두 언어의 유일한 차이점은 아니지만이 언어는 결코 나를 즐겁게하지 않습니다.
분명히 C # 사람들은 "모든 프리미티브는 a struct
이고 struct
Object에서 파생됩니다"라는 첫 번째 시도에서 올바르게 얻었습니다.
모든에도 불구하고 FUD 사용 정의 연산자 오버로딩에 대해, 다음과 같은 언어를 지원 : 스칼라 , 다트 , 파이썬 , F 번호 , C #을 , D , 알골 (68) , 스몰 토크 , 그루비 , 펄 6 , C ++, 루비 , 하스켈 , MATLAB , 에펠 , 루아 , Clojure , Fortran 90 , Swift , Ada , Delphi 2005 ...
너무나 많은 다른 (때때로 반대되는) 철학을 가진 많은 언어들이 있지만, 그들은 모두 그 시점에 동의합니다.
생각할 거리...
James Gosling은 Java 디자인을 다음과 같이 비유했습니다.
"한 아파트에서 다른 아파트로 이사 할 때 이사하는 것에 대한이 원칙이 있습니다. 흥미로운 실험은 아파트를 포장하고 모든 것을 상자에 넣은 다음 다음 아파트로 옮기고 필요할 때까지 포장을 풀지 않는 것입니다. 첫 식사를 다시하고 상자에서 무언가를 꺼내는 것입니다. 그리고 한 달 정도 지나면 인생에서 실제로 필요한 것들을 거의 파악하고 나머지는 물건-좋아하는 것과 잊어 버리는 것을 잊어 버리고 그냥 버려라 인생을 단순화시키는 방법이 놀랍고 모든 종류의 디자인 문제에서 그 원칙을 사용할 수 있습니다. '멋지거나 재미 있기 때문에.'
기본적으로 연산자 과부하는 일종의 포인트, 통화 또는 복소수를 모델링하는 클래스에 적합합니다. 그러나 그 후에는 예제가 빨리 부족하기 시작합니다.
또 다른 요인은 개발자가 '&&', '||', 캐스트 연산자 및 물론 'new'와 같은 연산자를 오버로드하는 개발자가 C ++의 기능을 남용하는 것입니다. 이를 통과 가치 및 예외와 결합하여 발생하는 복잡성에 대해서는 예외적 인 C ++ 책 .
Many C++ design decisions have their roots in my dislike for forcing people to do things in some particular way [...] Often, I was tempted to outlaw a feature I personally disliked, I refrained from doing so because I did not think I had the right to force my views on others. (B. Stroustrup)
입니다.
I'd like them to go have a look at some C++ code out there that is hideously put together with weird hacks and "exceptional" features of the language
나쁜 프로그래머는 언어에 관계없이 나쁜 코드를 작성합니다. Java에서 함수 매개 변수에 대한 "통과 기준"을 모방하여 아이디어를 얻으십시오. 나는 코드를 보았고 너무 힘들어 웃었다. 이것은 Gosling이 사용하지 않은 종류이므로 Java에서 끔찍한 해킹이 필요했지만 C #과 C ++ 모두 기본적으로 비용이 들지 않습니다.
Boost.Units를 확인하십시오. 링크 텍스트
작업자 과부하를 통해 오버 헤드없는 차원 분석을 제공합니다. 이것이 얼마나 더 명확합니까?
quantity<force> F = 2.0*newton;
quantity<length> dx = 2.0*meter;
quantity<energy> E = F * dx;
std::cout << "Energy = " << E << endl;
실제로 "에너지 = 4J"를 출력합니다.
Groovy 는 연산자 오버로딩을 가지고 있으며 JVM에서 실행됩니다. 성능 저하를 신경 쓰지 않으면 (매일 더 작아집니다). 메소드 이름에 따라 자동으로 수행됩니다. 예를 들어, '+'는 'plus (argument)'메소드를 호출합니다.
where ...
가 됨 .Where(i => ...
). 산술 연산자로만 동일한 작업을 수행하면 훨씬 더 간단하고 강력 해집니다. Java는 깨끗한 슬레이트의 이점을 가지고 있으며, 올바른 방법으로 얻을 수 있습니다.
필자는 이것이 의도적으로 의도를 전달하는 이름을 가진 함수를 개발자가 만들도록 의식적인 디자인 선택 일 수 있다고 생각합니다. C ++에서 개발자는 종종 주어진 연산자의 일반적으로 받아 들여지는 특성과 관련이없는 기능을 가진 연산자를 오버로드하여 연산자의 정의를 보지 않고 코드 조각이 무엇인지 판단하는 것이 거의 불가능합니다.
In C++ developers would overload operators with functionality that would often have no relation to the commonly accepted nature of the given operator
: 이것은 무의미한 주장입니다. 나는 12 년 이후로 전문적인 C ++ 개발자 이며이 문제는 거의 발생하지 않습니다. 사실, C ++에서 보았던 대부분의 버그와 디자인 오류는 C 스타일 코드 ( void *
, 캐스트 등)에
add
함수가 실제로 잘못 사용 될 수 있다는 사실에 대해서도 언급하고 있지 않습니다 (곱셈을 수행하거나 뮤텍스를 얻는 것과 같이). user14128이 언급 한 남용은 연산자에 국한되지 않지만 연산자 오버로드에 대한 일종의 병리학 적 두려움이 있습니다 .C vs. C ++의 초기 시대에서 왔으며 Java로 수정되지 않은 두려움입니다.하지만 고맙게도 C #으로 들어 가지 않았습니다 ... 시맨틱을 존중합니다. 명확한 기능 / 연산자를 작성하는 것은 개발자의 일입니다. 언어가 아닙니다.
cout << f() || g();
괄호는 명확하지 않고 정확합니다. 그리고 비트 시프트 연산자는 남용되지 않았으므로 필요하지 않았습니다. 왜 cout << (5&3) << endl;
보다 낫 cout.fmt(5&3)(endl);
습니까? functor 멤버 변수에 함수 호출 연산자를 사용하면 글리프가 멋지게 보이기 때문에 비트 연산자를 용도 변경하는 것보다 스트림에 대해 무한히 더 나은 디자인이됩니다. 그러나 이것은 스트림에 잘못된 유일한 것은 아닙니다.
연산자 오버로드로 인해 연산자가 운영 논리와 일치하지 않는 유형의 논리적 오류가 발생한다고 말하는 것은 아무 것도 말하지 않는 것과 같습니다. 함수 이름이 연산 로직에 적합하지 않은 경우 동일한 유형의 오류가 발생합니다. 따라서 해결책은 무엇입니까? 이것은 "작동 논리에 적합하지 않음", 모든 매개 변수 이름, 모든 클래스, 함수 또는 논리적으로 부적절 할 수있는 것 같은 코믹한 답변입니다. 이 옵션은 프로그래밍 가능한 언어로 사용할 수 있어야하며 안전하지 않다고 생각하는 사람들은이 옵션을 사용해야한다고 생각합니다. C #을 보자. 그들은 포인터를 떨어 뜨 렸지만 당신은 자신의 위험에 따라 원하는대로 '안전하지 않은 코드'문구가 있습니다.
기술적으로, 모든 프로그래밍 언어에는 정수 및 실수와 같은 다른 유형의 숫자를 처리 할 수있는 연산자 오버로드가 있습니다. 설명 : 오버로딩이라는 용어는 하나의 함수에 대해 단순히 여러 구현이 있음을 의미합니다. 대부분의 프로그래밍 언어에서 연산자 +, 정수, 실수, 실수에 대해 서로 다른 구현이 제공됩니다. 이것을 연산자 오버로딩이라고합니다.
이제 많은 사람들이 Java에 연산자에 대한 연산자 과부하가 있고 문자열을 함께 추가하기 때문에 이상하다고 생각합니다. 수학적 관점에서 보면 이것이 이상하게 보일 수는 있지만 프로그래밍 언어 개발자의 입장에서 볼 때 내장 연산자 오버로드를 추가해도 아무런 문제가 없습니다. 연산자 + 다른 클래스 (예 : 문자열) 그러나 대부분의 사람들은 + for String에 내장 과부하를 추가하면 일반적으로 개발자에게도이 기능을 제공하는 것이 좋습니다.
연산자 오버로드로 인해 코드가 난독 화된다는 오류에 완전히 동의하지 않습니다. 이는 개발자가 결정할 수 있기 때문입니다. 이것은 생각하기에 순진하고 아주 정직하기 때문에 나이가 들었습니다.
Java 8에서 연산자 오버로드를 추가하기위한 +1
+
문자열과 같은 것을 연결 하는 Java의 사용 은 IMHO가 매우 무시 무시합니다 /
.C 및 FORTRAN의 전체 및 분수 분할에 대한 과부하입니다 . 많은 버전의 Pascal에서 모든 숫자 유형에 산술 연산자를 사용하면 피연산자를로 변환하는 것과 같은 Real
결과를 얻을 수 있지만 정수가 아닐 수있는 결과 는 정수를 통해 할당되기 전에 공급 Trunc
되거나 전달되어야합니다 Round
.
Java를 구현 언어로 가정하면 a, b 및 c는 모두 초기 값이 null 인 Complex 유형에 대한 참조입니다. 또한 언급 된 BigInteger 및 유사한 불변의 BigDecimal 과 같이 Complex가 변경 불가능하다고 가정 하면 b와 c를 추가하여 반환 된 Complex에 대한 참조를 할당 하고이 참조를 a와 비교하지 않기 때문에 다음을 의미한다고 생각합니다.
아닙니다 :
Complex a, b, c; a = b + c;
다음보다 훨씬 간단합니다.
Complex a, b, c; a = b.add(c);
때로는 연산자 오버로드, 친구 클래스 및 다중 상속을 갖는 것이 좋을 수도 있습니다.
그러나 나는 여전히 좋은 결정이라고 생각합니다. Java가 연산자 오버로딩을 가졌다면 소스 코드를 보지 않고도 연산자 의미를 확신 할 수 없었습니다. 현재는 필요하지 않습니다. 그리고 연산자 오버로드 대신 메소드를 사용하는 예제도 읽을 수 있다고 생각합니다. 더 명확하게하고 싶다면 항상 털이 많은 문장 위에 주석을 추가 할 수 있습니다.
// a = b + c
Complex a, b, c; a = b.add(c);
이것이 허용하지 않는 좋은 이유가 아니라 실용적인 이유입니다.
사람들은 항상 책임감있게 그것을 사용하지는 않습니다. Python 라이브러리 scapy에서이 예제를보십시오.
>>> IP()
<IP |>
>>> IP()/TCP()
<IP frag=0 proto=TCP |<TCP |>>
>>> Ether()/IP()/TCP()
<Ether type=0x800 |<IP frag=0 proto=TCP |<TCP |>>>
>>> IP()/TCP()/"GET / HTTP/1.0\r\n\r\n"
<IP frag=0 proto=TCP |<TCP |<Raw load='GET / HTTP/1.0\r\n\r\n' |>>>
>>> Ether()/IP()/IP()/UDP()
<Ether type=0x800 |<IP frag=0 proto=IP |<IP frag=0 proto=UDP |<UDP |>>>>
>>> IP(proto=55)/TCP()
<IP frag=0 proto=55 |<TCP |>>
설명은 다음과 같습니다.
/ 연산자는 두 레이어 사이의 작성 연산자로 사용되었습니다. 그렇게 할 때, 하위 계층은 상위 계층에 따라 하나 이상의 기본 필드가 오버로드 될 수 있습니다. (여전히 원하는 값을 줄 수 있습니다). 문자열은 원시 레이어로 사용할 수 있습니다.
Java 연산자 오버로딩의 기본 지원에 대한 대안
Java에는 연산자 오버로드가 없으므로 다음과 같은 대안을 살펴보십시오.
누구든지 다른 사람을 알고 있다면 의견을 말하십시오.이 목록에 추가하겠습니다.
Java 언어는 연산자 오버로드를 직접 지원하지 않지만 Java 프로젝트에서 Manifold 컴파일러 플러그인 을 사용하여 활성화 할 수 있습니다. Java 8-13 (현재 Java 버전)을 지원하며 IntelliJ IDEA에서 완전히 지원됩니다.