Lab3

Lab3 프로젝트 디렉토리 안에 모든 파일과 보고서 (2~3장)를 넣고 Lab3_학번_이름.zip 압축한 후 e-learning

(http://lms.dankook.ac.kr/index.jsp)으로 제출 ()

Lab3 – Class/OOP

수업블로그에 클래스 OOP 참고하여, 본인이 작성한 Lab2를 객체지향적인 프로그램으로 바꾼다. 그리고 본인이 원하는 Converter 클래스를 하나더 추가 작성한다 (예시: degree <-> radian 변환, kilometer <-> mile 변환, kilogram <-> pound 변환, 등등). ConverterMode 를 사용해줄 것!

http://www.unitconverters.net/
보고서는 출력해서 수업시작 전에 제출한다.

보고서의 내용은 기존 코드 분석과 이해한 내용 그리고 본인이 추가한 코드내용을 적는다..

Person Array

Person[] pArray = new Person[3];

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

 

Person[] pArray2 = new Person[3];
// 아래와 같이 for문 안에 Person p = new Person()와같이
// 새로운 객체를 생성해야 각자 다르게 입력된 정보가 들어가게 됨
for (int i = 0; i < 3; i++) {

Person p2 = new Person();
p2.Name = Console.ReadLine();           // 입력정보
p2.age = int.Parse(Console.ReadLine()); // 입력정보
pArray2[i] = p2; // 이때 p는 새로운 Person객체

}

 

Person2[] pArray3 = new Person2[3];
// 만약 Person2 객체의 name과 age는 static으로 사용할 경우
// static은 공유하는 것이므로, 마지막으로 입력된 데이터로 모든 데이터값이 치환됨
for (int i = 0; i < 3; i++) {

Person2 p3 = new Person2();

Person2.Name = Console.ReadLine(); 
Person2.Age = int.Parse(Console.ReadLine())
pArray3[i] = p3; // // p3 객체의 name과 age는 static이므로 모두 공유하기때문에, 배열의 모든 원소는 마지막에 들어간 정보로 셋팅

}

Parameter Passing: pass by value vs pass by reference vs pass by output

http://dis.dankook.ac.kr/lectures/hci10/entry/pass-by-value와-pass-by-reference와-pass-by-output-비교

 

pass value type by value (값형식을 값에 의한 전달)

static void Square1(int x)
{
x *= x;
Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
int i = 5;
Console.WriteLine(“i={0}”, i);
Square1(i);
Console.WriteLine(“i={0}”, i);
}
//i=5
//The value inside the method: 25
//i=5

 

pass reference type by value (참조형식을 값에 의한 전달)
-copy of reference가 전달

static void ChangeArray1(int[] arr)
{
arr[0]=888; // arr -> myArray이므로 원본 배열의 첫번째 값은 888로 변경
Console.WriteLine(“arr=” + string.Join(“,”, arr)); // .NET4만 동작
//Console.WriteLine(“arr=” + string.Join(“,”, Array.ConvertAll(arr, x => x.ToString()))); // .NET4  Earlier
arr = new int[5] {-3, -1, -2, -3, -4}; // local 변수로 새롭게 할당하여 지정
Console.WriteLine(“arr=” + string.Join(“,”, arr)); // .NET4
}
static void Main()
{
int[] myArray = {1, 4, 5};
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
ChangeArray1(myArray);
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
}
//myArray=1, 4, 5
//arr=888, 4, 5
//arr=-3, -1, -2, -3, -4
//myArray=888, 4, 5

 

 

pass value type by reference (값형식을 참조에 의한 전달)
ref 키워드 사용

static void Square2(ref int x)
{
x *= x;
Console.WriteLine(“The value inside the method: {0}”, x);
}
static void Main()
{
int i = 5;
Console.WriteLine(“i={0}”, i);
Square2(ref i);
Console.WriteLine(“i={0}”, i);
}
//i=5
//The value inside the method: 25
//i=25

 

pass reference type by reference (참조형식을 참조에 의한 전달)
ref 키워드 사용

static void ChangeArray2(ref int[] arr)
{
arr[0]=888; // 원본 배열의 첫번째 값은 888로 변경
Console.WriteLine(“arr=” + string.Join(“,”, arr)); // .NET4만 동작
arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 다시 변경
Console.WriteLine(“arr=” + string.Join(“,”, arr)); // .NET4만 동작
}
static void Main()
{
int[] myArray = {1, 4, 5};
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
ChangeArray2(ref myArray);
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
}
// myArray=1, 4, 5
// arr=888, 4, 5
// arr=-3, -1, -2, -3, -4
// myArray=-3, -1, -2, -3, -4

 

pass value type by output (값형식을 output에 의한 전달)
out 키워드 사용

static void Square3(int x, out int result)
{
result = x*x;
Console.WriteLine(“The value inside the method: {0}”, result);
}
static void Main()
{
int i = 5;
Console.WriteLine(“i={0}”, i);
int result;
Square3(i, out result);
Console.WriteLine(“result={0}”, result);
}
//i=5
//The value inside the method: 25
//result=25

 

pass reference type by output (참조형식을 output에 의한 전달)
out 키워드 사용

static void ChangeArray3(out int[] arr)
{
//arr[0]=888; // use of unassigned out parameter ‘arr’ ERROR
arr = new int[5] {-3, -1, -2, -3, -4}; // 원본 배열이 변경
Console.WriteLine(“arr=” + string.Join(“,”, arr)); // .NET4
}
static void Main()
{
int[] myArray = {1, 4, 5};
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
ChangeArray3(out myArray);
Console.WriteLine(“myArray=” + string.Join(“,”, myArray)); // .NET4
}
//myArray=1, 4, 5
//arr=-3, -1, -2, -3, -4
//myArray=-3, -1, -2, -3, -4

 

static class vs singleton design pattern

공용 데이터를 저장하여 사용하고자 할 때, singleton 패턴이나 static 클래스를 사용한다.

싱글톤 패턴 (Singleton design pattern) -싱글톤 패턴이란 single instance object(해당 클래스의 인스턴스 하나)가 만들어지고, 어디서든지 그 싱글톤에 접근할 수 있도록 하기 위한 패턴

https://msdn.microsoft.com/en-us/library/ee817670.aspx

싱글톤 패턴 in C# https://msdn.microsoft.com/en-us/library/ff650316.aspx

/// Sample singleton object.
public sealed class SiteStructure
{

/// This is an expensive resource we need to only store in one place.
object[] _data = new object[10];

/// private constructor를 사용해서 static readonly로 객체 하나를 생성.
static readonly SiteStructure _instance = new SiteStructure();

/// 그 싱글톤에 접근하기 위한 property를 제공.
public static SiteStructure Instance
{

get { return _instance; }

}

/// private constructor, 즉 외부에서는 이 생성자를 부를 수 없음.
private SiteStructure()
{
// Initialize members, etc. here.
}

}// 싱글톤 객체를 인자로 전달 가능

SiteStructure site = SiteStructure.Instance;
OtherFunction(site); // Use singleton as parameter.

정적 클래스 (Static class)
-static 키워드를 사용한 정적 클래스는 정적 멤버만 포함 가능
-정적 클래스는 new 키워드를 사용하여 정적 클래스의 인스턴스를 생성할 수 없음
-정적 클래스는 봉인 클래스 (sealed class) 임
-static 클래스는 single-instance, global 데이터를 저장하여 사용하는 용도로 적당
-그러나, 싱글톤은 인자(parameter)나 객체(object)로 사용가능하나 정적클래스는 불가능

/// Static class example.
static public class SiteStatic
{

/// The data must be a static member in this example.
static object[] _data = new object[10];
/// C# doesn’t define when this constructor is run, but it will likely be run right before it is used.
static SiteStatic()
{
// Initialize all of our static members.
}

}

http://dis.dankook.ac.kr/lectures/hci10/entry/singleton-pattern과-static-class-비교

static constructor vs instance constructor

C#은 두 가지 종류의 constructor, 즉 class constructor(static constructor), instance constructor(non-static constructor)를 지원한다.

static constructor
-static constructor는 static data member를 초기화하는데 사용
-static constructor는 접근 지정자를 쓸수 없음
-static constructor는 인자를 가질 수 없음
-static constructor는 non-static data member를 접근할 수 없음

// Test.cs
Test
{
//Declaration and initialization of static data member
private static int id = 5;
public static int Id
{
get
{
return id;
}
}

public static void print()
{
Console.WriteLine(“Test.id=” + id);
}
}

class Program
{
static void Main(string[] args)
{
Test.print(); // 정적 메소드를 사용하여 Test.id를 출력
}
}
Test.id=5

// Test1.cs
class Test1
{
private static int id;

// static constructor를 사용하여 Test.id값에 따라서 Test1.id를 지정
static Test()
{
if( Test.Id < 10 ) { id = 20; }
else { id = 100; }
}

public static void print()
{
Console.WriteLine(“Test.id=” + id);
}
}

class Program
{
static void Main(string[] args)
{
Test1.print(); // 정적 메소드를 사용하여 Test.id를 출력
}
}

Test.id=20 // 정적 생성자 내에서 Test.id=5였기때문에 Test.id=20

instance constructor
-instance constructor는 new 키워드를 사용하여 객체 생성에 사용
-instance constructor는 일반적으로 constructor라고 불림
-constructor initializer는 생성자들 코드를 간략하게 만들기 위해 사용

public class MySimpleClass
{
public MySimpleClass (int x)
{
Console.WriteLine (x);
}
}

// 위의 코드는 컴파일러에서 아래의 코드처럼 해석
public class MySimpleClass
{
public MySimpleClass (int x) : base()
{
Console.WriteLine (x);
}
}

public class MyClass {
private ArrayList col;
private string name;
public MyClass() : this(0,””) // 생성자 초기화목록을 사용하여 기본 생성자 지정 { }
public MyClass(int initialCount) : this (initialCount, “”) { }
public MyClass(int initialCount, string name)
{
col = (initialCount > 0) ? new ArrayList(initialCount) : new ArrayList();
this.name = name;
}
}

-default constructor가 지정되어 있지 않다면 컴파일러에서 자동 생성해줌

public class MySimpleClass
{
int someMemberVariable;
}

// 위의 코드를 컴파일러에서 아래와 같이 해석함
public class MySimpleClass
{
int someMemberVariable;public MySimpleClass() : base()
{
}
}

-constructor는 상속되지 않음

public class MyBaseClass
{
public MyBaseClass (int x)
{
}
}

public class MyDerivedClass : MyBaseClass
{
// This constructor itself is okay – it invokes an
// appropriate base class constructor
public MyDerivedClass () : base (5)
{
}

public static void Main()
{
new MyDerivedClass (10); // ERROR: MyDerivedClass는 인자를 받는 생성자가 없음
}
}

Private constructor vs Protected constructor

private constructor는 정적 메소드와 속성 (static method & property)만 있는 경우 사용함.
http://msdn.microsoft.com/en-us/library/vstudio/kcfb85a6.aspx

public class Counter
{
private Counter() { }
public static int currentCount;
public static int IncrementCount() { return ++currentCount; }
}
class TestCounter
{
static void Main()
{
// If you uncomment the following statement, it will generate
// an error because the constructor is inaccessible:
// Counter aCounter = new Counter(); // Error
Counter.currentCount = 100;
Counter.IncrementCount();
Console.WriteLine(“New count: {0}”, Counter.currentCount);
// Keep the console window open in debug mode.
Console.WriteLine(“Press any key to exit.”);
Console.ReadKey();
}

} // Output: New count: 101

protected constructor는 추상클래스 (abstract class)에서 사용을 권고함. 추상 클래스를 상속받는 파생클래스에서 파생 클래스 생성자가 부모 클래스 즉, 추상 클래스를 초기화 하기 위해 추상 클래스 생성자를 호출 할 수 있도록 지원함.
http://msdn.microsoft.com/en-us/library/bcd5672a%28v=vs.80%29.aspx
http://msdn.microsoft.com/ko-kr/library/ms229047(v=vs.100).aspx

public abstract class Shape
{
protected Shape(string name) { this.name = name; }
private string name;
public virtual void Print() { Console.Write(this.name); }
}
public class Triangle: Shape
{
public Triangle(string name): base(name) { this.bottom = 1; this.height = 1 }
private double bottom, height;
public override void Print()
{
base.Print();
Console.WriteLine(” 밑변: {0} 높이: {1}”, this.bottom, this.height);
}
}
public class Rectangle: Shape
{
public Rectangle(string name): base(name) { this.width = 2; this.height = 3 }
private double width, height;
public override void Print()
{
base.Print();
Console.WriteLine(” 가로: {0} 세로: {1}”, this.width, this.height);
}
}
class ShapeTest
{
static void Main()
{
// Shape s = new Shape(“도형”); // Error CS0144, Cannot create an instance of the abstract class
Shape s = new Triangle(“삼각형”);
s.Print(); // 삼각형 밑변: 1 높이: 1
s = new Rectangle(“직사각형”);
s.Print(); // 직사각형 가로: 2 세로: 3
}
}

 

 

Lab2

Lab2 프로젝트 디렉토리 안에 모든 파일과 코드분속 보고서 (2~3장)를 넣고 Lab2_학번_이름.zip 압축한 후 e-learning(http://lms.dankook.ac.kr/index.jsp)으로 제출 (10점)
Lab2 – Basics (method, for, foreach, if, switch, do/while, while, array 활용)
수업블로그에 2.Basic 안에 TemperatureConverter 클래스 참고하여, 본인이 원하는 Converter 클래스를 추가작성한다 (예시: degree <-> radian 변환, kilometer <-> mile 변환, kilogram <-> pound 변환, 등등).
http://www.unitconverters.net/