Assignment3
연습문제 (3)
□ 단원 : C# 기초 □ 목표 : C# 객체지향 프로그래밍 □ 주요 연습 내용 : collections, class, interface, 속성, FileIO 연습 □ 준비자료 : 지진데이터 |
연습문제 Ex3 (Due by 11/12 금 24시까지)
-cyber 강의(cyber.dku.edu)로 source code, executable file, solution/project VC# file,
보고서를 학번_이름_Ex3.zip으로 묶어서 낼 것. 보고서 (30%)
[연습문제]
1. QuakeData.cs 파일에 QuakeData 클래스를 정의하라. (10%)
다음 데이터 멤버 필드를 포함한다.
– private int year, month, day;
– private double time;
– private double lat, lon;
– private double magnitude, depth;
그리고 각 멤버 필드에 대한 속성(Property)를 지정하여 외부에서 사용할 수 있도록 한다.
– public int Year { get; set;}// get과 set에 대한 내부구현 필요
– public int Month { get; set;}
– public int Day { get; set;}
– public double Time { get; set;}
– public double Lat { get; set;}
– public double Lon { get; set;}
– public double Magnitude { get; set;}
– public double Depth { get; set;}
또한 다음 메소드를 포함한다.
– QuakeData() // 기본 생성자 내부구현 필요
– QuakeData(int, int, int, double, double, double, double, double)// 생성자 내부구현필요
– public override string ToString() // QuakeData의 모든 정보를 csv 포맷으로 출력하는 메소드 내부구현 필요
2. QuakeData클래스에 IComparable<QuakeData>와 IEquatable<QuakeData> 인터페이스를 상속받고 다음 메소드를 구현한다. (10%)
– public int CompareTo(QuakeData other){ // Year 순서대로 비교하는 내부구현 필요}
– public bool Equals(QuakeData other){ // == 내부구현 필요 }
3. QuakeDataComparer.cs 파일에는 IComparer<QuakeData> 인터페이스를 상속받은 각종 비교 클래스들을 구현한다. QuakeDataManager 클래스의 Sort 메소드에서 사용됨. (10%)
– class QuakeMonthComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeDayComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeTimeComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeLatComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeLonComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeMagnitudeComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
– class QuakeDepthComparer : IComparer<QuakeData>
{ public int Compare(QuakeData p, QuakeData q) // 내부구현 필요 }
4. QuakeDataManager.cs 파일에는 QuakeDataManager 클래스를 정의하라. (20%)
http://msdn.microsoft.com/en-us/library/system.collections.arraylist(VS.71).aspx
QuakeSortMode 열거형을 정의한다.
– enum QuakeSortMode { Year, Month, Day, Time, Lat, Lon, Magnitude, Depth}
QuakeDataManager클래스는 리스트를 데이터 멤버로 포함한다.
– private List<QuakeData> pList = new List<QuakeData>();
그리고 메소드는 다음을 포함한다.
// cvs(comma separated value) 텍스트를 읽어서 pList에 추가
// StreamReader 사용
– public void Import(string filename) { // 내부구현 필요 }
// pList의 모든 원소를 cvs(comma separated value) 텍스트로 저장
// StreamWriter 사용
– public void Export() { // 내부구현 필요 }
// 선택한 모드에 따라서 리스트의 데이터를 Year, Month, Day, Time, Lat, Lon, Magnitude, Depth 순서로 정렬
// QuakeMonthComparer, QuakeDataComparer, QuakeTimeComparer 등을 사용
– public void Sort(QuakeSortMode mode) { // 내부구현 필요 }
// 리스트에 모든 QuakeData를 출력
// pList.ForEach에 각각의 Print를 출력하는 Action delegate 사용
– public void Print() { pList.ForEach(Print); }
– private void Print(QuakeData q) { Console.WriteLine(q); }
5. QuakeDataManger클래스 또는 Program 클래스의 Main 함수에서 본인이 더 테스트해보고 싶은 Method를 추가하라. (20%)
// 리스트에서 강도가 몇 이상인 조건을 만족하는 새 리스트 List<QuakeData> 반환
// pList.FindAll에 IsMagnitudeGreater를 호출하는 Predicate delegate 사용
// IsMagnitudeGreater 안에서는 사용자가 지정한 mag값보다 클 경우 true반환
– public List<QuakeData> GetQuakeListByMagnitude(double mag)
– private bool IsMagnitudeGreater(QuakeData q)
// 리스트에서 지정한 영역에 속한 데이터만 뽑아 새 리스트 List<QuakeData> 반환
// pList.FindAll에 InRange안에 있는지 알려주는 Predicate delegate 사용
// InRange 안에서는 사용자가 지정한 lat1, lon1, lat2, lon2 안에 있을 경우 true반환
– public List<QuakeData> GetQuakeListByRange(double lat1, double lon1, double lat2, double lon2)
– private bool InRange(QuakeData q)
C# Formatting Numeric String
C# ArrayList
http://dotnetperls.com/arraylist
// 마지막으로 입력된 데이터로 모든 데이터값이 치환됨
Person p = new Person();
for (int i = 0; i < 5; i++) {
p.Name = Console.ReadLine(); // 입력정보
p.ID = int.Parse(Console.ReadLine()); // 입력정보
p.Phone = Console.ReadLine(); // 입력정보
p.Address = Console.ReadLine(); // 입력정보
pArray.Add(p); // 리스트에 들어간 모든 원소는 동일한 p
}
// 각자 다르게 입력된 정보가 들어가게 됨
for (int i = 0; i < 5; i++) {
Person p = new Person();
p.Name = Console.ReadLine(); // 입력정보
p.ID = int.Parse(Console.ReadLine()); // 입력정보
p.Phone = Console.ReadLine(); // 입력정보
p.Address = Console.ReadLine(); // 입력정보
pArray.Add(p); // 이때 p는 새로운 Person객체
}
C# Generic Class vs. C++ Template Class
Point Class Assembly
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; }
// ToString method override
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); }
// 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 bool Equals(Point other)
{
if (this.x == other.x && this.y == other.y)
return true;
return false;
}
// 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 ToString method
public override string ToString() { return (String.Format(“({0}, {1}, {2})”, x, y, z)); }
// overrided method
public override void Print() { Console.WriteLine(“X={0} Y={1} Z={2}”, x, y, 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);
}
// IEquatable
public bool Equals(Point3D other)
{
if (this.x == other.x && this.y == other.y && this.z == other.z)
return true;
return false;
}
}
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);
Swap(i, j);
Console.WriteLine(“After integer pass-by-value swap: i={0}, j={1}”, i, j);
Swap(ref i, ref j);
Console.WriteLine(“After integer pass-by-reference Swap: i={0}, j={1}”, i, j);
// 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);
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2)
Console.Write(“{0} “, a);
Console.WriteLine();
Swap(arr1, arr2);
Console.WriteLine(“After array pass-by-value swap: “);
Console.Write(“arr1: “);
foreach (int a in arr1)
Console.Write(“{0} “, a);
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2)
Console.Write(“{0} “, a);
Console.WriteLine();
Swap(ref arr1, ref arr2);
Console.WriteLine(“After array pass-by-reference swap: “);
Console.Write(“arr1: “);
foreach (int a in arr1)
Console.Write(“{0} “, a);
Console.WriteLine();
Console.Write(“arr2: “);
foreach (int a in arr2)
Console.Write(“{0} “, a);
Console.WriteLine();
Console.Write(“p1: “);
Point p1 = new Point();
Console.Write(“p2: “);
Point p2 = new Point();
// Point
p1.SetPosition(10, 10); // 변수 값 지정
Console.Write(“p1 SetPosition: “);
p1.Print(); // 현재 좌표 출력
p1.Move(20, 50); // 좌표 변경 (점의 위치 이동)
Console.Write(“p1 Move: “);
p1.Print(); // 현재 좌표 출력
Console.WriteLine(“p1=” + p1);
p2.SetPosition(20, 30); // 변수 값 지정
Console.Write(“p2 SetPosition: “);
p2.Print(); // 현재 좌표 출력
//포인터 객체 교환함수 호출
Console.WriteLine(“\nSwap”);
Swap(ref p1, ref p2);
Console.WriteLine(“p1: {0}”, p1);
Console.WriteLine(“p2: {0}”, p2);
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();
Console.Write(“p4: “);
Point3D p4 = new Point3D();
Console.WriteLine();
p3.SetPosition(10, 20);
Console.Write(“p3 SetPosition: “);
p3.Print(); // 현재 좌표 출력
p3.SetPosition(30, 40, 50);
Console.Write(“p3 SetPosition: “);
p3.Print(); // 현재 좌표 출력
++p3;
Console.Write(“++p3: “);
p3.Print(); // 현재 좌표 출력
p3.Move(20, 30, 40); // 좌표 변경 (점의 위치 이동)
Console.Write(“p3 Move: “);
p3.Print(); // 현재 좌표 출력
p3.Move(10, 10); // 좌표 변경 (점의 위치 이동)
Console.Write(“p3 Move: “);
Console.WriteLine(p3); // p3는 Point클래스의 ToString이 호출
Console.WriteLine();
p4.SetPosition(100, 200, 300);
Console.Write(“p4 SetPosition: “);
p4.Print(); // 현재 좌표 출력
p4.Move(10, 10, 10); // 좌표 변경 (점의 위치 이동)
Console.Write(“p4 Move: “);
p4.Print(); // 현재 좌표 출력
//포인터 객체 교환함수 호출
Console.WriteLine(“\nSwap”);
Swap(ref p3, ref p4);
Console.WriteLine(“p1: {0}”, p3);
Console.WriteLine(“p2: {0}”, p4);
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”);
if (p3 != p4)
Console.WriteLine(“p3 != p4”);
Console.Write(“p5: “);
Point p5 = p3;
p5.Print(); // 현재 좌표 출력 p5는 Point3D – polymorphism
Console.Write(“p6: “);
Point p6 = new Point3D(110, 210, 310); // p6도 Point3D
p6.Print(); // Point3D의 Print가 호출 (late binding) – polymorphism
Point3D p7 = (Point3D)p5;
Console.WriteLine(p7); // p7는 Point3D클래스의 ToString이 호출
if (p7 == p5)
Console.WriteLine(“p7 == p5”);
if (p7 == p6)
Console.WriteLine(“p7 == p6”);
}
}
Delegate & Event
Interface
Interface (인터페이스)
http://dis.dankook.ac.kr/lectures/hci09/entry/Interface
IEnumerable & IEnumerator Interface
http://dis.dankook.ac.kr/lectures/hci09/entry/Enumerator
IEquatable Interface
http://dis.dankook.ac.kr/lectures/hci09/entry/Equals
Class & Inheritance
Indexer
http://dis.dankook.ac.kr/lectures/hci09/entry/Indexer
Property (속성)
http://dis.dankook.ac.kr/lectures/hci09/entry/Property
Method overloading (메소드 오버로딩) Method overriding (메소드 오버라이딩)
http://dis.dankook.ac.kr/lectures/hci09/entry/Method-Overloading
Abstract Class (추상 클래스)
http://dis.dankook.ac.kr/lectures/hci09/entry/Abstract-class
Sealed Class (봉인 클래스)
http://dis.dankook.ac.kr/lectures/hci09/entry/Sealed-Class