C# 클래스나 변수를 선언할때 다음과 같은 접근 제한자가 있다.
- public : 외부클래스(스크립트)에서 접근가능, 인스펙터에 노출됨
- private : 동일클래스에서만 접근가능. 외부접근 불가, 인스펙터에 노출안됨
- protected: private과 동일하게 외부접근 불가능하고 상속받은 파생 클래스에서만 접근가능
- internal : 같은 어셈블리에서만 접근가능. class의 경우 접근제한자를 생략하면 internal이 기본값으로 설정
액세스 한정자는 멤버 또는 형식의 선언된 접근성을 지정하는데 사용되는 키워드
키워드 | 접근성 |
public | 제한 없음 |
protected | 포함 및 파생 |
internal | 동일 어셈블리로 제한 |
protected internal | 동일 어셈블리 또는 다른 어셈블리여도 포함하는 클래스에서 파생된 형식 |
private | 포함 |
private protected | 포함 or 동일 어셈블리 내의 포함하는 클래스의 파생 ( C# 7.2 이상 ) |
* 네임 스페이스에는 액세스 한정자가 허용되지 않음
public class A { }
// 동일 어셈블리에서는 internal만 사용할 경우 public과 접근 제어 수준이 동일함
internal class B { }
// protected, protected internal, private, private protected는 namespace에는 허용되지 않기 때문에 에러
protected class C { }
* 멤버 선언이 발생한 구문에 따라 특정 액세스 한정자만 허용
- 멤버가 다른 형식 내에 중첩되면 해당 엑세스 가능 영역은 엑세스 가능성 수준 및 한 수준 위 형식의 엑세스 가능 영역에 의해 결정됨
public class A{
private class AA {
public int x;
}
}
public class B {
void Test() {
// AA Class가 private 이기 때문에 AA.x가 public 이여도 외부에서 접근할 수 없음
A.AA aa = new A.AA();
}
}
* 기본 멤버 액세스 가능성 및 멤버의 허용된 액세스 가능성
구문 | 기본 멤버 엑세스 | 멤버의 허용된 액세스 |
enum | public | none |
class | private | public / protected / internal / private / protected internal, private protected |
interface | public | public / protected / internal / *private ( 기본 구현 필요 ) / protected internal, private protected |
struct | private | 상속이 안되기 때문에 protected는 제외됨 public / internal / private |
* protected
class A
{
protected int x = 1;
}
class B : A
{
void Start()
{
A a = new A();
B b = new B();
// x에 접근할 수 없기 때문에 에러
a.x = 1;
// x에 접근할 수 있기 때문에 정상
x = 2;
}
}
* internal
// EveryDayDevup-Framework 어셈블리
// 같은 어셈블리에서는 접근이 가능
internal class A {
public static int x = 1;
}
class C{
void Test() {
A.x = 2;
}
}
// Assembly-CSharp
class B {
void Start() {
// 어셈블리가 다르기 때문에 A에 접근할 수 없음
A.x = 3;
}
}
// internal class를 public으로 변경하고 멤버를 internal로 변경
public class A
{
internal static int x = 1;
}
class C
{
void Test()
{
A.x = 2;
}
}
class B :
{
void Start()
{
A a = new A();
// 인스턴스 생성은 가능하지만
// internal로 설정한 x에 접근할 수 없음
a.x = 2;
}
}
* protected internal
// EveryDayDevup-Framework
// 같은 어셈블리에 있는 C는 A.x의 접근할 수 있음
public class A
{
internal int x = 1;
}
public class C
{
void Test()
{
x = 3;
}
}
// Assembly-CSharp
// 다른 어셈블리에 있는 B클래스는 상속을 해도 A.x의 접근할 수 없음
class B : A
{
void Start()
{
x = 2;
}
}
// EveryDayDevup-Framework
// protected internal을 사용하면 다른 어셈블리의 파생 클래스에서 x의 접근이 가능
// protected internal은 멤버에만 사용할 수 있음
public class A
{
protected internal int x = 1;
}
// Assembly-CSharp
class B : A
{
void Start()
{
// protected internal은 상속 시 다른 어셈블리에서 접근이 가능
x = 2;
}
}
* private
class A
{
private int x;
public int GetX() {
return x;
}
}
class B
{
void Test()
{
A a = new A();
// private는 선언된 클래스 또는 구조체의 본문에서만 접근 가능
// a.x의 접근할 수 없기 때문에 에러
a.x;
// A에서 x를 접근할 수 있도록 해줘야함
a.GetX();
}
}
* private protected
// EveryDayDevup-Framework
// 동일 어셈블리의 파생 클래스에서는 접근이 가능
public class A {
private protected int x = 1;
}
public class C : A{
void Test() {
x = 2;
}
}
// Assembly-CSharp
class B : A {
void Test(){
// 다른 어셈블리에서는 상속을 받아도 x에 접근할 수 없음
x = 3;
}
}
'유니티게임강좌 > 주인공 캐릭터 제작' 카테고리의 다른 글
[Player제작] 캐릭터 회전 - Rotate (0) | 2023.02.25 |
---|---|
Assembly (0) | 2023.02.25 |
[Player제작] 캐릭터의 이동 (0) | 2023.02.25 |
[Player제작] InputManager (2) | 2023.02.25 |
[Player제작] 유니티 Class 종류 (0) | 2023.02.25 |