iterface ImyInterface
{
void Method1();
int Method2(string str);
}
namespace Week4
{
internal class Class1
{
public interface IUsable
{
void Use();
}
public class Item : IUsable
{
public string Name { get; set; }
public void Use()
{
Console.WriteLine("아이템 {0}을 사용했습니다.", Name);
}
}
public class Player
{
public void UseItem(IUsable item)
{
item.Use();
}
}
static void Main(string[] args)
{
Player player = new Player();
Item item = new Item() { Name = "Heath Position" }; //중괄호 넣어서 지정해줄 수 있음.
player.UseItem(item);
}
}
}
인터페이스 사용 이유
ex) 우리가 아이템이라는게 iusable 상속받았기 떄문에 사용할 수 있었는데
소모성 아이템 / 장착 아이템 등등 종류가 많은데 그걸 전부다 하나의 클래스가 아니라
다양한 클래스로 구현하게 될텐데 거기서 인터페이스를 상속하게 되면 use함수를 그냥 사용할 수 있다.
다중 상속 구현 예제
namespace Week4
{
internal class Class2
{
//다중 상속 구현 예제
public interface IItemPickable
{
void PickUp();
}
public interface IDroppalbe
{
void Drop();
}
public class Item : IItemPickable, IDroppalbe
{
public string Name { get; set; }
public void PickUp()
{
Console.WriteLine("아이템 {0}을 주웠습니다.", Name);
}
public void Drop()
{
Console.WriteLine("아이템 {0}을 버렸습니다.", Name);
}
}
public class Player
{
public void InteractWithItem(IItemPickable item)
{
item.PickUp();
}
public void DropItem(IDroppalbe item)
{
item.Drop();
}
}
static void Main(string[] args)
{
Player player = new Player();
Item item = new Item { Name = "Sword" };
//아이템 주울 수 있음
player.InteractWithItem(item);
//아이템 버릴 수 있음
player.DropItem(item);
}
}
}
추상 클래스의 특징과 장단점
내가 생각하는 인터페이스 : 추상클래스
※ enum 선언하고 맨위에꺼에 상수 값 지정해주면 그 밑에서는 +1되서 자동으로 인덱싱됨
예외란? 프로그램 실행 중 발생하는 예기치 않은 상황
예외처리의 필요성과 장점
예외처리 구현
try-catch
try
{
//예외가 발생할 수 있는 코드
}
catch (ExceptionType1 ex)
{
//ExceptionType1에 해당하는 예외 처리
}
catch (ExceptionType2 ex)
{
//ExceptionType2에 해당하는 예외 처리
}
finally
{
//예외 발생 여부와 상관없이 항상 실행되는 코드
}
catch는 위에서부터 순서대로 실행, 상속관계에 있는 경우 상위 예외 타입이 먼저 실행됨
예외 객체
ExceptionType 이 매개변수 안에 이 예외처리에 발생한 여러가지 정보들, 오류메세지들이 내포되어있음.
실행 시점
예외가 발생한 경우 : 예외 처리과정을 다 거친후 실행
않은 경우 : 정상 실행
try
{
int result = 10 / 0; // ArithmeticException 발생
Console.WriteLine("결과: " + result);
}
catch (DivideByZeroException ex)
{
Console.WriteLine("0으로 나눌 수 없습니다.");
}
catch (Exception ex)
{
Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}
finally
{
Console.WriteLine("finally 블록이 실행되었습니다.");
}
사용자 정의 예외
사용자 정의 예외 클래스 작성
public class NegativeNumberException : Exception
{
public NegativeNumberException(string message) : base(message)
{
}
}
try
{
int number = -10;
if (number < 0)
{
throw new NegativeNumberException("음수는 처리할 수 없습니다.");
}
}
catch (NegativeNumberException ex)
{
Console.WriteLine(ex.Message);
}
catch (Exception ex)
{
Console.WriteLine("예외가 발생했습니다: " + ex.Message);
}
---------------------------------------------------------------
// 플레이어 이동
try
{
// 플레이어 이동 코드
if (IsPlayerCollidingWithWall())
{
throw new CollisionException("플레이어가 벽에 충돌했습니다!");
}
}
catch (CollisionException ex)
{
// 충돌 예외 처리
Debug.Log(ex.Message);
// 예외에 대한 추가 처리
}
// 리소스 로딩
try
{
// 리소스 로딩 코드
LoadResource("image.png");
}
catch (ResourceNotFoundException ex)
{
// 리소스가 없는 경우 예외 처리
Debug.Log(ex.Message);
// 예외에 대한 추가 처리
}
catch (ResourceLoadException ex)
{
// 리소스 로딩 중 오류가 발생한 경우 예외 처리
Debug.Log(ex.Message);
// 예외에 대한 추가 처리
}
// 게임 상태 전이
try
{
// 상태 전이 코드
if (currentGameState != GameState.Playing)
{
throw new InvalidStateException("게임이 실행 중이 아닙니다!");
}
// 게임 상태 전이 실행
}
catch (InvalidStateException ex)
{
// 상태 예외 처리
Debug.Log(ex.Message);
// 예외에 대한 추가 처리
}
throw = 일부러 에러 발생시킬 때 쓰는거
모든 부분에 작성하진 않지만 우려가 되는 부분에 사용한다.
예외처리는 길게 작성하면 오히려 어려워진다.
구체적인 예외 클래스를 사용하면좋음
박싱과 언박싱
박싱 = 값 -> 참조형 / 값형이 사라지는게 아니라 참조형이 새롭게 만들어지는거 > 독립된 값
언박싱 = (박싱된 객체) ->값형
기본 예제
class Program
{
static void Main()
{
// 값형
int x = 10;
int y = x;
y = 20;
Console.WriteLine("x: " + x); // 출력 결과: 10
Console.WriteLine("y: " + y); // 출력 결과: 20
// 참조형
int[] arr1 = new int[] { 1, 2, 3 };
int[] arr2 = arr1;
arr2[0] = 4;
Console.WriteLine("arr1[0]: " + arr1[0]); // 출력 결과: 4
Console.WriteLine("arr2[0]: " + arr2[0]); // 출력 결과: 4
// 박싱과 언박싱
int num1 = 10;
object obj = num1; // 박싱
int num2 = (int)obj; // 언박싱
Console.WriteLine("num1: " + num1); // 출력 결과: 10
Console.WriteLine("num2: " + num2); // 출력 결과: 10
}
}
리스트 활용 예제
List<object> myList = new List<object>();
// 박싱: 값 형식을 참조 형식으로 변환하여 리스트에 추가
int intValue = 10;
myList.Add(intValue); // int를 object로 박싱하여 추가
float floatValue = 3.14f;
myList.Add(floatValue); // float를 object로 박싱하여 추가
// 언박싱: 참조 형식을 값 형식으로 변환하여 사용
int value1 = (int)myList[0]; // object를 int로 언박싱
float value2 = (float)myList[1]; // object를 float로 언박싱
왜 쓰느냐
메서드에 직접 접근이 좀 불편할때 씀
등록하기
delegate int Calculate(int x, int y);
static int Add(int x, int y)
{
return x + y;
}
class Program
{
static void Main()
{
// 메서드 등록
Calculate calc = Add;
// 델리게이트 사용
int result = calc(3, 5);
Console.WriteLine("결과: " + result);
}
}
----------------------------------------------------------------------------
//하나 이상의 메서드 등록하기
delegate void MyDelegate(string message);
static void Method1(string message)
{
Console.WriteLine("Method1: " + message);
}
static void Method2(string message)
{
Console.WriteLine("Method2: " + message);
}
class Program
{
static void Main()
{
// 델리게이트 인스턴스 생성 및 메서드 등록
MyDelegate myDelegate = Method1;
myDelegate += Method2;
// 델리게이트 호출
myDelegate("Hello!");
Console.ReadKey();
}
}
// 델리게이트 선언 public delegate void EnemyAttackHandler(float damage); // 적 클래스 public class Enemy { // 공격 이벤트 public event EnemyAttackHandler OnAttack; // 적의 공격 메서드 public void Attack(float damage) { // 이벤트 호출 OnAttack?.Invoke(damage); // null 조건부 연산자 // null 참조가 아닌 경우에만 멤버에 접근하거나 메서드를 호출 } } // 플레이어 클래스 public class Player { // 플레이어가 받은 데미지 처리 메서드 public void HandleDamage(float damage) { // 플레이어의 체력 감소 등의 처리 로직 Console.WriteLine("플레이어가 {0}의 데미지를 입었습니다.", damage); } } // 게임 실행 static void Main() { // 적 객체 생성 Enemy enemy = new Enemy(); // 플레이어 객체 생성 Player player = new Player(); // 플레이어의 데미지 처리 메서드를 적의 공격 이벤트에 추가 enemy.OnAttack += player.HandleDamage; // 적의 공격 enemy.Attack(10.0f); }
이 부분 알아두면 많이 쓸거 같으니까 다시 보기
참조만을 가지고 컨트롤해야됨.
구현 - 좀 신기하게 생김
(parameter_list) => expression
Calculate cacl = (x,y) ->
{
return x+y;
};
람다를 사용할때는 델리게이트가 꼭 함께나옴
기능이 확장된다면 메서드로 빼주는게 좋지만
간단한 메서드일 경우 람다로 처리하는것도 깔끔함
델리게이트를 대체하는 미리 정의된 제네릭 형식
Func는 값을 반환하는 메서드를 나타내는 델리게이드
ex) Func<int,string>은 int를 입력받아 string을 반환
Action은 값을 반환하지 않는 메서드 / 매개변수를 받아들이지만 반환타입은 없음
func및action은 제네릭 형식으로 미리 정의되어 있어 매개변수와 반환타입을 간결하게 표현할 수 있음.
예시
// 게임 캐릭터 클래스
class GameCharacter
{
private Action<float> healthChangedCallback;
private float health;
public float Health
{
get { return health; }
set
{
health = value;
healthChangedCallback?.Invoke(health);
}
}
public void SetHealthChangedCallback(Action<float> callback)
{
healthChangedCallback = callback;
}
}
// 게임 캐릭터 생성 및 상태 변경 감지
GameCharacter character = new GameCharacter();
character.SetHealthChangedCallback(health =>
{
if (health <= 0)
{
Console.WriteLine("캐릭터 사망!");
}
});
// 캐릭터의 체력 변경
character.Health = 0;
예시중에 피가 닳 때마다 호출 callback 이란걸 많이 씀
이 부분 쓰는 이유 : HP UI, HP가 떨어졌을때 빨간화면이 나오는것도 걸어놓을수있고 HP 관련된 함수들을 전부 걸어놓으면 자동으로 HP가 변화를 가질때마다 Callback됨
var
키워드는 결과 값의 자료형을 자동으로 추론합니다.from
절에서는 데이터 소스를 지정합니다.where
절은 선택적으로 사용하며, 조건식을 지정하여 데이터를 필터링합니다.orderby
절은 선택적으로 사용하며, 정렬 방식을 지정합니다.select
절은 선택적으로 사용하며, 조회할 데이터를 지정합니다.List<int> numbers = new List<int> { 1, 2, 3, 4, 5 }; // 쿼리 작성 (선언적인 구문) var evenNumbers = from num in numbers where num % 2 == 0 select num; // 쿼리 실행 및 결과 처리 foreach (var num in evenNumbers) { Console.WriteLine(num); }
Nullable
Null?
Nullable?
ex) int?는 int형식에 null을 할당할 수 있는 Nullable를 나타냄
// Nullable 형식 변수 선언
int? nullableInt = null;
double? nullableDouble = 3.14;
bool? nullableBool = true;
// 값 할당 및 접근
nullableInt = 10;
int intValue = nullableInt.Value;
// null 값 검사
if (nullableDouble.HasValue)
{
Console.WriteLine("nullableDouble 값: " + nullableDouble.Value);
}
else
{
Console.WriteLine("nullableDouble은 null입니다.");
}
// null 병합 연산자 사용
// nullableInt ?? 0과 같이 사용되며, nullableInt가 null이면 0을 반환합니다.
int nonNullableInt = nullableInt ?? 0;
Console.WriteLine("nonNullableInt 값: " + nonNullableInt);
HasValue 값이 세팅된적 있는지 없는지로 bool로 반환됨.
학습법 특강
특강 제목 : Not Coder, Be Developer
어떻게하면 '진짜' 개발자가 될 수 있을까?
내가 단기간 바짝 공부해서 성공적으로 취업 할 수 있을까?
할 수 있다. 다만 쉽지 않다.
본인의 노력이 수반되어야 한다.
1) 습관화 : 나의 자산을 만들기 - TIL, WIL, 알고리즘
1 문제를 해결하기 위한 방안으로 어떤 것들을 생각했고, 어떤 것들을 선택 했는지, 또 그 선택이 옳은 선택인지 아닌지 기록해둘수있다.
2 채용자 입장에서 봤을 때도 면접자의 강점으로 작용한다. (문제 해결능력, 꾸준함) > 꾸준하게 작성하자.
2) 배운 내용 복습하며 사고력과 구현력 중점적으로 단련 - 개인과제, 팀과제
3) 기술적 의사결정, 기술적 고민을 동시에 - 프로젝트
본인만의 문제해결 능력이 나와야됨.
나는 어떤 프로젝트를 진행하려고했고, 어떤 부분을 구현하기 위해 이러이러한 고민을 했습니다.
이 선택에 대해 여러 고민과 합리적인 선택임을 어필 할 수 있어야됨 = 기술적 의사결정 + 고민 이라는것 / 프로젝트 기간 중 많이 길러야하는 부분
4) 메타인지, 수료 때까지 도달해야하는 실력 목표 - 개발역량점검표
기본기가 탄탄한 주니어 개발자를 안 데려갈 곳은 없다
왜 기술적인 요구사항이 아닌 자질이나 성향을 보는걸까요?
성장 가능성이 높은 사람 / 다른 사람과 협업하며 좋은 결과를 이끌어낼 수 있는 사람
자신의 성장뿐만 아니라 동료들과 함께 성장할 사람 / 끊임없는 고민으로 좋은 프로적트를 만들어낼 사람
중요한건 협업과 기술적 고민
기술적 고민을 잘하려면
협업을 잘하려면
질문과 공유는 필수 덕목
질문 : 1.문제정의 - 2. 해결방안 (어떤걸 생각 했는지)
공유 : 답변받은 좋은 내용이 있다면 주변에도 공유하기
집중코딩시간에는 몰입해서 코딩만 해주세요.
Chatgpt를 어떤 상황에서 써야 적절하게 썼다고 할 수 있을까요?
1.코드의 뼈대를 만들어봅니다.
2. 뼈대와 뼈대를 이어붙일 경우 구조와 흐름을 생각하여 어떻게 연결시킬지 고민해봅니다.
3. 중심이 되는 코드는 직접 고민하여 코드를 작성합니다.
4. 완성된 코드가 그대로 공유되어도 될지 충분히 검토해보고 고민해봅니다.
사용하더라도 이게 어떻게 동작하는지 이해하고 넘어가아된다.
고민이 있을 때, 혼자 낙담하지 않고 튜터 또는 매니저에게 상담 요청
어떻게 하면 유저 입장에서 더 좋은 서비스를 개발할 수 있을지 계속 고민
중꺾마 - 중요한 건 꺾였는데도 그냥 하는 마음
대답해주신 튜터님 - 김주안 튜터님
질문 1. Swich문으로 Method를 반복 실행되게 만들었는데 문제가 없는가?
대답 - while문처럼 연산 횟수가 확 늘어나는게 아닌 이상 정상적으로 동작되는게 갑자기 터질 일은 드물다. 게임 플레이 시간과 상관 없이 이 연산을 몇번이나 반복했느냐가 중요하다.
여담 - 데이터 저장 한 부분에 Json 썼다고 말씀드리고 어떤건지 여쭤보니까 정확하게 뭔지는 듣지 못했지만 파싱하는거부터 익히고 또 다음 공부할 스텝을 알려주셨다.
그리고 동기화 / 비동기화에 관한 얘기도 해주셔서 그것도 공부해 볼 예정이다.
강의 5주차 마저 완강
다음으로 뭘로 빠질지 모르겠는데
1. 주차별 과제 해보기
2. 고급 문법 + 알고리즘 부분 다시 복습
3. 튜터님이 추천해주신 내용 공부해보기
이건 내일 끌리는걸로 할 예정