반응형
- [21회차 수업내용]
- 1. 형변환
1.1 암시적 형변환 (Implicit Type Casting)
→ 자동으로 형 변환이 일어나는 경우 (작은 타입 → 큰 타입)
int i = 10;
float f = i; // int → float
1.2 명시적 형변환 (Explicit Type Casting)
→ 개발자가 직접 형 변환을 지정하는 경우
: 정보 손실이 있을 수 있음
: 형식 = (자료형)값 // 컴파일러가 확실하게 알 수 있도록 하기 위한 형식 , (int) 전체가 하나의 형변환 연산자임
float f = 3.14f;
int num = (int)f; // 강제 형변환, 소수점 버림 → num = 3
1.3 파싱 (Parsing)
- 문자열 데이터를 특정 형식(숫자, 날짜 등)으로 변환하는 과정
- 주로 string → 숫자/날짜/기타 타입 변환할 때 사용
string input = "25";
int number = int.Parse(input); // → 숫자 25로 사용 가능
| 메서드 | 설명 | 실패 시 |
| int.Parse(string) | 문자열 → 정수 변환 | 실패 시 예외 발생 |
| int.TryParse(string, out 변수) | 문자열 → 정수 변환 (안전하게) | 실패 시 false |
| float.Parse(string) | 문자열 → 실수 변환 | 실패 시 예외 발생 |
| bool.Parse(string) | “true”/“false” → bool 변환 | 실패 시 예외 발생 |
* 예외(Exception)란? 프로그램 실행 중에 문제가 생겼다는 신호 → 정상적인 코드 흐름을 강제로 중단
string s = i.ToString();
1.4 Convert.To
| Convert.ToInt32() | → 정수(int)로 변환 | Convert.ToInt32("123") → 123 |
| Convert.ToString() | → 문자열(string)로 변환 | Convert.ToString(123) → "123" |
| Convert.ToDouble() | → 실수(double)로 변환 | Convert.ToDouble("3.14") → 3.14 |
| Convert.ToBoolean() | → 불리언(bool)로 변환 | Convert.ToBoolean("true") → true |
*참고
| Convert.ToInt32() | 널(null) 값 → 0 반환 |
| int.Parse() | 널(null) 값 → ❗ 에러 발생 |
1.4 클래스의 형변환
“상속 관계가 있는 클래스들끼리 서로 타입을 바꾸는 것”
| 업캐스팅 | 자식 → 부모 (자동 형변환) | 부모 변수 = 자식객체; |
| 다운캐스팅 | 부모 → 자식 (수동, 명시적 형변환 필요) | 자식 변수 = (자식형)부모변수; |
1.4.1 업캐스팅 (자식 → 부모)
class Parent { }
class Child : Parent { }
Child c = new Child();
Parent p = c; // 업캐스팅, 자동 형변환
예시)
Orc orc = new Orc(); // 자식 타입 변수에 자식 객체
Monster monster = orc; // 부모 타입 변수에 자식 객체 (업캐스팅)
반응형
1.4.2 다운캐스팅(부모 → 자식)
- 형식1 = (자식타입) 부모변수
Monster monster = new Orc(); // 업캐스팅된 상태
Orc orc = (Orc)monster; //다운캐스팅 (명시적) 실패할 경우 = 예외 발생 = 코드진행중단
- is 연산자 + 캐스팅 (예외 방지)
if (monster is Orc)
{
Orc orc = (Orc)monster; // 안전하게 다운캐스팅
}
- is 연산자
- 객체가 특정 타입인지 확인하는 연산자
- 결과는 bool (true / false) 반환
- 형식3= as 연산자 사용
Monster monster = new Orc();
Orc orc = monster as Orc; // 다운캐스팅 시도 (실패 시 null 반환)
- as 연산자
- 형변환 시도하는 연산자
- 성공하면 해당 타입 객체 반환
- 실패하면 null 반환
- 예외 발생하지 않음
2.1 박싱
- 값 형식(예: int, float) 데이터를 참조 형식(object)으로 변환하는 과정
- C#에서 참조형 타입인 object나 인터페이스 타입 같은 곳에 넣을때 값을 힙(참조형 데이터가 저장되는 공간)에 복사해서 ‘박스’에 넣는 과정
- 힙에 새로운 객체가 만들어지고 변수는 그 객체를 가리키는 것
int num = 123;
object obj = num; // 박싱 발생 (스택->힙)
*object는 모든 클래스의 최상위 부모
C#에서 모든 클래스(참조형)는 자동으로 object에서 상속받음
2.2 언박싱
- 박싱(Boxing) 된 참조형 객체에서 다시 원래의 값 타입으로 데이터를 꺼내는 과정
- 언박싱할 때는 반드시 원래 박싱된 타입과 같아야 함 / 다르면 예외(InvalidCastException) 발생
int j = (int)obj; // 언박싱
요즘은 제네릭(List 등)을 쓰면 박싱/언박싱을 신경 쓸 일이 줄어듦
2.3 참조 타입은 언제 쓰는가
| 객체를 여러 곳에서 공유해야 할 때 | 하나의 객체를 여러 변수가 참조 |
| 상태 변경이 반영되어야 할 때 | 참조로 같은 객체 상태를 공유 |
| 상속/다형성 등 OOP 기능이 필요할 때 | 유연한 구조 설계 가능 |
| 큰 데이터를 효율적으로 다룰 때 | 복사 비용 줄임 |
3. 제네릭(Generic) <T> / 타입 매개변수
- 타입을 일반화해서 여러 타입을 하나의 코드로 다룰 수 있게 해주는 기능
- 형식에 의존하지 않고 다양한 타입을 처리할 수 있도록 클래스나 메서드를 정의
- 클래스, 메서드, 인터페이스에 타입 매개변수(<T>)를 넣어 다양한 타입을 처리 가능
public class Factory<T>
{
public T prefab;
}
Factory<Monster> monsterFactory = new Factory<Monster>();
Factory<Orc> orcFactory = new Factory<Orc>();
4. 상속(Inheritance)
- 기존 클래스(부모, base 클래스)의 기능을 물려받아 새로운 클래스(자식, derived 클래스)를 만드는 것
- 코드 재사용과 기능 확장이 목적
class Orc : Monster // 상속선언
{
public void Smash() { }
}
5. 가상 메서드 / Virtual + Override
- 부모 클래스에서 만든 메서드를 자식 클래스가 ‘새롭게 정의(재정의, override)’할 수 있게 해주는 기능
- 부모 클래스는 공통 동작 정의 + 자식 클래스는 상황에 맞게 다르게 동작하게 하고 싶을 때 사용
- virtual → 부모가 “나 재정의될 수 있어” 라고 표시한 것
- override → 자식이 그걸 “내가 새로 쓸게” 라고 한 것
- 다형성(polymorphism): 같은 타입이라도 동작이 다르게 나오게 만들기 위해
6. 추상 클래스 (abstract class)
- ‘공통적인 틀’만 제공하고 구체적인 내용은 자식 클래스에서 직접 구현하도록 강제하는 클래스
- 스스로 객체 생성 못 함 (new 불가)
- 여러 클래스에 공통 구조를 강제하기 위해 사용
- 예: 게임에 다양한 몬스터가 있다 → 공격 방식은 다 다름 → 하지만 ‘Attack()’ 이라는 이름으로 반드시 공격하게끔 강제
public abstract class Monster
{
public abstract void Attack(); // 구현 없음
}
public class Goblin : Monster
{
public override void Attack() { Debug.Log("Goblin 공격"); }
}
7.1 오버로딩
:같은 이름의 메서드를 매개변수의 개수나 타입을 다르게 해서 여러 개 정의하는 것
- 같은 동작을 하되, 입력(매개변수) 이 다른 경우 각각 처리하기 위해 사용
void CreateAccount(string name) { }
void CreateAccount(string name, int age) { }
7.2 오버라이딩
:부모 클래스의 virtual 메서드를 자식 클래스에서 override 키워드를 사용해 재정의하는 것
- 부모가 물려준 메서드의 동작을 자식 클래스에 맞게 바꾸기 위해 사용
class Monster
{
public virtual void Attack()
{
Console.WriteLine("몬스터가 공격합니다.");
}
}
class Orc : Monster
{
public override void Attack()
{
Console.WriteLine("오크가 강하게 공격합니다!");
}
}
다양한 개념을 배웠다. 실습하며 따라치는 것보다 이런 문법들을 처음 배우는 시간이 더 재미있는 것 같다. 그치만 더 중요한건 활용이니까 많이 익혀야겠다.
반응형