Class의 생성자
class의 생성자는 구조체와는 다르게 매게변수가 없어도 상관 없으며, 변수 값을 초기화 하지 않아도 된다.
class의 생성자는 선언시가 아니라 생성 시(new 키워드 쓸 때)에 실행된다.
생성자 문법
한정자 클래스명(매개변수형 매개변수명) { 한정자 클래스명(생성자매개변수형 생성자매개변수명...) { // class 이름과 동일한 이름의 함수를 작성하면 그게 생성자 // 매개변수 없어도 무관 // 이 곳에 생성자가 실행할 명령어를 넣으면 됨 } }
public class People
{
//필드(멤버변수)들
string Name;
int Age;
float Height;
float Weight;
bool IsMan;
public People()
{
Console.WriteLine("기본 생성자 호출됨");
// 데이터가 전달되지 않는 상황에 실행된다.
// 이렇게 실행될 경우에 대비해서 아래와 같이 멤버 변수에 기본값을 넣어두는 것이 좋다.
Name = "홍길동";
Age = -1; // 비정상적인 값을 기본 생성자 호출 시 넣는 것으로 Age 값으로 차후 정상적인 값인지 체크할 수 있음
Height = 0;
Weight = 0;
IsMan = true;
}
public People(string name, int age, float h, float w, bool isMan)
{
Console.WriteLine("생성자 호출 및 멤버 초기화됨");
Init(name, age, h, w, isMan);
// 데이터를 전달받으며 실행된 일반적인 상황
}
//멤버 변수에 값을 넣어주는 함수
public void Init(string name, int age, float h, float w, bool isMan)
{
Name = name;
Age = age;
Height = h;
Weight = w;
IsMan = isMan;
}
}
프로세싱과 정보설정
게임 로직의 마지막 처리 과정 = 화면에 출력하기 = 그림 그리기, 애니메이션과 비슷하다.
애니메이션과 달리 게임은 미리 그려진 그림을 재생만 하는 것이 아니라 실시간으로 그림을 그려 출력한다
그림을 그리기 위한 과정을 프로세싱이라고 한다.
프로세싱 전에는 프로세싱에 필요한 정보들을 준비하는 정보설정 과정이 필요하다.
게임은
정보설정 > 프로세싱 > 그림그리기 > 화면출력 > 프로세싱 > 그림그리기 > 화면출력 이 반복된다.
소멸자
소멸자는 객체가 해지 될 때 호출된다. 여기서 해지될 때란 할당되어 있던 힙 메모리가 비워질 떄를 의미한다.
소멸자 문법
한정자 클래스명
{
한정자 클래스명() //생성자
{
//명령들
}
~클래스명() //소멸자
{
//명령들
}
}
위와 같이 소멸자는 한정자를 쓰지 않으며 ~클래스명(){ 명령어들.. } 과 같은 식으로 만들 수 있다.
가비지 컬렉터
일반적으로 객체를 수동으로 소멸시키는 일은 거의 없다.
객체가 소멸되는 경우는 거의 둘 뿐인데, 하나는 프로그램이 종료될 때이고,
다른 하나는 가비지 컬렉터에 의해 참조하고 있지 않은 힙 메모리를 비울 때이다.
참조형 데이터는 참조 주소가 스택에, 실제 값이 힙에 저장되는데, 참조 중 스택의 참조 주소값이 사라지면 남은 힙 데이터는 사용할 수 없는 상태가 되어 메모리를 차지하는 쓰레기(가비지)가 된다.
가비지 컬렉터는 이러한 힙 메모리의 데이터를 비워주는 역할을 하는데 이렇게 비워줄 때 소멸자가 실행된다.
[과제1]
아래 조건에 맞는 아이템 클래스를 만들어라
이후 해당 클래스를 이용해 아래와 같은 아이템을 생성하라
4개의 아이템을 저장합니다.
1. 더러운 목검 : 장착형, 무기, HP -5, 공격력 13, 방어력 0
2. 새빨간 물약 : 소모품, 공격력 증가, HP 0, 공격력 2, 방어력 0
3. 출처불명의 방패 : 장착형, 방어구, HP 10, 공격력 0, 방어력 3
4. 달콤한 해골물 : 소모품, HP회복, HP 50, 공격력 0, 방어력 0
이를 통해 아래와 같은 결과화면을 가지는 프로그램을 제작하라
결과 화면
아이템 창을 열었습니다.
1. 더러운 목검
2. 새빨간 물약
3. 출처불명의 방패
4. 달콤한 해골물
5. 종료
4개의 아이템 중 사용할 아이템 번호를 선택하세요 :
(1~5의 값이 아니면 잘못 입력했다는 문구 출력 후 재입력 받음)
(장착형이면)
OOO에 ###을(를) 장착했습니다. HP +##, 공격력 -##, 방어력 +##
(소모품이면)
###을 사용했습니다.
OOO가 XXX 되었습니다.
4개의 아이템 중 사용할 아이템 번호를 선택하세요 :
(1~5의 값이 아니면 잘못 입력했다는 문구 출력 후 재입력 받음)
1. 더러운 목검
2. 새빨간 물약
3. 정체불명의 방패
4. 종료
(종료 할떄까지 반복)
내 답안은 구글드라이브
정적 멤버 변수
정적 멤버 변수는 정적 한정자를 사용한 변수로 객체 생성을 하지 않고 접근하여 사용 할 수 있다.
그래서 맴버 변수의 전역화라고도 한다.
정적 변수는 메모리 상에서 class와 함께 묶이지 않고 class 밖에 위치하게 된다. 또한 프로그램이 종료될때까지 메모리 할당이 유지된다.
정적 키워드 : .static
정적 멤버 변수의 문법
한정자 static 자료형 변수명
사용시 클래스명.변수명;으로 사용한다.
namespace LearnCS_ForLearn
{
class ForLearn
{
public static int _phaseCount;
}
}
네임스페이스
c#에서는 한 프로젝트의 파일을 모두 읽어들이지만 namespace에 의해 다른 공간에 있는 것처럼 정리하여 사용하게 된다.
namespace LearnCS_ForLearn
{
class ForLearn
{
public static int _phaseCount;
}
}
namespace LearnCS_ForLearn
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(ForLearn._phaseCount);
// namespace가 같으면 그냥 사용 가능
}
}
}
namespace ForLearnSpace
{
class ForLearn
{
public static int _phaseCount;
}
}
using ForLearnSpace;
namespace LearnCS_ForLearn
{
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine(ForLearn._phaseCount);
// namespace가 다르면 using 필요 혹은 ForLearnSpace.ForLearn._phaseCount 와 같이 사용
}
}
}
정적 멤버 함수
정적 멤버 함수는 정적 한정자(static)를 사용한 함수로, 객체 생성을 하지 않고 접근해 실행시킬 수 있다.
정적 멤버 함수 사용은 함수의 전역화라고도 한다.
클래스 상속
클래스는 다른 클래스로부터 상속이 가능하다.
이 상속을 통해 코드의 재 활용이 가능해진다.
문법
class 기반 클래스
{
//필드 및 메소드..
}
class 클래스명 : 기반클래스명
{
//필드 및 메소드..
}
클래스에서 상속이란 하위에 있는 클래스가 상위에 있는 클라스의 자원들을 별다른 정의나 선언 없이 사용할 수 있게 만드는 방법이다.
따라서, 상속을 사용하면 프로그램의 유연성을 높일 수 있다.
다만, 상위 클래스에서 추가 또는 변경이 발생할 시 상속 받는 모든 하위 클래스에 미칠 동작 예측이 어렵기 때문에 주의가 필요하다.
this 키워드
class Person
{
string Name;
int Age;
public void InitData(string Name, int age)
{
this.Name = Name;
//class 멤버 변수와 매개변수 및 지역변수의 이름이 겹칠 경우 class 쪽은 this.Name과 같은 식으로 처리할 수 있다.
Age = age;
}
}
[과제2]
아래 Student를 상속하는 클래스를 만들고 그 클래스에 "시간을 넣으면 그 시간 자신의 학창시절 행동이 나오는 메소드(함수)"를 만들어라
namespace LearnCS_ForLearn
{
class Person
{
string Name;
int Age;
public void InitData(string Name, int age)
{
this.Name = Name; //class 멤버 변수와 매개변수 및 지역변수의 이름이 겹칠 경우 class 쪽은 this.Name과 같은 식으로 처리할 수 있다.
Age = age;
}
public void BreakFast()
{
Console.WriteLine("아침밥을 먹습니다.");
}
public void Lunch()
{
Console.WriteLine("점심밥을 먹습니다.");
}
public void Dinner()
{
Console.WriteLine("저녁밥을 먹습니다.");
}
public void Sleep()
{
Console.WriteLine("깊게 잠을 잡니다.");
}
}
}
namespace LearnCS_ForLearn
{
internal class Student : Person
{
string SchoolName;
public void MorningStudy()
{
Console.WriteLine("오전 수업 중입니다.");
}
public void AfternoonStudy()
{
Console.WriteLine("오후 수업 중입니다.");
}
public void HobbyActivities()
{
Console.WriteLine("취미 활동을 하고 있습니다.");
}
public void ReadyForBed()
{
Console.WriteLine("취침 준비를 하고 있습니다.");
}
public void DoHomwork()
{
Console.WriteLine("숙제 중 입니다.");
}
public void Tutoring()
{
Console.WriteLine("과외 중입니다.");
}
public void StudyingAcademy()
{
Console.WriteLine("학원에서 공부중입니다.");
}
public void PlayingAtPCRoom()
{
Console.WriteLine("PC방에서 노는 중 입니다");
}
public void ClubActivity()
{
Console.WriteLine("동아리 활동 중입니다.");
}
public void PrivateStudy()
{
Console.WriteLine("개인 학습 중입니다.");
}
}
}
내 답안
0시 ~ 7시 : 잠
7시 ~ 12: 오전수업
12 ~ 13 : 점심
13~ 16 : 오후수업
16 ~ 17 : 동아리 활동
17 ~ 18 : 저녁
18 ~ 21 : 동아리 활동
21 ~ 23 : 취미활동
23 ~ 0 : 취침준비
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearnCS_ForLearn
{
internal class Program
{
static void Main(string[] args)
{
while (true)
{
ReadInt("시간을 입력하세요. (0 ~ 23, 999 입력 시 종료)", out int hour, 999, 0, 23);
if(hour == 999)
{
break;
}
var me = new Uther();
me.DoingWhat(hour);
}
Commend("pause");
}
public static void ReadInt(string text, out int input, int end = 999, int min = int.MinValue, int max = int.MaxValue)
{
string readLine;
int result;
while (true)
{
Console.Write(text + " : ");
readLine = Console.ReadLine();
if (int.TryParse(readLine, out result))
{
if(result == end)
{
break;
}
if (result >= min && result <= max)
{
break;
}
else
{
Console.WriteLine($"{min}에서 {max}까지의 숫자만 입력할 수 있습니다. 다시 입력해주세요.");
}
}
else
{
Console.WriteLine("숫자가 아닙니다. 다시 입력해주세요.");
}
}
input = result;
}
public static void Commend(string commend)
{
if (commend.CompareTo("pause") == 0)
{
Console.Write("종료하시려면 아무키나 누르세요...");
Console.ReadKey();
}
else
{
Console.WriteLine("존재하지 않는 명령어입니다...");
System.Threading.Thread.Sleep(5000);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LearnCS_ForLearn
{
class Uther : Student
{
public string Name;
public Uther()
{
SchoolName = "양영디지털고등학교";
Name = "이우석";
}
public void DoingWhat(int hour)
{
if(hour >= 0 && hour < 7)
{
Console.Write($"{Name}님은 {hour}시에 ");
Sleep();
return;
}
if(hour >= 7 && hour < 12)
{
Console.Write($"{Name}님은 {hour}시에 ");
MorningStudy();
return;
}
if(hour >= 12 && hour < 13)
{
Console.Write($"{Name}님은 {hour}시에 ");
Lunch();
return;
}
if(hour >= 13 && hour < 16)
{
Console.Write($"{Name}님은 {hour}시에 ");
AfternoonStudy();
return;
}
if(hour >= 16 && hour < 17)
{
Console.Write($"{Name}님은 {hour}시에 ");
ClubActivity();
return;
}
if (hour >= 17 && hour < 18)
{
Console.Write($"{Name}님은 {hour}시에 ");
Dinner();
return;
}
if(hour >= 18 && hour < 21)
{
Console.Write($"{Name}님은 {hour}시에 ");
ClubActivity();
return;
}
if (hour >= 21 && hour <23)
{
Console.Write($"{Name}님은 {hour}시에 ");
HobbyActivities();
return;
}
if(hour >= 23)
{
Console.Write($"{Name}님은 {hour}시에 ");
ReadyForBed();
return;
}
}
}
}