본문 바로가기

프로그래밍언어/C#

C#의 클래스

3장 c#의 클래스

 

3.1 클래스

3.1.1 클래스란

◆클래스는 새로운 데이터 타입을 만드는 데이터 타입 생성기

◆데이터 타입, 변수, 상수의 관계

데이터 타입: 데이터 타입으로 변수를 생성할 수 있음

변수: 변수의 선언은 메모리의 생성을 의미

상수: 상수는 변수에 할당

◆사용자 정의 데이터 타입

Built-in 데이터 타입을 단순 타입이라 부름

Built-in 타입의 한계: 정해진 형의 데이터만 넣을 수 있음

 

3.1.2 클래스로 데이터 타입 만들기

◆클래스 만들기

Person 클래스

Class person {

    Public int age;

    Public long height;

    Public float weight;

} //class

Class: 클래스를 만드는 키워드

Person: 클래스로 만들어진 새로운 데이터 타입

Int age, long height, float weight: person 클래스 내부의 맴버 필드

◆클래스의 사용

예제 클래스를 이용한 객체 생성

 

public class person

{

public int age;

public long height;

public float weight;

}

public class persontest{

public static void Main()

{

person sister = new person(); // 객체 생성, 변수 생성

sister.age = 100;

sister.height = 170L;

sister.weight = 67.0F;

Console.WriteLine("age : {0}", sister.age);

Console.WriteLine("height : {0}", sister.height);

Console.WriteLine("weight : {0}", sister.weight);

 

}

}

Person 클래스의 메모리 생성: person h = new person();

구조체와 달리 클래스에서의 메모리는 new연산자를 이용해야만 완전한 메모리가 만들어짐

 

3.1.3 클래스의 구성요소

◆클래스의 구성요소1

변수

함수

◆클래스의 구성요소2

멤버 변수 또는 멤버 필드

멤버 함수

◆클래스의 구성요소3

클래스 = 데이터+함수

클래스 = 구조체+함수

 

3.1.4 클래스 내에 함수 삽입

◆변수와 함수의 역할

변수: 정적인 측면(데이터)

함수: 기능적인 측면

예제 클래스 내에 함수를 삽입한 후 테스트

using System;

 

 

public class MethodTest

{

public int a, b; //맴버 필드

public int sum(int x, int y) //맴버 함수

{

return x + y;

}

} //class

public class MethodMain {

public static void Main(){

int s;

MethodTest test = new MethodTest();

test.a =1000;

test.b =2000;

s = test.sum(3, 5);

Console.WriteLine("변수 a는" + test.a);

Console.WriteLine("변수 b는" + test.b);

Console.WriteLine("sum메서드 결과는" + test.sum(3, 5));

Console.WriteLine("또다른 결과는" +s);

 

}

}

 

3.1.5 접근과 비접근

◆접근제어: 객체 생성 후 public은 점 찍고 접근을 할 수 있지만 private은 점으로 접근 불가능

public은 점을 찍고 할당해도 되는 허락 이 허락을 해주는 키워드를 접근 지정자

public의 반대되는 개념은 private
◆private을 사용하는 이유

클래스 내부에서만 사용하기 위해서

외부에서 들어오는 데이터를 직접 할당하기 보다는 간접 할당하기 위해서

◆public 함수를 이용한 private 멤버의 접근

외부로부터 들어오는 데이터를 매개변수의 값 복사를 이용해서 내부의 private멤버 필드로 값 복사

밖으로 내보낼 때는 함수의 리턴을 통해서 외부로 값 복사

Private에 접근하기 위한 방법을 제시하는 예제

public class testprivate

{

private int top_secret;

public void setweight(int my_weight)

{

top_secret = my_weight;

}

public int getweight()

{

return top_secret;

}

}//class

public class testprivatemain

{

public static void Main()

{

int s;

testprivate we = new testprivate();

we.setweight(70); //함수의 매개변수를 이용한 private에 값 세팅

s = we.getweight(); //함수의 리턴을 이용하여 private 데이터 얻기

Console.WriteLine("private멤버의 값은: " + we.getweight());

Console.WriteLine("private멤버의 값은" + s);

 

 

}//main

}//class

 

3.1.6 private의 진정한 의미

◆Private 멤버 함수 있음 해당 클래스 내부에서만 사용. 멤버끼리는 private과 public을 구분 안 함

◆private멤버 필드에 접근하는 방법이 함수 밖에 없음

◆private멤버 필드 사용 이유

자료를 보호하기 위해서 public 함수를 통해서만 접근하게 하는 것

Private의 진정한 의미를 테스트 하는 예제

public class testprivate

{

private int sum;

private int mul;

public void setvalue(int x, int y)

{

sum = x + y;

mul = x * y;

}

public int getvalue()

{

int s = sum + mul;

return s;

}

}

public class testprivatemain2{

public static void Main()

{

testprivate tp = new testprivate();

tp.setvalue(3, 5);

int s = tp.getvalue();

Console.WriteLine("두수의 합과 곱을 다시 더한 값은" + s);

 

}

}

 

3.1.7속성(property)

◆속성

멤버 필드에 값을 할당하고 얻어내는 방법

Set과 get 형식의 함수를 일반화한 형태

스마트 필드 라고도 함

◆속성형식

Private 데이터 타입 변수명;

Public 데이터 타입 속성명{ //속성멤버

    Set{

    //속성 설정 구현

}

    Get{

    //속성 반환 구현

}

}//속성

◆set 접근자의 매개변수 value

Set 내에서 value라는 매개변수를 사용하며 외부에서 들어오는 값을 얻어냄

Value는 set 접근자가 갖는 디폴트 매개변수

속성을 테스트 하는 예제

class Proptest

{

private string name; // 소문자 이름

public string Name{ // 대문자 이름

get {

return name;

}

set {

name = value +"님 반갑습니다.";

}

}

}

public class propmain{

public static void Main()

{

Proptest pt = new Proptest();

pt.Name = "홍길동";

string na = pt.Name;

Console.WriteLine("이름: {0}", na);

 

}//main

}//class

 

3.2 메모리

3.2.1 변수, 객체 그리고 인스턴스

◆값 타입과 참조 타입의 변수

값 타입의 변수와 이름을 선언함과 동시에 메모리가 할당

참조타입(클래스)은 변수의 선언과 변수에 대한 메모리의 할당이 분리

Person sister = new person()

◆메모리 있는 변수와 메모리 없는 변수

객체도 변수의 한 형태이며 클래스에서 만들어졌다 하여 객체 또는 인스턴스 라고 부름

 

3.2.2값 타입과 참조 타입의 메모리 생성의 차이

◆값 타입의 메몰

값 타입의 메모리는 스택 영역에 생성

◆참조 타입의 메모리

참조 값 자체를 저장하기 위한 메모리는 스택 영역에 생성

실제 객체의 메모리는 힙 영역에 생성

 

3.2.3 참조타입(reference type)의 특징

◆참조타입은 값 타입과 달리 변수를 선언하더라도 참조 값을 위한 메모리는 생성되지만 객체의 메모리는 생성 안됨

New 연산자를 이용해서 메모리를 생성해주는 순간에 참조 타입의 변수에 값을 가지게 됨

참조타입을 테스트하는 예제

class refsample

{

public int mycom = 0;

public int youcom = 0;

}

public class refsamplemain{

public static void Main()

{

refsample rs = null; // 변수선언

rs = new refsample(); // 메모리 생성

}

}

◆참조(reference) 할당

Refsample rs1 = new refsample(); // rs1의 값은 10001

Refsample jane = rs1; // jane의 값은 10001이 됨

 

3.2.4 value type 과 reference type 의 비교

◆값 타입과 참조타입의 구분하는 방법

값 타입과 참조타입의 메모리를 가리키는 방식

값 타입과 참조타입의 값 복사

값 타입과 참조타입의 메모리 생성

◆값 타입과 참조타입의 메모리를 가리키는 방식

값 타입: 메모리를 직접 가리킴

참조타입: 메모리를 참조를 통해서 가리킴

◆값 타입과 참조타입의 값 복사

값 타입: 값 타입끼리 할당할 때 메모리의 값들을 그대로 복사

참조타입: 참조타입끼리 할당할 때 참조 값만을 복사

◆값 타입과 참조타입의 메모리 생성

값 타입: 변수의 선언과 동시에 메모리 생성

참조타입: 변수의 선언과 메모리 생성 분리

 

3.2.5 C#에서의 구조체와 클래스의 차이

◆구조체, 데이터 타입, 변수, 상수의 구조

구조체

데이터 타입

변수

상수

◆클래스와 구조체의 유사점

클래스와 구조체는 데이터 타입 생성기

◆클래스와 구조체 차이점

구조체는 값 타입이며 클래스는 참조타입

◆구조체를 사용하는 이유

구조체는 직접적으로 메모리에 접근하기 때문에 참조의 낭비를 막을 수 있음

◆구조체의 특징1

구조체는 상속할 수 없으면 또한 상속해 줄 수 없음

구조체를 테스트 하는 예제

struct person

{

public int age;

public long height;

public float weight;

public person(int a, long h, float w)

{

age = a;

height = h;

weight = w;

}

} // struct

 

public class structtest

{

public static void Main()

{

person sister; // 일반적인 값타입 변수선언

sister.age = 13;

sister.height = 170L;

sister.weight = 55f;

Console.WriteLine("sister : {0}-{1}-{2}", sister.age, sister.height, sister.weight);

person brother = new person(); // 디폴트 생성자

Console.WriteLine("brother : {0}-{1}-{2}", brother.age, brother.height, brother.weight);

person mother = new person(40, 160L, 60F); // 초기값을 할당할 수 있는 값타입의 구조체

Console.WriteLine("mother :{0}-{1}-{2}", mother.age, mother.height, mother.weight);

person twins = sister; //값복사

Console.WriteLine("twins : {0}-{1}-{2}", twins.age, twins.height, twins.weight);

}// main

}//class


◆값 타입의 메모리 생성

값 타입은 묵시적으로 디폴트 생성자를 호출해서 메모리를 생성

Int a; 라는 구문은 int a = new int(); 와 같이 해석 가능

◆구조체의 특징2

디폴트 생성자만큼은 재정의해서 사용할 수 없음

이유: 값 타입의 변수를 선언함과 동시에 메모리의 생성되기 때문

◆구조체(struct)

클래스는 참조타입이지만 구조체는 값 타입

◆구조체와 new

구조체에 초기값을 할당하는 방법을 제공하기 위해서 new 키워드를 사용하지만 값 타입인 것은 변함 없음

 

3.3 call by xxx

3.3.1 값(value0)에 의한 전달

◆값 복사(value copy) : 값 복사란 두 개의 메모리가 존재하고 한쪽의 메모리에 들어있는 값을 다른 쪽의 메모리로 그 값만을 복사하는 행위

값 복사를 이용해서 매개변수를 전달한 후 함수를 호출

◆sum() 함수의 선언

Int sum(int x, int y){

    Int c;

    C = x+y;

    Return c;

}

◆함수의 호출

Int a =3;

Int b =4;

Int c = sumB(a,b);

◆값 복사의 예1

X =a; //함수를 호출할 때 값 복사 발생

Y =b; //함수를 호출할 때 값 복사 발생

C = Sum(a,b); //함수의 리턴값을 c의 메모리에 값 복사

◆값 복사의 예2

Int a =3;

Int b =4;

C = x+y;

값 타입(value type)의 매개변수를 테스트 하는 예제

class testvalue

{

static void callbyval(int x)

{

x = 10000;

}

public static void Main()

{

int x1 = 10;

callbyval(x1);

Console.WriteLine("call-by-value: {0}", x1);

 

}//main

}//class

 

3.3.2. ref에 의한 참조(reference)

◆참조형 매개변수는 메모리의 위치에 대한참조

참조 매개변수를 테스트 하는 예제

class testref

{

static void callbyref(ref int x)

{

x = 10000;

}

 

public static void Main()

{

int x1 = 10;

callbyref(ref x1);

Console.WriteLine("call-by-reference: {0}", x1);

}

}

◆ref 키워드

참조에 의한 전달을 할 때 사용하는 키워드

참조로 값을 넘길 때 참조할 대상은 반드시 초기화

 

3.3.3 out에 의한 참조

◆out 키워드

참조에 의한 전달을 할 때 사용하는 키워드

참조로 값을 넘길 때 참조할 대상을 초기화될 필요는 없음

Out 으로 호출하는 예제

class testout

{

static void callbyref(out int x)

{

x = 10000;

}

 

public static void Main()

{

int x1;

callbyref(out x1);

Console.WriteLine("call-by-out: {0}", x1);

}

}

◆ref와 out 키워드

Ref: 참조할 변수는 반드시 초기화

Out: 참조할 변수가 반드시 초기화될 필요 없음

 

4장 C#프로그램 시작하기

 

4.1 C# hello world 프로그램

4.1.1. hello world console 프로그램

◆hello world 프로그램 작성 및 실행

Hello world 프로그램

namespace org.jabook

{

class helloworld

{

public static void Main()

{

Console.WriteLine("hello world!");

}//main

}//class

}//namespace

 

4.1.2 visual studio 2005에서의 console 프로그램

◆컴파일 명령

F7

◆실행 명령

CTRL+F5

 

4.2 C# hello world 분석

4.2.1 hello world 프로그램의 구성]

◆hello world 프로그램 구성

Using system

Namespace

Main()함수

Static 키워드

Console.writeline()

 

4.2.2 네임스페이스와 어셈블리

◆C# 프로그램의 종류

진입점을 포함하는 형태의 실행 파일(.exe)

진입점을 포함하지 않는 라이브러리 형태의 파일(.dll)

Exe나 dll은 모두 중간언어 형태

◆C#의 어셈블리(assembly)

컴파일한 결과파일(중간언어 형태로 되어 있음)

◆네임스페이스(namespace)

어셈블리 내에서 각각의 클래스들을 구분하는 기준이 네임스페이스

네임스페이스를 사용하는 이유

Top 클래스들을 사용할 경우 어느 것이 Top인지 구분할 수 없는 사태가 발생할 때

네임스페이스를 사용하면 이러한 문제를 해결할 수 있음

 

4.2.3 네임스페이스 사용하기

◆라이브러리 형태의 어셈블리를 사용하기 위한 절차

Person.dll의 물리적인 위치를 명시(컴파일 시 콘솔창에서 작업)

코드 내에서 Person.dll 내부에서 사용하고자 하는 네임스페이스를 using함 (코딩시 코드 내에서 작업)

 

4.2.4 main() 함수

디폴트 컴파일(default compile)

C#에서 아무런 옵션 없이 컴파일을 한다면 컴파일러는 현재의 프로그램을 진입점이 있는 프로그램으로 간주 그렇기 때문에 코드 내에 Main() 함수를 반드시 포함해야 함 그렇지 않으면 에러가 발생

진입점이 없는 라이브러리 형태의 프로그램을 만들고자 한다면 컴파일 옵션에서 /target:library 또는 /t:library를 사용하여 라이브러리 형태라는 것을 명시

◆main() 함수의 특징

프로그램의 시작점

Main() 함수가 끝나면 프로그램은 종료

Main() 함수가 끝나면 반드시 static 으로 선언

Main() 함수에서 객체를 생성하거나 다른 함수를 호출

명령 프롬프트 상의 매개변수를 읽기 위해서 string 배열을 사용

C#의 main() 메서드를 테스트 하는 예제

public class MainTest

{

public void SayHello()

{

Console.WriteLine("Hello World!");

}

public static void Main()

{

MainTest m = new MainTest(); // maintest 객체 생성

m.SayHello(); // 멤버함수 호출

}

}

 

4.2.5 static 키워드

◆static 키워드

모든 클래스에서 공유하기 위한 멤버를 선언하기 위해 사용

스테틱을 멤버 필드를 테스트하는 예제

public class StaticTest

{

private static int sint = 0;

private int nint = 0;

public StaticTest()

{

sint = sint + 1;

nint = nint + 1;

}

public void SayMember()

{

Console.WriteLine("sint:{0}, nint:{1}", sint, nint);

}

 

public static void Main()

{

for (int i = 0; i < 10; i++)

{

StaticTest s = new StaticTest();

s.SayMember();

}

}//main

}//class

 

4.2.6 console.writeline() 함수

◆console 클래스

System 네임스페이스의 클래스

◆writeline() 함수

Console 클래스의 스테틱 멤버 함수

System.Console.WriteLine();

Console 클래스의 스태틱 멤버 함수

화면에 표준출력을 처리하는 함수

출력형식을 테스트하기 위한 예제

public class WriteTest

{

public static void Main()

{

int a = 3;

int b = 2;

Console.WriteLine("a:{0},b:{1},a-b:{2}", a, b, a - b);

Console.WriteLine("a:{0},a:{0},a+b:{1}", a, a + b);

Console.Write("a:" + a + ", b:" + b + "a*b:" + (a * b));

}//main

}//class

 

4.4 const, unsafe

4.4.1 const 상수

const 키워드

상수를 선언하는 키워드

const 상수 선언하기의 예

public const int SALLERY = 7070;

const 상수의 특징1

const는 자동으로 static이 됨

const 상수의 특징2

const로 선언한 변수는 반드시 초기화

const 상수를 테스트 하는 예제

public class ConstSample

{

public const int boy = 8, man = boy + 12;

}

public class ConstTest

{

public static void Main()

{

Console.Write("boy=" + ConstSample.boy);

Console.Write("man=" + ConstSample.man);

}//main

}//class

 

4.4.2 readonly 상수

readonly 상수의 특징1

반드시 초기화할 필요 없음

생성자에서 딱 한번 값을 할당 가능

readonly 상수 특징2

static 키워드를 사용하면 스태틱 상수가 된다. 사용하지 않으면 일반 상수가 됨

static readonly

static readonly일 경우 스태틱 생성자에서 초기화 가능

static readonly일 경우 클래스의 이름으로 접근가능

일반 readonly

일반 readonly일 경우 생성자에서 초기화 가능

일반 readonly일 경우 객체의 이름으로 접근가능

◆readonly 상수의 특징3

Readonly 상수는 생성자를 통해서 런타임 시 값을 초기화 하고자 할 때 사용

생성자에서 값이 결정되면 다시는 그값을 변경할 수 없음

 

4.4.3 가비지 콜텍터와 메모리

◆c++ 에서의 메모리 관리

New 를 사용해서 메모리를 생성했으면 반드시 사용자가 직접 delete를 사용해서 메모리를 제거

◆가비지 콜텍터

C#의 메모리 관리자 역할을 담당

◆가비지 콜텍터가 하는 일

더 이상 사용하지 않는 메모리나 불필요한 메모리를 제거

메모리가 부족하면 메모리의 조각 모음을 함

◆가비지 콜텍터의 관리 대상

힙에 생성되는 객체의 메모리

 

4.4.4 unsafe 코드

◆unsafe code

C#에서 포인터를 사용하면 unsafe code가 됨

CLR이 메모리를 전자동으로 관리해주는데 사용자가 직접 메모리를 건드리는 것은 안전하지 못하기 때문에 unsafe code가 되는 것

포인터를 사용했을 때 unsafe code로 처리하는 예

class unsafetest2

{

unsafe static void callbypoint(int* x)

{

*x = 10000;

}

 

public static void Main()

{

int x1 = 10;

unsafe

{

callbypoint(&x1);

}

Console.WriteLine("call-by-point: {0}", x1);

}

}

 

4.4.5 fixed 키워드를 이용한 메모리 고정

◆fixed 키워드

CLR이 메모리를 이동하지 않는다는 것이 보장

◆fixed 특징

Unsafe code 내에서만 사용 가능

Fixed 키워드를 사용한 메모리의 고정1

class fixedtest1

{

unsafe static void ArrayCopy(byte[] source, byte[] target)

{

fixed (byte* s = source, t = target)

{

for (int i = 0; i < source.Length; i++)

*(t + i) = *(s + i);

}

}

 

public static void Main()

{

byte[] sample = { 5, 6, 4, 6, 3, 4, 100 };

byte[] copyed = new byte[7];

ArrayCopy(sample, copyed);

foreach (byte temp in copyed)

Console.Write(temp + "\t");

}//main

}//class

Fixed 키워드를 사용한 메모리의 고정

class point

{

public int x, y;

}

class fixedtest2

{

unsafe static void doublesum(int* p)

{

int a = *p;

*p = a + a;

}

 

unsafe static void Main()

{

point pt = new point();

pt.x = 5;

pt.y = 6;

//메모리 고정 시작

fixed (int* p = &pt.x)

{

doublesum(p);

}

//메모리 고정끝

Console.WriteLine("{0}{1}", pt.x, pt.y);

}

}

 출처: 소설같은 C#

'프로그래밍언어 > C#' 카테고리의 다른 글

닷넷의 배경 및 특징, 네임스페이스가 뭐죠?  (0) 2010.12.31
C# 테이블  (0) 2010.12.27
C# 컨트롤  (0) 2010.12.27
Chapter 04 변수 – 정보를 담는 방법  (0) 2010.12.06
C++ 배열과 구조체와 포인터  (1) 2010.12.06