Method Overloading vs Method Overriding

http://dis.dankook.ac.kr/lectures/hci10/entry/Method-Overloading-vs-Method-Overriding

Method Overloading: 동일한 함수명에 매개변수가 다른 함수를 둘 이상 정의하는 것으로, 동일한 함수 기능을 수행하지만 다른 매개변수의 경우를 처리할 때 사용

Method Overriding: 상속받은 파생 클래스에서 동일한 함수명에 동일한 매개변수로 정의하여 함수를 재정의하는 것으로 상속되어진 함수의 기능을 변경해서 재사용하고 싶을 때 사용

class Point : IEquatable<Point>, IComparable<Point>
{
// static member field
protected static int count = 0;
// instance member field
protected int x, y;
// property
public int X
{
get { return this.x; }
set { this.x = value; }
}
public int Y
{
get { return this.y; }
set { this.y = value; }
}
public static int Count
{
get { return count; } // error: this.count 는 사용할 수 없음
}
// constructor & destructor
public Point() : this(0, 0) { }
public Point(int x, int y) { this.x = x; this.y = y; count++; }
~Point() { count–; }
// method
public void SetPosition(int x, int y) { this.x = x; this.y = y; }
public void Move(int x, int y) { this.x += x; this.y += y; }
// override method
public override string ToString() { return (String.Format(“({0}, {1})”, x, y)); }
// virtual method
public virtual void Print() { Console.WriteLine(“X={0} Y={1}”, x, y); }public virtual void Sum(Point other) { x += other.X; y += other.Y; }
// static method
public static int GetCount() { return count; }

// operator++ overload
public static Point operator++(Point p) { ++p.x; ++p.y; return p; }
// operator== overload
public static bool operator==(Point p1, Point p2) { return p1.Equals(p2); }
// operator!= overload
public static bool operator!=(Point p1, Point p2) { return !p1.Equals(p2); }
public override int GetHashCode() { return x ^ y; }
public override bool Equals(object obj)
{
if (!(obj is Point))
return false;
return Equals((Point)obj);
}

// IEquatable
public virtual bool Equals(Point other)
{
if (object.ReferenceEquals(this, other)) // if reference is the same
return true;
return (this.x == other.x && this.y == other.y);
}
// IComparable
public int CompareTo(Point other)
{
if (this.x > other.x)
{
return 1;
}
else if (this.x < other.x)
{
return -1;
}
else
{
return 0;
}
}

}

class Point3D : Point, IEquatable<Point3D>
{

// instance member field
protected int z;

// property
public int Z
{
get { return this.z; }
set { this.z = value; }
}

// constructor & destructor
public Point3D() : this(0, 0, 0) { }
public Point3D(int x, int y, int z) : base(x, y) { this.z = z; }
~Point3D() { }

public void SetPosition(int x, int y, int z) { base.SetPosition(x, y); this.z = z; }
public void Move(int x, int y, int z) { base.Move(x, y); this.z += z; }

// override method
public override string ToString() { return (String.Format(“({0}, {1}, {2})”, x, y, z)); }
public override void Print() { Console.WriteLine(“X={0} Y={1} Z={2}”, x, y, z); }

public override void Sum(Point other)
{

if (other is Point3D)
Sum((Point3D)other);
else base.Sum(other);
}


// overload method
public void Sum(Point3D other) { x += other.X; y += other.Y; z += other.Z; }
// operator++ overload
public static Point3D operator++(Point3D p) { ++p.x; ++p.y; ++p.z; return p; }
// operator== overload
public static bool operator ==(Point3D p1, Point3D p2) { return p1.Equals(p2); }
// operator!= overload
public static bool operator !=(Point3D p1, Point3D p2) { return !p1.Equals(p2); }
public override int GetHashCode() { return x ^ y ^ z; }
public override bool Equals(object obj)
{

if (!(obj is Point3D))

return false;

return Equals((Point3D)obj);
}
public override bool Equals(Point other)
{

if (other is Point3D))

return Equals((Point3D)other);

else

return base.Equals(other);

}

// IEquatable
public bool Equals(Point3D other)
{

if (object.ReferenceEquals(this, other))
return true;
return this.x == other.x && this.y == other.y && this.z == other.z;
}
// IComparable
public int CompareTo(Point3D other)
{
if (this == other)
{
return 0;
}
else if (this.x < other.x)
{
return -1;
}
else if ((this.x == other.x) && (this.y < other.y))
{

return -1;
}

else if ((this.x == other.x) && (this.y == other.y) && (this.z < other.z))
{

return -1;
}

else
{

return 1;
}
}

}

class PointTest
{
// pass-by-value (value type)
static void Swap(int p1, int p2)
{
int p;
p = p1;
p1 = p2;
p2 = p;
}
// pass-by-reference (value type)
static void Swap(ref int p1, ref int p2)
{
int p;
p = p1;
p1 = p2;
p2 = p;
}
// pass-by-value (reference type)
static void Swap(int[] p1, int[] p2)
{
int[] p;
p = p1;
p1 = p2;
p2 = p;
}
// pass-by-value (reference type)
static void Swap(ref int[] p1, ref int[] p2)
{
int[] p;
p = p1;
p1 = p2;
p2 = p;
}
static void Swap(ref Point p1, ref Point p2)
{
Point p;
p = p1;
p1 = p2;
p2 = p;
}
static void Swap(ref Point3D p1, ref Point3D p2)
{
Point3D p;
p = p1;
p1 = p2;
p2 = p;
}
static void Main(string[] args)
{
// value type: pass-by-value/pass-by-reference
int i = 5, j = 10;
Console.WriteLine(“Before: i={0}, j={1}”, i, j); // i=5, j=10
Swap(i, j);
Console.WriteLine(“After Swap(i,j): i={0}, j={1}”, i, j); // i=5, j=10
Swap(ref i, ref j);
Console.WriteLine(“After Swap(ref i, ref j): i={0}, j={1}”, i, j); // i=10, j=5
// reference type: pass-by-value/pass-by-reference
int[] arr1 = { 1, 2, 3 };
int[] arr2 = { 4, 5, 6, 7, 8 };
Console.WriteLine(“Before array pass-by-value swap: “);
Console.Write(“arr1: “);
foreach (int a in arr1) Console.Write(“{0} “, a); // arr1: 1 2 3
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2) Console.Write(“{0} “, a); // arr2: 4 5 6 7 8
Console.WriteLine();
Swap(arr1, arr2);
Console.WriteLine(“After Swap(arr1, arr2): “);
Console.Write(“arr1: “);
foreach (int a in arr1) Console.Write(“{0} “, a); // arr1: 1 2 3
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2) Console.Write(“{0} “, a); // arr2: 4 5 6 7 8
Console.WriteLine();
Swap(ref arr1, ref arr2);
Console.WriteLine(“After Swap(ref arra1, ref arr2): “);
Console.Write(“arr1: “);
foreach (int a in arr1) Console.Write(“{0} “, a); // arr1: 4 5 6 7 8
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2) Console.Write(“{0} “, a); // arr2: 1 2 3
Console.WriteLine();
// Point
Console.Write(“p1: “);
Point p1 = new Point();
p1.Print(); // Point.Print() (0, 0)
Console.Write(“p2: “);
Point p2 = new Point();
p2.Print(); // Point.Print() (0, 0)
p1.SetPosition(10, 10); // Point.SetPosition(int, int)
Console.Write(“p1 SetPosition: “);
p1.Print(); // Point.Print() (10, 10)
p1.Move(20, 50); // Point.Move(int, int)
Console.Write(“p1 Move: “);
Console.WriteLine(“p1=” + p1); // Point.ToString() (30, 60)
p2.SetPosition(20, 30); // Point.SetPosition(int, int)
Console.Write(“p2 SetPosition: “);
p2.Print(); // Point.Print() (20, 30)
//포인터 객체 교환함수 호출
Console.WriteLine(“\nSwap”);
Swap(ref p1, ref p2);
Console.WriteLine(“p1: {0}”, p1); // Point.ToString() (20, 30)
Console.WriteLine(“p2: {0}”, p2); // Point.ToString() (30, 60)
Console.WriteLine();
Console.WriteLine(“p1.m_nX={0}, p1.m_nY={1}, Point.GetCount()={2}”, p1.X, p1.Y, Point.Count);
Console.WriteLine(“p2.m_nX={0}, p2.m_nY={1}, Point.GetCount()={2}”, p2.X, p2.Y, Point.Count);
// Point3D
Console.Write(“p3: “);
Point3D p3 = new Point3D();
p3.Print(); // Point3D.Print() (0, 0, 0)
Console.Write(“p4: “);
Point3D p4 = new Point3D();
p4.Print(); // Point3D.Print() (0, 0, 0)
Console.WriteLine();
p3.SetPosition(10, 20); // Point3D.SetPosition(int,int)
Console.Write(“p3 SetPosition: “);
p3.Print(); // Point3D.Print() (10, 20, 0)
p3.SetPosition(30, 40, 50); // Point3D.SetPosition(int,int,int)
Console.Write(“p3 SetPosition: “);
p3.Print(); // Point3D.Print() (30, 40, 50)
++p3; // Point3D.operator++
Console.Write(“++p3: “);
p3.Print(); // Point3D.Print() (31, 41, 51)
p3.Move(20, 30, 40); // Point3D.Move(int,int,int)
Console.Write(“p3 Move: “);
p3.Print(); // Point3D.Print() (51, 71, 91)
p3.Move(10, 10); // Point3D.Move(int,int)
Console.Write(“p3 Move: “);
Console.WriteLine(p3); // Point3D.ToString() (61, 81, 91)
Console.WriteLine();
p4.SetPosition(100, 200, 300); // Point3D.SetPosition(int,int,int)
Console.Write(“p4 SetPosition: “);
p4.Print(); // Point3D.Print() (100, 200, 300)
p4.Move(10, 10, 10); // Point.Move(int, int,int)
Console.Write(“p4 Move: “);
p4.Print(); // Point3D.Print() (110, 210, 310)
//SUM
Console.WriteLine(“\nSUM”);
p3.Sum(p4); // Point3D.Sum(Point3D) (61+110, 81+210, 91+310)
p3.Print(); // Point3D.Print() (171, 291, 401)
//포인터 객체 교환함수 호출
Console.WriteLine(“\nSwap”);
Swap(ref p3, ref p4); // (171,291,401) <-> (110,210,310)
Console.WriteLine(“p1: {0}”, p3); // Point3D.ToString() (110,210,310)
Console.WriteLine(“p2: {0}”, p4); // Point3D.ToString() (171,291,401)
Console.WriteLine();
Console.WriteLine(“p3.m_nX={0}, p3.m_nY={1}, p3.m_nZ={2}, Point.GetCount()={3}”, p3.X, p3.Y, p3.Z, Point.GetCount());
Console.WriteLine(“p4.m_nX={0}, p4.m_nY={1}, p4.m_nZ={2}, Point.count={3}”, p4.X, p4.Y, p4.Z, Point.Count);
if (p3 == p4) Console.WriteLine(“p3 == p4”); // Point3D.operator==
if (p3 != p4) Console.WriteLine(“p3 != p4”); // Point3D.operator!=
Console.Write(“p5: “);
// polymorphism
Point p5 = p3; // upcasting – P5는 Point 타입인 Point3D 객체
p5.Print(); // Point3D.Print() (late binding) (110,210,310)
p5.SetPosition(10,20); // Point.SetPosition(int,int)
p5.Print(); // Point3D.Print() (late binding) (10,20,310)
((Point3D)p5).SetPosition(10,20,30); // downcasting – Point3D.SetPosition(int,int,int)

p5.Print(); // Point3D.Print() (late binding) (10,20,30)
Console.Write(“p6: “);
Point p6 = new Point3D(110, 210, 310); // upcasting – p6도 Point 타입인 Point3D 객체
p6.Print(); // Point3D.Print() (late binding) (110,210,310)
p5.Sum(p6); // Point3D.Sum(Point) (late binding) (10+110, 20+210, 30+310)
p5.Print(); // Point3D.Print() (late binding) (110,230,340)
p6.Print(); // Point3D.Print() (late binding) (110,210,310)
Point3D p7 = (Point3D)p5; // downcasting
Console.WriteLine(p7); // Point3D.ToString()
Point3D p8 = p5 as Point3D;
Console.WriteLine(p7); // Point3D.ToString()
if (p7 == p8)
Console.WriteLine(“p7 == p8”); // p7 == p8
}
}

 

C# Collections

Collections are based on the ICollection interface, the IList interface, the IDictionary interface, or their generic counterparts. The IList interface and the IDictionary interface are both derived from the ICollection interface; therefore, all collections are based on the ICollection interface either directly or indirectly. In collections based on the IList interface (such as Array, ArrayList, or List<T>) or directly on the ICollection interface (such as Queue, ConcurrentQueue<T>, Stack, ConcurrentStack<T> or LinkedList<T>), every element contains only a value. In collections based on the IDictionary interface (such as the Hashtable and SortedList classes, the Dictionary<TKey, TValue> and SortedList<TKey, TValue> generic classes), or the ConcurrentDictionary<TKey, TValue> classes, every element contains both a key and a value. The KeyedCollection<TKey, TItem> class is unique because it is a list of values with keys embedded within the values and, therefore, it behaves like a list and like a dictionary.

Generic collections are the best solution to strong typing. However, if your language does not support generics, the System.Collections namespace includes base collections, such as CollectionBase, ReadOnlyCollectionBase, and DictionaryBase, which are abstract base classes that can be extended to create collection classes that are strongly typed. When efficient multi-threaded collection access is required, use the generic collections in the System.Collections.Concurrent namespace.

Collections can vary, depending on how the elements are stored, how they are sorted, how searches are performed, and how comparisons are made. The Queue class and the Queue<T> generic class provide first-in-first-out lists, while the Stack class and the Stack<T> generic class provide last-in-first-out lists. The SortedList class and the SortedList<TKey, TValue> generic class provide sorted versions of the Hashtable class and the Dictionary<TKey, TValue> generic class. The elements of a Hashtable or a Dictionary<TKey, TValue> are accessible only by the key of the element, but the elements of a SortedList or a KeyedCollection<TKey, TItem> are accessible either by the key or by the index of the element. The indexes in all collections are zero-based, except Array, which allows arrays that are not zero-based.

The LINQ to Objects feature allows you to use LINQ queries to access in-memory objects as long as the object type implements IEnumerable or IEnumerable<T>. LINQ queries provide a common pattern for accessing data; are typically more concise and readable than standard foreach loops; and provide filtering, ordering and grouping capabilities. LINQ queries can also improve performance. For more information, see LINQ to Objects and Parallel LINQ (PLINQ).


Title Description
Collections and Data Structures Discusses the various collection types available in the .NET Framework, including stacks, queues, lists, arrays, and dictionaries.
Hashtable and Dictionary Collection Types Describes the features of generic and nongeneric hash-based dictionary types.
Sorted Collection Types Describes classes that provide sorting functionality for lists and sets.
Generics in the .NET Framework Describes the generics feature, including the generic collections, delegates, and interfaces provided by the .NET Framework. Provides links to feature documentation for C#, Visual Basic, and Visual C++, and to supporting technologies such as reflection.

Object-Oriented Programming (OOP)

Class – defines the grouping of data and code, the “type” of an object
Instance – a specific allocation of a class
Message – sent to objects to make them act
Method – a “function” that an object knows how to perform
Instance Variables – a specific piece of data belonging to an object
Property – away to access instance variables and other attributes of an object
Encapsulation – keep implementation private and seperate from interface
Polymorphism – different objects, same interface
Inheritance – hierarchical organization. share code, customize or extend behaviors

C# == operator

static void Main(string[] args)
{
// 값형식과 참조형식
int val1 = 5;
int val2 = 10;
if (val1 == val2) // false (val1과 val2는 값이 다름)
Console.WriteLine(“val1 == val2”);
else
Console.WriteLine(“val1 != val2”);
object val3 = val1;
object val4 = val1;
if (val3 == val4) // false (val3와 val4는 같은 곳을 참조하지 않음)
Console.WriteLine(“val3 == val4”);
else
Console.WriteLine(“val3 != val4”);

int val5 = (int)val3;
int val6 = (int)val4;
if (val5 == val6) // true (val5와 val6은 같은 값을 가짐)
Console.WriteLine(“val5 == val6”);
else
Console.WriteLine(“val5 != val6”);

Point pos1 = new Point(val1, val2);
Point pos2 = new Point(val1, val2);
if (pos1 == pos2) // false (만약 Point Class가 ==연산자와 != 연산자와 Equals와 GetHashCode를 구현하지 않았다면 같은 곳을 참조하고 있지 않음) true (만약 Point Class가 데이터의 내용이 같은지를 판별하는 ==연산자와 !=연산자와 Equals와 GetHashCode를 구현했다면)
Console.WriteLine(“pos1 == pos2”);
else
Console.WriteLine(“pos1 != pos2”);
if (pos1.X == pos2.X) // true
Console.WriteLine(“pos1.X == pos2.X”);
else
Console.WriteLine(“pos1.X != pos2.X”);
if (pos1.Y == pos2.Y) // true
Console.WriteLine(“pos1.Y == pos2.Y”);
else
Console.WriteLine(“pos1.Y != pos2.Y”);

Point pos3 = pos1;
Point pos4 = pos1;
if (pos3 == pos4) // true (pos3와 pos4는 같은 곳을 참조하고 있음)
Console.WriteLine(“pos3 == pos4”);
else
Console.WriteLine(“pos3 != pos4”);

object pos5 = pos3;
object pos6 = pos4;
if (pos5 == pos6) // true (pos5와 pos6는 같은 곳을 참조하고 있음)
Console.WriteLine(“pos5 == pos6”);
else
Console.WriteLine(“pos5 != pos6”);

Point pos7 = (Point)pos6;
if (pos1 == pos7) // true (pos1, pos3, pos4, pos6, pos7는 같은 곳을 참조하고 있음)
Console.WriteLine(“pos1 == pos7”);
else
Console.WriteLine(“pos1 != pos7”);
if (pos2 == pos7) // false (만약 Point Class가 ==연산자와 != 연산자와 Equals와 GetHashCode를 구현하지 않았다면 같은 곳을 참조하고 있지 않음) true (만약 Point Class가 데이터의 내용이 같은지를 판별하는 ==연산자와 !=연산자와 Equals와 GetHashCode를 구현했다면)
Console.WriteLine(“pos2 == pos7”);
else
Console.WriteLine(“pos2 != pos7”);

C# ==operator vs Equals

http://msdn.microsoft.com/en-us/library/ms173147.aspx

// Operator Overloading
if (x == y) { // 컴파일시 x와 y가 동일한지 확인

// 참조형일 경우
object x = “hello”;
object y = ‘h’ + “ello”; // ensure it’s a different reference
if (x == y) { // 결과 => FALSE
if (x.Equals(y)) { // 결과 => TRUE

// string 형(참조형이긴 하지만)일 경우
// Equals와 equality operators (== and !=) 을 구현하여 string 객체의 값이 동일한지 확인
string x1 = “hello”;
string y1 = ‘h’ + “ello”; // ensure it’s a different reference
if (x1 == y1) { // 결과 => TRUE
if (x1.Equals(y1)) { // 결과 => TRUE

Dictionary

using System.Collections.Generic;

static Dictionary<string, FigureType> figureNameDic = new Dictionary<string, FigureType>();

static void SetFigureNameDictionary()
{
figureNameDic.Add(“삼각형”, FigureType.Triangle);
figureNameDic.Add(“Triangle”, FigureType.Triangle);
figureNameDic.Add(“TRIANGLE”, FigureType.Triangle);
figureNameDic.Add(“정사각형”, FigureType.Square);
figureNameDic.Add(“Square”, FigureType.Square);
figureNameDic.Add(“SQUARE”, FigureType.Square);
// 중간 생략…
}

 

C# Array/ArrayList

Person[] pArray = new Person[5];

// 만약 Person 객체를 하나만 생성한 후 for문에서 공유해 사용할 경우
// 마지막으로 입력된 데이터로 모든 데이터값이 치환됨
Person p = new Person();
for (int i = 0; i < 5; i++) {
p.Name = Console.ReadLine();           // 입력정보
p.age = int.Parse(Console.ReadLine()); // 입력정보
pArray[i] = p;                                  // 리스트에 들어간 모든 원소는 동일한 p
}

 

Person[] pArray = new Person[5];

// 아래와 같이 for문 안에 Person p = new Person()와같이 새로운 객체를 생성해야
// 각자 다르게 입력된 정보가 들어가게 됨
for (int i = 0; i < 5; i++) {
Person p = new Person();
    p.Name = Console.ReadLine();           // 입력정보
p.age = int.Parse(Console.ReadLine()); // 입력정보
pArray[i] = p;                                  // 이때 p는 새로운 Person객체
}


http://dis.dankook.ac.kr/lectures/hci10/entry/C-ArrayList
 (ArrayList 사용예)