29
C# 10 장 . 장장장

10 장 . 참조형

  • Upload
    vui

  • View
    68

  • Download
    0

Embed Size (px)

DESCRIPTION

C#. 10 장 . 참조형. 학습 목표. 참조형의 주요한 특징을 이해하고 응용해서 사용한다 서로 다른 형식 사이의 형 변환의 가능성을 결정할 수 있다 참조형 사이의 데이터 형 변환을 이해할 수 있다 값형과 참조형 사이의 박싱과 언박싱 변환을 이해하고 변환할 수 있다 . . 목차. 참조형 변수 데이터 형 변환. 1. 참조형 변수. 참조형 변수 - 변수는 스택 영역에 저장 - 실제 데이터는 메모리의 힙 영역에 저장 클래스도 일종의 참조형으로 분류된다 . - PowerPoint PPT Presentation

Citation preview

Page 1: 10 장 .  참조형

C#10 장 . 참조형

Page 2: 10 장 .  참조형

c#

10 장 . 참조형

2 / 24

• 참조형의 주요한 특징을 이해하고 응용해서 사용한다

• 서로 다른 형식 사이의 형 변환의 가능성을 결정할 수 있다

• 참조형 사이의 데이터 형 변환을 이해할 수 있다

• 값형과 참조형 사이의 박싱과 언박싱 변환을 이해하고 변환할 수 있다 .

학습 목표

Page 3: 10 장 .  참조형

c#

10 장 . 참조형

3 / 24

목차1. 참조형 변수2. 데이터 형 변환

Page 4: 10 장 .  참조형

c#

10 장 . 참조형

4 / 24

1. 참조형 변수

참조형 변수

- 변수는 스택 영역에 저장

- 실제 데이터는 메모리의 힙 영역에 저장

클래스도 일종의 참조형으로 분류된다 .클래스를 인스턴스화 해서 변수에 할당

== 참조형 변수 선언과 같다 .

Page 5: 10 장 .  참조형

c#

10 장 . 참조형

5 / 24

1. 참조형 변수

참조형 변수의 선언과 해제변수는 스택영역에 저장되고 , 실제 데이터는 힙영역에 저장된다 . 스택에 저장되는 값은 실제 데이터가 저장된 힙영역의 주소값이다 . 메모리의 해제 방법은 참조형 변수에 null 을 할당하면 된다 .

< 참조형 선언및 멤버 접근 예제 >class Coordinate{

public int x = 0 ;}…Coordinate c = new Coordinate() ;

c.x = 1;

< 참조형 메모리해제 예제 >Coordinate c = new Coordinate() ;

c = null ;

참조형 변수선언 및 메모리할당참조형 변수 c 를 선언하고 실제 데이터가

저장될 힙 영역의 메모리 확보는 new 키워드를 통해서 이루어 지며 , 생성자(Coordinate()) 를 통해서 초기화된다 .

참조형의 메모리 해제null 을 참조형 변수에 할당하면 확보되어

있던 메모리가 해제된다 .

Page 6: 10 장 .  참조형

c#

10 장 . 참조형

6 / 24

1. 참조형 변수

참조형 변수 예제

1. using System;

2. class Coordinate3. {4. public int x;5. public int y;6. }

7. class ConsoleApplication8. {9. static void Main(string[] args)10. {11. Coordinate c = new Coordinate();12. // 참조형 변수 선언 및 메모리 할당

13. c.x = 1;14. c.y = 2;15. // 참조형 변수의 멤버 접근16. Console.WriteLine("c = {0}, {1}", c.x, c.y);17. }18.}

(11 행 ) 객체 생성 측면에서 Cordinate 클래스로 변수 c 를 선언 후 new 키워드를 사용해서 객체 선언

클래스를 데이터형 측면으로 보면 , Cordinate 형 변수 c 를 선언하고 힙 영역의 메모리를 할당

즉 , 객체 생성은 데이터형의 선언 , 메모리 확보와 같다 .

Page 7: 10 장 .  참조형

c#

10 장 . 참조형

7 / 24

1. 참조형 변수

값형과 참조형의 비교값형의 경우 == 와 != 의 연산자로 값을 비교한다 .참조형의 값은 == 와 != 로 비교할 수 없다 .== 혹은 != 연산자는 단지 참조형 변수의 힙영역 주소값 만을 비교하게 된다 .

< 예제 >class Coordinate{

public int x ;}…Coordinate c1 = new Coordinate();Coordinate c2 = new Coordinate();

c1.x = 1 ;c2.x = 1 ;

if(c1= = c2) Console.WriteLine(“c1==c2”);

elseConsole.WriteLine(“c1!=c2”);

두 객체의 멤버에 같은 값을 할당한다 .

두 객체의 저장된 값은 같으나 참조형 데이터 값은

== 연산자로 비교할 수 없다 . 굳이 비교를 하게 되면 서로 다른 값으로 인식한다 .

Page 8: 10 장 .  참조형

c#

10 장 . 참조형

8 / 24

1. 참조형 변수

값형과 참조형 변수 ( 주소 ) 비교 예제1. using System;

2. class Coordinate3. {4. public int x;5. public int y;6. }

7. class ConsoleApplication8. {9. static void Main(string[] args)10. {11. Coordinate c1 = new Coordinate();12. Coordinate c2 = new Coordinate();

13. c1.x = 1;14. c1.y = 2;15. c2.x = 1;16. c2.y = 2;

17. Console.WriteLine("c1 = {0}, {1}", c1.x, c1.y);18. Console.WriteLine("c2 = {0}, {1}", c2.x, c2.y);

19. if (c1 == c2) // 참조형 변수 비교20. Console.WriteLine("c1 == c2");21. else22. Console.WriteLine("c1 != c2");23. }24.}

Page 9: 10 장 .  참조형

c#

10 장 . 참조형

9 / 24

1. 참조형 변수

값형과 참조형 값 ( 실제 값 ) 비교 예제using System;

class Coordinate{ public int x; public int y;}

class ConsoleApplication{ static void Main(string[] args) { Coordinate c1 = new Coordinate(); Coordinate c2 = new Coordinate();

c1.x = 1; c1.y = 2; c2.x = 1; c2.y = 2;

Console.WriteLine("c1.x c1.y = {0}, {1}", c1.x, c1.y); Console.WriteLine("c2.x c2.y = {0}, {1}", c2.x, c2.y);

if (c1.x == c2.x) // 참조형 값 비교 Console.WriteLine("c1.x == c2.x"); else Console.WriteLine("c1.x != c2.x"); }}

Page 10: 10 장 .  참조형

c#

10 장 . 참조형

10 / 24

1. 참조형 변수

같은 객체에 대한 다중 참조 ( 참조형 변수 복사 : 주소 복사 )1. using System;

2. class Coordinate3. {4. public int x;5. public int y;6. }

7. class ConsoleApplication8. {9. static void Main(string[] args)10. {11. Coordinate c1 = new Coordinate();12. Coordinate c2; //Coordinate 형 변수 c2 선언

13. c1.x = 1;14. c1.y = 2;

15. c2 = c1; // 복사

16. Console.WriteLine("c1.x, c1.y = {0}, {1}", c1.x, c1.y);17. Console.WriteLine("c2.x, c2.y = {0}, {1}", c2.x, c2.y);

18. if (c1 == c2) // 참조형 변수 비교 ( 주소 비교 )19. Console.WriteLine("c1 == c2");20. else21. Console.WriteLine("c1 != c2");22. }23.}

스택영역 힙영역

c1c2

1 2x y

(15 행 ) c1 이 가리키는 주소를 c2 에 복사함

Page 11: 10 장 .  참조형

c#

10 장 . 참조형

11 / 24

1. 참조형 변수

같은 객체에 대한 다중 참조 ( 참조형 데이터 변경 )1. using System;

2. class Coordinate3. {4. public int x;5. public int y;6. }

7. class ConsoleApplication8. {9. static void Main(string[] args)10. {11. Coordinate c1 = new Coordinate();12. Coordinate c2;

13. c1.x = 1;14. c1.y = 2;

15. c2 = c1;16. Console.WriteLine("c1.x, c1.y = {0}, {1}", c1.x, c1.y);17. Console.WriteLine("c2.x, c2.y = {0}, {1}", c2.x, c2.y);

18. c2.x = 10; // 멤버의 값 변경 19. c2.y = 20;

20. Console.WriteLine("c1.x, c1.y = {0}, {1}", c1.x, c1.y);21. Console.WriteLine("c2.x, c2.y = {0}, {1}", c2.x, c2.y);

22. }23.}

C1 과 C2 는 같은 곳을 참조 하므로x,y 의 값을 변경 후 결과 값은 같다 .

Page 12: 10 장 .  참조형

c#

10 장 . 참조형

12 / 24

2. 데이터 형 변환

기반클래스와 파생 클래스형 간의 형 변환

파생클래스 -> 기반클래스로의 변환은 암시적 가능

기반클래스 -> 파생클래스로의 변환은 명시적으로 변환해야 가능

데이터 호환이 되지 않을 때는 InvalidCastException 발생

< 예제 >class Vehicle{}class Car : Vehicle{}…

Vehicle veh = new Vehicle();Car car = new Car();

Vehicle a = car ;

Car b = (Car) a ;

파생 클래스형을 기반 클래스형으로 형 변환

암시적으로 형 변환됨

기반 클래스형을 파생 클래스형으로 형 변환

명시적으로 형 변환해야 함

Page 13: 10 장 .  참조형

c#

10 장 . 참조형

13 / 24

2. 데이터 형 변환

참조형 데이터 형 변환1. using System;2. class Vehicle3. {4. }5. class Car : Vehicle6. {7. }8. class ConsoleApplication9. {10. static void Main(string[] args)11. {12. Vehicle vehicle = new Vehicle();

// 기반 클래스인 Vehicle 형 변수 vehicle 선언 및 객체 생성13. Car car = new Car();

//v 파생 클래스인 Car 형 변수 car 를 선언 및 객체 생성14. Vehicle a = car; // Child to Parent 형 변환

// a : Vehicle 형 변수 , car : Car 형 변수 // 암시적 형변환이 이루어짐 : car 가 대입되기 전에 Vehicle 형으로

15. Car b = (Car)a; // Parent to Child 형 변환16. }17.}

(14 행 ) : 파생에서 기반으로 변환하는 명시적 형 변환(15 행 ) : 기반에서 파생으로 변환하는 암시적 형 변환

Page 14: 10 장 .  참조형

c#

10 장 . 참조형

14 / 24

2. 데이터 형 변환

참조형 데이터 형 변환

1. using System;

2. class Vehicle3. {4. }

5. class Car : Vehicle6. {7. }

8. class ConsoleApplication9. {10. static void Main(string[] args)11. {12. Vehicle vehicle = new Vehicle();13. Car car = new Car();

14. Vehicle a = car; // Child to Parent 형변환15. Car b = a; // Parent to Child 형변환16. //Car b = (Car)a; // Parent to Child 형변환17. }18.}

(15 행 ) 형 변환 없이 복사 ( 대입 ) 시 : 에러 발생

Page 15: 10 장 .  참조형

c#

10 장 . 참조형

15 / 24

2. 데이터 형 변환

참조형 데이터 형 변환1. using System;2. class Vehicle3. { }4. class Car : Vehicle5. { }6. class ConsoleApplication7. {8. static void Main(string[] args)9. {10. Vehicle vehicle = new Vehicle();11. Car car = new Car();

12. Vehicle a = car; // Child to Parent 형변환13. try14. {15. Car b = (Car)a; // Parent to Child 형변환16. Console.WriteLine("Vehicle 이 Car 로 형 변환 ");17. }18. catch (InvalidCastException e)19. {20. Console.WriteLine(e.Message);21. }22. }23.}

(15 행 ) 실행할 때 캐스트 연산자가 데이터 형을 확인한다 . 이때

데이터 호환이 되지 않는다면 예외를 발생 시킨다 . 발생하는

예외는 InvalidCastException 이다 .앞의 예에서 try … catch 문을 추가해서 예외 처리를 했다 .

Page 16: 10 장 .  참조형

c#

10 장 . 참조형

16 / 24

2. 데이터 형 변환

is 연산자

참조형 사이의 형 변환을 하고자 할 때 데이터 형이 다르면 Invalid-CastException 을 이용해서 예외 처리를 했지만 is 연산자를

사용하면 예외 상황을 비켜가게 할 수도 있다 .

is 연산자는 형 변환을 하지 않고 객체의 데이터 형을 테스트 하는데

유용하다 .

Page 17: 10 장 .  참조형

c#

10 장 . 참조형

17 / 24

2. 데이터 형 변환

is 연산자

데이터 형 사이의 호환성을 테스트하는 데 사용

< 예제 >class Vehicle{}class Car : Vehicle{}…

Vehicle veh = new Vehicle();Car car = new Car();

if( car is Vehicle){

…}else

car 참조형 변수가 Vehicle형과 호환 가능한 형태인지 조사

호환가능하면 true, 호환가능하지 않으면 false

return

Page 18: 10 장 .  참조형

c#

10 장 . 참조형

18 / 24

2. 데이터 형 변환

is 연산자의 사용

using System;class Vehicle{}

class Car : Vehicle{}

class ConsoleApplication{ static void Main(string[] args) { Vehicle vehicle = new Vehicle(); Car car = new Car();

// is 연산자 if (car is Vehicle) { vehicle = car; // 형이 같으면 변환 없이 대입 가능 Console.WriteLine("Car is a Vehicle"); } else { Console.WriteLine("Car is not a Vehicle"); } }}

Page 19: 10 장 .  참조형

c#

10 장 . 참조형

19 / 24

2. 데이터 형 변환

as 연산자

as 연산자는 괄호 안에 데이터형을 표현하는 캐스트 연산자와 비슷한

역할을 한다 .

as 연산자는 서로 간의 형식을 비교해서 형 변환이 가능한지를 검사한 후

형 변환이 가능하면 형 변환된 값을 반환한다 .

Page 20: 10 장 .  참조형

c#

10 장 . 참조형

20 / 24

2. 데이터 형 변환

as 연산자

캐스트 연산과 비슷

형변환이 가능한 형인지 호환성 조사 후에 형 변환된 값 반환

참조형 변수 car 를 Vehicle형으로 변환

형 변환 가능한지 호환성 검사 후에 변환된 값을 넘긴다 . 만약 형 변환이 가능치 않으면 null 을

반환하고 예외를 발생시키지 않는다 .

< 예제 >class Vehicle{}class Car : Vehicle{}…

Vehicle veh = new Vehicle();Car car = new Car();

veh = car as Vehicle ;

Page 21: 10 장 .  참조형

c#

10 장 . 참조형

21 / 24

2. 데이터 형 변환

as 연산자

using System; class Vehicle{ }

class Car : Vehicle{}class ConsoleApplication{ static void Main(string[] args) { Vehicle vehicle = new Vehicle(); Car car = new Car();

// 1. as 연산자 사용하여 형 변환 vehicle = car as Vehicle; //Car 형 변수 car 를 as 연산자를 사용해서 Vehicle 형으로 변환

if (vehicle != null) // 2. 형 변환 성공 여부 확인 { Console.WriteLine("Car is a Vehicle"); } else { Console.WriteLine("Car is not a Vehicle"); } }}

1. Vehicle 형 변수 vehicle 선언2. new 연산자 이용하여 변수명이 vehicle

인 객체를 생성3. Vehicle() 생성자를 이용하여 변수명이

vehicle 인 객체를 초기화

Page 22: 10 장 .  참조형

c#

10 장 . 참조형

22 / 24

2. 데이터 형 변환

object 형 변환모든 참조형은 System.Object 형으로부터 파생되어 나왔다 . 따라서 모든 참조형은 System.Object 형으로 형 변환이 가능하다 .

1. using System;2. class Vehicle { }3. class Car : Vehicle{ }4. class ConsoleApplication5. {6. static void Main(string[] args)7. {8. Vehicle v = new Vehicle();9. Car c = new Car();

10. // object11. object o = c;12. Car b = o as Car;

13. if (b != null)14. { Console.WriteLine("Vehicle is a Car"); }15. else16. { Console.WriteLine("Vehicle is not a Car");17. }18. }19.}

(11 행 ) Car 형 변수 c 를 object 형으로 암시적으로 변환함

(12 행 ) object 형으로 변환된 변수 o 를 Car형으로 명시적으로 변환함 .

즉 , object 형은 모든 객체의 최상위 기반 클래스 형이므로 형 변환이 가능하다 .

Page 23: 10 장 .  참조형

c#

10 장 . 참조형

23 / 24

2. 데이터 형 변환

박싱과 언박싱

C# 에서는 값형과 참조형 사이에서도 형 변환이 가능하다 .값형을 참조형으로 형 변환하는 것을 박싱 (Boxing), 반대로

참조형을 값형으로 형 변환하는 것을 언박싱 (Unboxing) 이라고

한다 .

Page 24: 10 장 .  참조형

c#

10 장 . 참조형

24 / 24

2. 데이터 형 변환

박싱과 언박싱

값형 -> 참조형 : 박싱 (boxing)

참조형 -> 값형 : 언박싱 (unboxing)

< 예제 >

int x = 123 ;

object o = x ;

int y = (int) o ;

박싱 (boxing)정수형 ( 값형 ) 변수 x 를 참조형

변수 o 에 할당하게 되면 암시적으로 x 는 참조형으로 형

변환되게 된다 .

언박싱 (unboxing)정수형 변수 y 에 참조형 변수를

할당하려고 하면 명시적으로 캐스팅해서 참조형을 정수형으로

변환하게 된다 .

Page 25: 10 장 .  참조형

c#

10 장 . 참조형

25 / 24

2. 데이터 형 변환

박싱과 언박싱using System;

class ConsoleApplication{ static void Main(string[] args) { int x = 123;

object o = x; // Boxing // 값형인 int 형으로 정의된 x 를 // 참조형인 object 형으로 암시적으로 변환해서 변수 o 에 복사 int y = (int)o; // Unboxing // 참조형인 변수 o 를 값형인 int 형으로 변환해서 복사

Console.WriteLine(x); Console.WriteLine(y); }}

형변환이 발생 했지만 데이터는 변하지 않음

Page 26: 10 장 .  참조형

c#

10 장 . 참조형

26 / 24

요약• 참조형 변수란 곧 객체라고 말할 수 있다 . • 참조형 변수는 메모리의 스택 영역에 저장되지만 실제

저장되는 값은 데이터가 저장된 메모리의 힙 영역의 주소 값이다 .

Page 27: 10 장 .  참조형

c#

10 장 . 참조형

27 / 24

요약• is 연산자를 통해 형 변환의 가능 여부를 알 수 있다 . is

연산자를 통해 true 를 반환하면 형 변환이 가능하고 false 면 형 변환이 가능하지 않다 .

Page 28: 10 장 .  참조형

c#

10 장 . 참조형

28 / 24

요약• 기반 클래스와 파생 클래스 관계에 있는 객체 사이에는

형 변환이 가능하다 .

• 파생 클래스형 변수는 기반 클래스형으로 변환할 때 명시적으로 변환하지 않아도 되면 내부적으로 변환한다 .

• 그렇지만 기반 클래스형 변수를 파생 클래스형으로 변환할 때는 명시적으로 형 변환을 해줘야 한다 .

Page 29: 10 장 .  참조형

c#

10 장 . 참조형

29 / 24

요약• 값형과 참조형 변수 사이에도 형 변환이 가능하다 .

• 값형을 참조형으로 변환하는 것을 박싱이라고 하며 참조형을 값형으로 변환하는 것을 언박싱이라고 한다 .