abstract
추상(Abstract) 클래스는 클래스 선언 앞과 추상화할 메소드 앞에 'abstract' 을 붙여 사용
추상 메서드는 구현부가 없는 메서드로, 자식 클래스에서 반드시 구현되어야 된다
자식 클래스에서 구현이 안되면 해당 메소드는 사용불가
virtual
오버라이딩(Overriding)은 클래스 선언 앞과 추상화할 메소드 앞에 'virtual' 을 붙여 사용
추상화와는 다르게 부모클래스에서 한번 정의를 하고, 자식 클래스에서 재정의
자식클래스에서 재정의 하지 않으면 부모클래스의 정의된것을 사용한다.
class Stack<T>
{
public T1 First { get; set; }
public T2 Second { get; set; }
}
클래스나 메서드를 일반화시켜 다양한 자료형에 대응하기 위한 것
아직 저것이 문자형이 될지 정수형이 될지 안정해진것.
왜 저렇게 쓰나 싶긴한데. 아마 변수를 초기화 해줄때 자료형도 지정해주며 쓰기 위함인것 같다.
메서드에서 매개변수를 전달할 때 사용.
out 키워드는 메서드에서 반환 값을 매개변수로 전달하는 경우이고, ref 키워드는 메서드에서 매개변수를 수정하여 원래 값에 영향을 주는 경우 사용한다.
void Divide(int a, int b, out int quotient, out int remainder)
{
quotient = a / b;
remainder = a % b;
}
int quotient, remainder;
Divide(7, 3, out quotient, out remainder);
Console.WriteLine($"{quotient}, {remainder}"); // 출력 결과: 2, 1
void Swap(ref int a, ref int b)
{
int temp = a;
a = b;
b = temp;
}
#
int x = 1, y = 2;
Swap(ref x, ref y);
Console.WriteLine($"{x}, {y}"); // 출력 결과: 2, 1
반환해서 얻은것이 아니고 실제 매개변수에 전달한 것.
out과 ref에 차이점은 아무래도 out은 직접 메소드 내에서 사용하고 ref는 아직 매개변수를 모를때 쓰는것 같아. out은 이미 어떤 매개변수를 쓸지 파라미터에 지정했다면 ref는 함수를 사용할때 매개변수를 지정하는듯. 적어도 out을 쓰면 해당 매개변수에는 값이 들어있겠구나 생각하기.
out, ref는 직접적으로 변수값을 바꾸기 때문에 남용은 금물
최근 out을 쓴 경험
if(int.TryParse(Console.ReadLine(), out a);
위의 경우 TryParse는 bool값을 반환해야 하기때문에 Console.ReadLine()은 매개변수 a에 저장하고 bool값을 줄 수 있다.
이전까지는 out에 대해 감이 잘 안잡혔는데 이해가 되니 해당 코드가 더 잘외워지는듯
캐릭터의 스테이터스를 클래스로 정리했다. 구조체여도 상관없다고 생각했지만, 나중에 던전로직을 구현할때 좀더 클래스 내의 변수를 잘 이용할 수 있는 클래스로 캐릭터 변수를 만들었다.
class Character
{
public string Name { get; set; }
public int LV = 1;
public string Chad = "전사";
public int Attack = 10;
public int Defense = 5;
public int HP = 100;
public int Gold = 1500;
public List<item> haveitem = new List<item>(); //플레이어가 가지고 있는 아이템 목록 인벤토리에서 사용
//나중에 던전 들어갈때 위의 변수를 이용한 함수 만들예정
}
while (true) // 조건 수정
{
Console.Clear(); //이전 내용 지우기
switch (Map)
{
case 0: //시작마을
StartMap();
break;
case 1: //상태보기
State(Player);
break;
case 2: //인벤토리
Console.WriteLine("인벤토리");
break;
case 3: //상점
Store();
break;
default:
break;
}
}
맵은 반복문에서 Console.ReadLine()을 통해 잠깐 멈추는 상황을 유도했다.
인벤토리를 구현하기전 기본적으로 인벤토리에는 아이템이 비어있으니 상점 로직을 구현하기로 했다.
상점 구현 전, 아이템에 대한 구조체 먼저 만든다 아이템의 들어갈 변수는 아래와 같다.
class item //방어구 아이템
{
public string Name;
public int Plusstat;
public string Explanation; //아이템 설명
public int Price;
public bool Have; //가지고 있는지 여부
public bool Setting; //장착여부
}
static List<item> Armors = new List<item> ();
static List<item> Weapons = new List<item>();
아이템은 구조체로 관리했다
내용은 아이템의 이름, 증가 스텟, 설명, 가격, 가지고 있는지 여부, 착용하는지 여부등의 자료가 들어있다.
그리고 이후 방어구 아이템과 공격 아이템을 나눠서 리스트를 만들었다. 방어구와 공격아이템의 증가 스테이터스를 구별하기 위해서 따로 만들었으나, foreach문 과정이 두배로 늘었다. 그냥 정수형 숫자로 방어구인지 무구인지 구별하기로 하고 한꺼번에 리스트<아이템>을 만들걸 그랬다.
if (Console.ReadLine() == "0") //나가기
{
Map = 0;
}
else if (Console.ReadLine() == "1")
{
Purchase = true;
Console.Clear();
Store();
}
else
{
Fail();
Store();
}
문제가 된 코드이다.
'0' 나가기는 잘 작동 되었는데, elseif 문과 else 문은 전혀 실행이 되지 않았다. 오류로그도 뜨지 않았고. 예외처리 문제도 안떳으며,반복 문제도 없었다. 그냥 콘솔이 멈추는 문제가 발생했다.
if (Console.ReadLine() == "0") //나가기
{
Map = 0;
}
else
{
Fail();
Store();
}
이상한점은 위의 로직에서는 if문도 else 문도 잘만 작동이 된다는 점이었다. 그런데 else if문만 들어오면 else문도 같이 안되기 시작한다. elseif 문의 함수가 문제인가 싶어 elseif 문을 전부 지워나도 작동이 안되었다.
결론적으로는 해결하긴 했다.
string userInput = Console.ReadLine();
if (userInput == "0") //나가기
{
Map = 0;
}
else if (userInput == "1")
{
Purchase = true;
Console.Clear();
Store();
}
else
{
Fail();
Store();
}
Console.ReadLine()이 중첩이 되어 발생한 문제였다. if 문에서 Console.ReadLine() 읽고, if 문의 조건이 맞질 않으니 다음 elseif문을 읽었을때 또 Console.ReadLine()가 나온것이 문제였다. 이 경우엔 else까지 전부 실행이 안되게된다. if 문에서 조건식이 충족이 되면 나머지는 else는 안읽지만 조건이 충족 안될때 다음 구문을 읽게 되어 문제가 생긴것이었다.
Console.ReadLine()은 중첩이 안되는거 기억하도록 하자
가장 힘들었던것은 함수는 Main에서가 아니면 사용할 수가 없었기 때문에 메인 에서 함수를 사용하는 기능 모두 호출 하는것이 어려웠다. 함수의 파라미터를 이용하여 함수간의 연계를 잘 이어놓고 한번에 모든 기능이 줄줄이 실행되게끔 설계하긴 했는데 이때 자료형에서 엄청 애먹었다.
특히 클래스를 리스트화 하는게 정말 어려웠다.
리스트 자체는 어렵다고 생각 안했는데, 여러가지와 연관되어 쓰려고 하니 자꾸 문제가 생긴다 '[]'를 써야 할때 안쓰고 쓰면 안될 때 계속 쓰게 되는데, 아직까지 감이 잘 안잡힙다. 아직까지는 오류 로그에서 빼라고 하면 빼고 있다.
그리고 꼭 리스트 객체를 만들면 new List();로 초기화 해줘야 한다. 안되면 지역 변수 오류가 뜨던데 이유는 모르겠다.
어찌됐든 구조체를 이용해서 3,4중 구조를 이루는데 2개의 로직만 서로 연관하여 처리할때는 할만한데, 같은 난이도의 기능이어도 3개, 4개정도로 연관해서 쓰면 리스트 관리가 좀 힘들다.