2014년 9월 2일 화요일

C#, 닷넷, 연산자 오버로딩[닷넷C#교육/ADO.NET강좌/ASP.NET교육잘하는곳/C#,ASP.NET교육추천/닷넷실무교육/.NET,C#/ADO.NET교육/닷넷학원/ASP.NET실무교육]

C#, 닷넷, 연산자 오버로딩,닷넷강좌,닷넷교육
 
연산자 오버로딩이란 +, >와 같은 표준 연산자들을 클래스의 용도에 맞게 작동토록 한 것이다. 연산자를 오버로딩 한다는 것은 이름은 같지만 받아 들이는 피연산자의 형식이 다른 연산자를 여러 개 정의 한다는 뜻이다. 연산자 오버로딩은 표준 연산자들이 가지는 단순 형식들에 대해 가지는 의미를 좀더 복잡한 형식에도 그데로 적용하고자 할 때 유용하게 쓰인다.
다음과 같은 AddClass1 이 있다고 하자.
 
public class AddClass1 {
 public int val;
}
 
아래의 코드는 될 것 같지만 컴파일 되지 않는다.
 
AddClass1 op1 = new AddClass();
op1.val=1
AddClass1 op2 = new AddClass();
op2.val=2
AddClass1 op3 = op1 + op2;  //오류 +연산자가 AddClass1 형식의 피연산자에는 적용되지 않는 다는 점이다.
 
위의 예제를 다음과 같이 고쳐 보자.

using System;
namespace OperatorOverload1
{
 public class AddClass1 
 {
  public int val;
  public static AddClass1 operator + (AddClass1 op1, AddClass1 op2) 
  {
   AddClass1 obj = new AddClass1();
   obj.val = op1.val + op2.val;
   return obj;
  }
 }

 class Test 
 {
  static void Main() 
  {
   AddClass1 op1 = new AddClass1();
   op1.val=1;
   AddClass1 op2 = new AddClass1();
   op2.val=2;
   AddClass1 op3 = op1 + op2;
   Console.WriteLine("op1 + op2 = {0}", op3.val);
  } 
 }
}
결과는 다음과 같다.
Op1 + op2 = 3

[조금 변형한 아래의 예제를 보자]


using System;
namespace OperatorOverload1
{
 public class AddClass2 
 {
  public int val;
  //아래의 함수는 AddClass1, AddClass2에서는 정의가 가능하며 AddClass3에서는 불가
  public static AddClass3 operator + (AddClass1 op1, AddClass2 op2) 
  {
   AddClass3 obj = new AddClass3();
   obj.val = op1.val + op2.val;
   return obj;
  }
  
 }
 public class AddClass1
 {
  public int val;
 }
 public class AddClass3
 {
  public int val;
  
 }
 class Test 
 {
  static void Main() 
  {
   AddClass1 op1 = new AddClass1();
   op1.val=1;
   AddClass2 op2 = new AddClass2();
   op2.val=2;
   AddClass3 op3 = op1 + op2;
   Console.WriteLine("op1 + op2 = {0}", op3.val);
  } 
 }
}
다음은 C#에서 오버로딩 할 수 있는 연산자들이다.
 
단항 연산자 : +, -, !, ~, ++, --, true, false
이항 연산자 : +, -, *, /, %, &, |, ^, <<, >>
비교 연산자 : ==, !=, <, <=, >, >=
 
- true와 false를 오버라이딩 하면 클래스들을 부울 표식 안에서 사용 할 수 있다.
- += 같은 배정 연산자는 오버로딩 할 수 없지만 +연산자를 오버로딩 함으로서 +=을 오버로딩 한 것과 같은 효과를 나타낸다. =의 경우 오버로딩 할 수 없는데 이 연산자는 작동 방식을 바꿀 필요가 없는 것이다.  &&와 ||역시 오버로딩 할 수 없는데 이것 역시 &, |를 오버로딩 하면 된다. 
- < 와 >의 경우 반드시 쌍으로 오버로딩 해야 한다. 즉 < 를 오버로딩 했을 때 >도 반드시 오버로딩 오버로딩 해야 한다. 비교연산자를 오버로딩 할 때는 한 연산자에서 다른 연산자를 호출하는 식으로 구현해서 코드를 줄이곤 한다.
 
public class AddClass1 {
 public int val;
 
public static bool operator >= (AddClass1 op1, AddClass1 op2) {
return (op1.val >= op2.val);
}
 
 public static bool operator < (AddClass1 op1, AddClass1 op2) {
  return !(op1 >= op2);

}
 
- ==와 != 연산자에 대해서는 위의 경우 처럼 사용이 가능하나 Object.Equals()와 Object.GetHashCode()도 재정의 하는 경우가 많이 있다. 즉 ==를 재정의 하는 부분에서 Equals 메소드도 재정의 함으로서 사용자가 == 또는 Equals() 어느 것으로 비교 하든지 같은 결과가 나타나게 할 수 있다.
 
public class AddClass1 {
 public int val;
 public static bool operator == (AddClass1 op1, AddClass1 op2) {
  return (op1.val == op2.val);
 }
 public static bool operator != (AddClass1 op1, AddClass1 op2) {
  return !(op1 == op2);
}
public override bool Equals(object op1) {
 return val == ((AddClass1)op1).val;
}
//GetHashCode 는 개체의 상태에 기반한 고유한 int 값을 얻는데 사용 한다.
public override int GetHashCode() {
 return val;
}
}
 
변환연산자

산술연산자 뿐 아니라  형식들 사이의 암시적, 명시적 변환 방식도 오버로딩 할 수 있다. 서로 관련되지 않은 즉 상속 관계도 없고 공통의 인터페이스도 없는 형식들 사이의 변환을 지원 하려면 그러한 변환 연산자 오버로딩 이 필요 하다.
 
- 예를들어 ConvClass1과 ConvClass2 라는 두개의 클래스가 아무런 관계가 없다고 할 때 다음과 같은 암시적 변환은 불가능하다.
 
 
ConvClass1 op1 = new ConvClass1();
ConvClass2 op2 = op1;
 
물론 아래와 같은 명시적인 변환 역시 불가능하다.
 
ConvClass1 op1 = new ConvClass1();
ConvClass2 op2 = (ConvClass2)op1;
 
위의 두 가지 변환을 가능하게 할려면 다음 예처럼 변환방식을 코드로 정의 해 부어야 한다.
 
public class ConvClass1 {
 public int val;
 //암시적 변환을 지정하는 키워드 : implicit
 public static implicit operator ConvClass2(ConvClass1 op1) {
  ConvClass2 retVal = new ConvClass2();
  retVal.val = op1.val;
  return retVal;
}
}
public class ConvClass2 {
 public double val;
 //명시적변환을 지정하는 키워드 : explicit
 public static explicit operator ConvClass1(ConvClass2 op1) {
  ConvClass1 retVal = new ConvClass1();
  checked {
   //double을 int로 변환
   retVal.val = (int)op1.val;
  }
return retVal;
 }
}
ConvClass1은 int 값을 담으며, Convclass2는 하나의 double 값을 담는다. int 값은 double로 암시적으로 변환 될 수 있으므로 ConvClass1 에서 ConvClass2로의 변환을 암시적으로 정의 할 수 있다. 그 역은 가능하지 않으므로 반드시 명시적 변환으로 정의 해야 한다.

[연산자 오버로딩 예제]
 
두 날짜의 차이를 구하기 위한 예문
 

using System;
public class Time 
{
 private int Year = 0;
 private int DDay = 0;
 private int Month = 0;
 
// 기본 생성자
 public Time() 
 {
  this.Year = 0;
  this.Month = 0;
  this.DDay = 0;
 }
 
 //매개변수가 있는 경우의 생성자
 public Time(int Year, int Month, int DDay) 
 {
  this.Year = Year;
  this.Month = Month;
  this.DDay = DDay;
 }
 
// '-' 연산자 Overloading
 public static Time operator-(Time t1, Time t2) 
 {
  int newYear = t1.Year - t2.Year;  //년도는 그냥 빼자
  int newMonth = 0;
  int newDDay = 0;
  //뒤의 월이 큰 경우
  if (t1.Month < t2.Month) 
  {
   newYear = newYear -1;     //년을 1 빼고
   newMonth = newMonth + 12; //월을 12를 더 해줌, Carry(올림수)
  }
  newMonth = newMonth + t1.Month - t2.Month;
  
  //뒤의 일이 큰 경우
  if (t1.DDay < t2.DDay) 
  {
   newMonth = newMonth -1;
   newDDay = newDDay + 30;
  }
  
  newDDay = newDDay + t1.DDay - t2.DDay;
  Time newTime = new Time(newYear, newMonth, newDDay);
  return newTime;
 }
 public override string ToString() 
 {
  return String.Format("{0}:{1}:{2}", Year, Month, DDay);
 }
}
public class OpOverloadTest 
{
 public static void Main() 
 {
  Time t1 = new Time(2004, 05, 05);
  Time t2 = new Time(1977, 07, 07);
  Time t3 = t1 - t2;
  Console.WriteLine(t1);
  Console.WriteLine(t2);
  Console.WriteLine(t3);
 }
}



 기업100%환급/오라클/자바/스프링/안드로이드/닷넷C#/jQUERY개발… 오라클자바…12-271691
 [채용예정교육]오라클자바개발잘하는신입뽑기2개월과정,교육전취…오라클자바…12-111207
53 [평일주간]100%환급6건,안드로이드,자바,C#,스프링3.2,SQL,힌트/… 오라클자바…03-15966
52 [주말주간]C#, ASP.NET마스터 오라클자바…01-311126
51 [평일,기업100%환급]SQL기초에서 Schema Object까지 오라클자바…01-31889
50 [평일야간]HTML5, CSS3,Ajax, jQuery마스터과정 오라클자바…01-31816
49 [평일주간,평일야간,주말]Spring,MyBatis,Hibernate개발자과정 오라클자바…01-191105
48 [평일주간,평일야간,주말]안드로이드개발자과정 오라클자바…01-11991
47 [평일야간,주말주간]JAVA,Network&WEB&Framework 오라클자바…01-031485
46 기업100%환급/오라클/자바/스프링/안드로이드/닷넷C#/jQUERY개발… 오라클자바…12-271691
45 [평일야간,주말]자바기초에서JSP,Ajax,jQuery,Spring3.2,MyBatis… 오라클자바…12-191236
44 웹퍼블리싱 마스터(HTML5,CSS3,jQUERY,AJAX,JavaScript) 오라클자바…12-141230
43 [채용예정교육]오라클자바개발잘하는신입뽑기2개월과정,교육전취… 오라클자바…12-111207
42 [평일,기업100%환급]자바기초에서 JDBC, Servlet/JSP까지 오라클자바…12-09973
41 [평일야간]닷넷(C#,Network,ADO.NET,ASP.NET)마스터 오라클자바…12-011145
40 [기업100%환급]C#4.0,WinForm,ADO.NET프로그래밍(평일주간(단기)… 오라클자바…12-011373
39 [평일야간,주말,주말야간]SQL기초에서실무까지(SQL기초,PLSQL,힌… 오라클자바…12-01860

댓글 없음:

댓글 쓰기