클래스에 대한 기본적인 지식은 배웠으나 파편화 되어있어 gpt와 기초 복습을 다시 진행하였다.
하면서, 함수, 변수 또한 추가적인 지식이 필요해서 함께 진행한다.
완전 애기 수준 기초부터 어느정도 심화까지 쭉 진행한다.
우선 변수에 대해서 알아야할 추가적인 지식이다.
변수는 어디에 선언되느냐에 따라 범위(scope)가 달라진다.
C#에서는 변수의 위치에 따라 나뉘는데
1. 지역변수 : 메서드/ 생성자 안에 선언. 해당 메서드 내부에서만 사용가능.
2. 필드(멤버변수) : 클래스 안, 메서드 밖. 해당 클래스 전체에서 사용가능.
3. 매개변수(parameter) : 메서드/생성자 괄호 안. 해당 메서드 실행될 때만 사용가능.
4. 전역 변수(static 변수) : 클래스 안에서 static 붙임. 프로그램 전체에서 공유 가능.
지역 변수란
특정 블록 { } 안에서만 살아있고 그안에서만 쓸 수 있는 변수.
public void SayHello( )
{
string greeting = "안녕하세요";
Console.WriteLine(greeting);
}
greeting은 SayHello() 함수 안에서만 존재.
밖에서는 이 변수는 존재안한다.
따라서
public void SayHello()
{
string greeting = " 안녕!";
}
public void Speak()
{
Console.WriteLine(greeting);
}
은 greeting은 Sayhello() 함수 안의 지역변수라 오류를 일으킨다!
또다른 특징으론 :
다른 메서드에서 같은 이름의 변수 선언가능
{ } 중괄호 안에서만 살아있음
초기화 필요 ( 선언 후 바로 값을 주는 것이 안전)
메모리 효율면에선 함수 끝나면 사라짐으로 가볍다.
지역변수 vs 필드 vs 매개 변수 비교하기
public class Character
{
// 필드(멤버변수) - 클래스 전체에서 사용가능
private string name ;
// 생성자
public Character(string inputName) // 매개변수
{
string title = "영웅"; // 지역변수 (생성자 안에서만 사용됨)
name = inputName; // 필드(name)에 매개변수(inputName) 값을 저장하겠다.
}
public void Introduce ( )
{
string msg = "반가워요!"; // 지역변수로 함수 Introduce() 내에서만 사용됨
Console.WriteLine(msg + "제 이름은" + name);
}
}
보자면.
name : 필드(멤버변수) , 클래스 전체 사용가능
inputName: 매개변수 , 생성자 안에서 사용
title : 지역변수, 생성자 안에서 사용
msg : 지역변수, Introduce() 안에서 사용
필드란
클래스 내부에 선언된 변수로 객체(인스턴스) 가 기억하고 있어야하는 정보(데이터)를 저장한다.
선언 위치는 클래스 안, 메서드 밖
클래스 내 모든 메서드에서 생존가능
클래스 전체에 접근 가능(접근 제한자에 따라 다름)
객체가 살아있는 동안 메모리는 지속되며
객체의 상태저장을 위해 쓰인다.
매개변수란
함수의 특별한 지역변수+ 외부의 값을 받아오는것으로
함수/ 메서드/ 생성자 호출 시, 외부에서 값을 받아오는 그릇이라고 이해하면 좋다.
함수나 메서드, 생성자에 값을 전달할 수 있게 해주는 변수. 함수가 외부에서 정보를 받기 위한 통로, 그릇이라 생각하자.
소괄호 안에 쓰이면서 바로 선언되는게 특징이다.
호출이 끝나면 사라진다. 함수안에서만 사용가능하며 함수가 끝나면 사라지는것이다.
자동으로 값을 전달한다. 함수안에서는 일반 변수처럼 사용할 수 있다.
예시)
public void SayHello (string name)
{
Console.WriteLine("안녕하세요," + name + "님!");
}
여기서 string name이 매개변수 이다.
이 함수는 name 이라는 값을 받아서 인사문에 쓴다.
사용을 위해선
SayHello("철수");
// 출력시
안녕하세요, 철수님!
여기서 "철수" 는 인자(Argument) 라고 부른다.
함수가 실행될때, 인자가 매개변수에 들어가서 사용되는 구조이다.
여러개의 매개변수도 가능하다
public void Add( int a, int b)
{
int result = a + b;
Console.WriteLine ("결과: " + result );
}
Add(3, 5);
결과: 8
이라고 호출한다.
생성자에서도 매개변수 사용
public class Character
{
private string name;
public Character (string inputName) // 매개변수
{
name = inputName ;
}
}
Character hero = new Character("철수"); // "철수"가 inputName에 들어간다.
접근제한자 private vs public 그리고 protected, internal
이 필드나 메서드에 , 누가 접근할 수 있냐를 정해주는 자물쇠 역할.
public : 공개됨, 클래스내부 접근가능, 클래스 외부 접근가능
private : 비공개, 클래스 내부 접근가능, 클래스 외부 접근 불가.
protected: 상속받은 클래스 내부에서
internal : 같은 프로젝트(어셈블리) 내에서만
객체의 내부 데이터는 외부가 마음대로 건드리지않게 보호하기위해 private을 쓴다.
이를 캡슐화라고한다.
필드는 보통 private으로 만든다.
외부에서 접근할땐 속성(property) 나 메서드로 조절한다.
private int level;
public int level
{
get { return level;} // 읽기 가능
set { if (value >=1 level = value; } // 유혀성 검사하고 쓰기.
}
필드는 외부에서 접근 못하게 막고 필요한 경우에만 정해진 방식으로 값을 읽고 쓰기 하고싶을때 사용하는 속성이다.
값을 안전하게 관리하는 통로를 열어주는게 속성(property) 라고한다.
속성(property)의 기본구조는
[ name (숨김) ]
|
getter/ setter (읽고/ 바꾸는 문)
|
외부코드 (사용자)
여기서
getter= 값만 살짝 보여주는 개념
setter = 값을 전달하는 방식이다.
코드로 표현해보면
public class Character
{
private string name; // 필드, private이므로 숨김
public string Name
{
get { return name;} // getter: 읽을때
set { name = value; } // setter: 바꿀때
}
}
사용자가 쓸때는?
Character hero = new Character(); // 객체(인스턴스) 생성
hero.Name = "철수"; // 이건 setter가 실행됨
name = "철수" 라고 인지.
Console.WriteLine(hero.Name); // 이건 getter가 실행됌.
name 값을 보여주는것이다.
"철수" 라고 내뱉는다.
예를들어 이 방식으로 내 이름을 "똥손"이라고 웃기게 짖는걸 막을 수 있다.
public string Name
{
get { return name; }
set
{
if (value == "똥손")
{
Console.WriteLine("그런 이름은 안 돼요!");
}
else
{
name = value;
}
}
}
setter는 함수처럼 { } 안에 조건, 검사, 로직을 넣을 수 있다.
다시 복습해보자면.
private int level;
public int Level
{
get{ return level;} // 외부에서 읽을때 실행
set{ level = value;} // 외부에서 쓸때 실행
}
쓰려면,
here.Level = 10; // set -> Level = 10;
int 1 = here.Level; // get -> return Level;
Level 이라는 이름으로 읽고 쓰기를 하지만
실제로는 get과 set이라는 메서드처럼 작동한다.
값은 읽고싶지만, 바꾸지는 못하게 하고싶은데?
setter 없이 getter 만 쓰면 된다.
public class Character
{
private string name = " 철수"; // 필드에서 미리 선언
public string Name
{
get { return name;} // 읽을수만있음
// set{ --- } 없음
}
}
사용하려할때
Character hero = new Character( ) ;
Console.WriteLine(hero.Name); //
철수 라고 낸다.
hero.Name = "영희"
// 컴파일 오류가 난다.
정보를 공개만하고 수정은 못하게 하고싶을때 유용하다.
예)
캐릭터 생성일
ID나 고유번호
등..
이런식으로 짧게 생성자에서만 값을 넣고 외부에서 읽기만 하게 할수도있다.
public string Name { get ;}
이것으로 변수의 종류별 특징에 대해 간략하게 배웠다.
....
클래스(class) 란?
설계도
public class Character
{
// 이름, 레벨 같은 정보나
// 말하기, 공격하기 같은 행동을 넣을 수 있음
}
클래스는 다음을 담고있다.
필드 - 데이터 저장 / 이름,레벨등
메서드 - 행동 정의 / 말하기, 공격하기 등
생성자 - 처음 태어날때 해야할일 / 이름 정하기, 레벨 초기화 등
객체(object), 인스턴스(Instance)란?
클래스만 있으면 실제로는 아무것도 존재안한다.
클래스는 설계도니까, 실제로 사용하는 객체를 만들어줘야한다.
Character hero = new Character( ) ;
이건 세가지 일을 동시에한다.
1. new Character ( ) -> Character 클래스의 객체(인스턴스)를 메모리에 생성
2. hero = ... -> 만든 인스턴스를 hero 라는 변수에 담음
3. hero 를 통해 캐릭터를 사용할 수 있게된다.
비유해서 정리하자면
class Character -> 캐릭터 그리는 설계도
new Character() -> 진짜 캐릭터 만드는것
hero -> 그 캐릭터에 붙인 이름표
필드란?
클래스 안에서 데이터(정보)를 저장하는 변수다. 맴버변수라고도 한다.
예를들면 캐릭터가 있따면 이름과 레벨은 꼭필요할테니,
public class Character
{
private string name;
private int level;
}
여기서 private은 이 정보는 이 클래스 안에서만 쓸 수 있다라는 뜻.
앞서 배운데로, 보통 private으로 써서 외부에서 막고, 필요하다면 속성(property)로 컨트롤한다.
추후 더 자세히 공부하자.
메서드(Method)란?
클래스 안에 들어있는 행동이다.
우리가 알고 있는 함수랑 똑같지만, 클래스 안에 있으니 메서드라고 불린다.
public class Character
{
private string name;
private int level;
public void Introduce()
{
Console.WriteLine("안녕하세요! 제 이름은" + name + "입니다."
}
}
하게되면
Introduce()는 캐릭터가 "자기소개"하는 행동이며,
Console.WriteLine()은 화면에 글자를 보여주는 코드이다.
실제 사용예시에는
Character hero = new Character( ); // 캐릭터를 만들어주고
hero.Introduce(); // 캐릭터 자기소개를 실시할 수 있다.
그러나 아직 이렇게만하면 name이 설정되지 않아서 출력에 문제가 있다.
이때 "초기화 값" 인 생성자(Constructor)가 필요하다.
생성자(Constructor)란?
생성자는 객체가 만들어질 때 자동으로 실행되는 특별한 함수.
객체가 태어날때 초기값을 세팅해주는 역할을 한다.
우리가 new Character( ) 같은 코드로 객체를 만들때,
클래스 안에 생성자 함수가 자동으로 실행되서
필드에 초기값을 넣어주는것이다.
비유하자면,
클래스: 사람을 만드는 설계도
인스턴스(객체): 실제로 태어난 사람
생성자 : 사람이 태어날때 이름을 정해주는 과정!
예)
public class Character
{
private string name;
private int level;
// 생성자는 이름이 클래스와 똑같아, 반환형의 데이터 형식이 없음)
public Character( )
{
name = "이름 없음";
level = 1;
}
public void Introduce()
{
Console.WriteLine($"이름: {name}, 레벨: {level}");
}
}
이렇게 클래스에 필드, 생성자, 메서드를 만들어주고
Character hero = new Character( ); // 생성자 실행되도록 만들고
hero.Introduce( ); //클래스에 만든 메서드에 출력하는 실행문이 있으니 아래와 같이 출력한다.
이름: 이름없음, 레벨: 1
생성자란
1. 클래스 이름과 똑같아야함
2. 반환형 없음 : void, int 등 안씀
3. 자동실행: new로 객체 만들면 바로 실행됌.
4. 여러개 만들어도됌. 매개변수 다르게 하면 여러 생성자 가능 (오버로딩)
매개변수가 있는 생성자
예)
public class Character
{
private string name;
private int level;
public Character(string inputName)
{
name = inputName;
level = 1;
}
public void Introduce()
{
Console.WriteLine($"이름: {name}, 레벨: {level}");
}
}
한후에,,
Character hero = new Character ("철수");
hero.Introduce(); // 할시에
"철수" 라는 값을 inputName이라는 매개변수로 받고
name = inputName으로 초기화 되어서
이름: 철수, 레벨: 1
이라고 출력한다.
생성자는 꼭 쓸필요는 없다.
안써도 자동으로 c#이 매개변수가 없는것을 만들어준다.
다만 우리가 직접 값을 넣고싶을때는 직접 생성자를 만들어야한다.
참고로 위에 코드를 실행하려면 정확히는 이렇게 써야하는데,
using System;
public class Character
{
private string name;
private int level;
public Character(string inputName)
{
name = inputName;
level = 1;
}
public void Introduce()
{
Console.WriteLine($"이름: {name}, 레벨: {level}");
}
}
public class Program
{
public static void Main()
{
Character hero = new Character("철수");
hero.Introduce();
}
}
C#은 원래 진입점(Main 함수) 이 있어야 실행되는 언어이며
아무 코드나 파일 맨아래 써두면 실행이 안됌.
Main 함수는 여기서부터 시작! 이라는 뜻으로
실행코드는 반드시 Main 메서드 안에서 실행 해야한다.
static : 정적 메서드 객체를 만들지않아도 바로 실행하게한다.
void : 아무결과도 return 안하는 반환형
Main() : 메서드이름인데, C# 프로그램의 시작점,
Main()은 프로그램 시작점이기때문에 반드시 static 이어야한다.
(컴퓨터)실행기는 누가봐도 딱 1개만 있는 고정된 장소를 원한다.
C#실행기 -> Main() 메서드 찾기 -> 실행
이때 static이 아니라면 실행기는 그걸 어떤 객체를 통해 실행해야 하는지 모른다.
★초보라서 헷갈리는 부분을 좀더 보완했다.
Program 이라는 클래스는 name과 level을 직접 쓸 수는 없다. 해당 변수는 Character 라는 클래스의 private 필드이기때문.
하지만 지금 Program 클래스에서 호출한건 Introduce() 메서드 이다.
Introduce()는 public 으로 선언된 공개된 행동이고,
hero는 Character 클래스에서 만들어진 객체이다.
헌데, Introduce() 메서드 안에서는 name, level을 읽고 출력할 수 있다.
즉,
hero.Introduce()를 함으로서 자기소개하라는 명령으로 private 정보인 (name, level) 에 접근해서 스스로 꺼내서 말한다.
다시 돌고돌아서 속성에 대해서 심화다.
우선 알아둘것이 있다. 데이터에 접근하는것과 출력하는것을 구분해보자.
닷(.) -> 데이터에 접근하는 도구로, 데이터에서 정보를 꺼내주는것이다.
Console.WriteLine() 같은 실행문은 실제로 화면에 보여주는 도구다.
속성(Property) 란?
클래스 안에 있는 필드(정보)를 안전하게 꺼내고 안전하게 바꾸기 위해 만든 스마트한 문
왜 필요한가?
public class Character
{
public string name;
}
할경우에,
온갓 다른 클래스에서도 쓰일 수 있고,
Character c = new Character();
c.name = "똥손";
이렇게 웃기게도 이름을 아무나 막 바꿀 수 있다.
그래서 정보보호를 위해
private string name;
으로 하고, 밖에서 값을 못읽고 못 바꾸게한다.
private string name;
public string Name // 속성의 값은 대문자로 처리
{
get { return name;} // 읽기
set { name = value;} // 쓰기 (value는 전달받은값으로, value는 변수가 아니라 여기선 이렇게 쓰이기로한 약속이다)
}
그다음,
Character c = new Character();
c.Name = "철수"; // 자동으로 set 실행되고 name = "철수" 로 한다.
Console.WriteLine(c.Name); // 자동으로 get 실행되면서
철수
를 출력한다.
get: 값을 읽을때 실행
set: 값을 바꿀때 실행
value : set에서 전달 받은 값이다.
값 검사를 통해 보호도 가능하다.
private int level;
public int level
{
get {return level;}
set
{
if (value <1)
{
Console.WriteLine("레벨은 1 이상이어야 합니다.");
}
else
{
level = value ;
}
}
}
이렇게 하면
c.level = -5; 하면 경고출력된다.
'Unity 개발 공부' 카테고리의 다른 글
| [내일배움캠프 사전캠프] 4일차 C# 기초문법 복습 및, 활용해보기 (25.03.26) (0) | 2025.03.26 |
|---|---|
| [내일배움캠프 사전캠프] 4일차 C# 캐스팅, 제어문, 반복문 프로그래밍 연습. (25.03.26) (1) | 2025.03.26 |
| [내일배움캠프 사전캠프] 3일차 C# 문법기초 제어문,배열, 함수, 클래스와 객체 (25.03.24) (0) | 2025.03.24 |
| [내일배움캠프 사전캠프] 2일차 C# 문법기초 연산자,비트연산 (25.03.21) (0) | 2025.03.20 |
| [내일배움캠프 사전캠프] 1일차 C# 사전문법 기초 공부 - 변수 (0) | 2025.03.20 |