프로퍼티(Property)
- 클래스가 가지는 속성, 특성
- 멤버 필드(내부데이터)를 보호하되 외부에서 제어를 해야 하는 경우...
- 내부적으로는 메소드의 형태를 가지고, 외부적으로는 멤버 변수의 형태를 가진다.
- Smart Field or Logical Field
프로퍼티의 정의
- 파라미터가 없는 메소드 형식
- get, set 접근자 사용(일종의 내부메소드)
- 한 클래스내에서 프로퍼티명과 멤버변수의 명이 같으면 X (프로퍼티는 첫글자 대문자)
- get : 데이터를 읽어올때 (외부에서 클래스내의 데이터를...) 내부에 retrun문 필요(getter)
- set : 데이터를 설정할때, 내부에 value 키워드 사용 (setter)
private string text;
public string Text //text는 필드이지만 마치 메소드인것처럼 body를 가진다.
{
get {return text;}
set{text = value;}
}
프로퍼티 형식
- 읽기 및 쓰기 지원 프로퍼티 : get, set 모두 정의한 프로퍼티
- 읽기 전용 프로퍼티 : get만 정의
- 쓰기 전용 프로퍼티 : set만 정의
- 정적 프로퍼티 : 정적메소드처럼 클래스 단위로 접근
- 계산된 프로퍼티 : 연산등 임의의 계산된 값을 다루는 프로퍼티 생성 가능
프로퍼티 & 필드
- void 형식을 제외한 데이터 형식 정의 가능
- 접근 제한자 선언가능
- 정적(static) 프로퍼티 선언 가능
- 필드 사용과 유사
- 프로퍼티는 값에 의한 전달만 가능
- 프로퍼티는 필드와는 달리 실제 메모리상에서 값을 가지고 있지 않기 때문에 주소와 관련된 ref,out같은 메소드 매게변수를 쓸 수 없다.
using System;
namespace CSharpStudy
{
class Pen
{
private string color;
public Pen() : this("검정"){} //기본생성자
public Pen(string color) //기본생성자 오버로딩
{
this.color = color;
}
public void TextWrite(string text) //출력메소드
{
Console.WriteLine("{0} color : {1}", color, text);
}
//메소드를 이용해서 지역변수 필드에 특성등을 변경후 사용할때
public void ChangeColor(string color)
{
this.color = color;
}
public string GetColor()
{
return this.color;
}
//프로퍼티를 이용할때
public string Color //파라미터(인자값)이 생략된 메소드형태
{
//멤버변수와 프로퍼티명은 같으면 안되므로 프로퍼티명은 멤버변수명의 첫글자를 대문자로 바꾸어 사용한다.
get { return this.color;}
set { this.color = value;}
}
}
class MainClass
{
[STAThread]
static void Main(string[] args)
{
Pen bPen = new Pen();
Pen rPen = new Pen("빨강");
Pen yPen = new Pen("노랑");
bPen.TextWrite("테스트");
rPen.TextWrite("테스트");
yPen.TextWrite("테스트");
//메소드 이용
Console.WriteLine("------------ Method 이용---------------");
bPen.ChangeColor("보라");
bPen.TextWrite("테스트");
//프로퍼티를 이용
Console.WriteLine("------------ Property이용---------------");
bPen.Color = "보라"; //프로퍼티명에 값 입력
bPen.TextWrite("테스트");
}
}
}
프로퍼티 & 메소드
- 반환 형식 설정
- virtual, abstract, override 사용가능
- 객체 내의 상태에 대한 접근 분리
- 프로퍼티는 void형식 불가
- 프로퍼티는 value 인자 하나외에는 파라미터 추가 불가
abstract class A
{
int y;
public virtual int X
{
//가상 읽기전용프로퍼티
get { return 0; }
}
public virtual int Y
{
//가상 읽기,쓰기프로퍼티
get { return y; }
set { y = value; }
}
public abstract int Z
{
//추상 읽기,쓰기프로퍼티
get; set;
}
}
class B: A
{
int z;
public override int X { //오버라이드(가상) 프로퍼티
get { return base.X + 1; }
}
public override int Y { //오버라이드(가상) 프로퍼티
set { base.Y = value < 0? 0: value; }
}
public override int Z { //오버라이드(추상) 프로퍼티
get { return z; }
set { z = value; }
}
프로퍼티 가이드 라인
- 객체에서 겉으로 드러나는 속성일 경우...
- 읽기전용 속성, 쓰기 전용 속성 생성자 ->* readonly를 이용한 읽기전용 필드보다는 get을 이용해서 많이 사용
- 값을 받아 들일때 값의 검증이 필요한 경우...
using System;
namespace CSharpStudy
{
class Person
{
private string lastName ="";
private string firstName="";
private int birthYear = 0;
private static int generation = 0;
//읽기, 쓰기 프로퍼티
public string LastName
{
get {return lastName;}
set {this.lastName = value;}
}
//읽기전용 프로퍼티
public string FirstName
{
get {return "김";}
}
//쓰기전용프로퍼티
public int BirthYear
{
set
{
//입력값 검증
if(1950<=value && value <=2050)
this.birthYear = value;
else
birthYear = 0;
}
}
//계산된 프로퍼티
public int Age
{
get{return 2004-birthYear;}
}
//정적프로퍼티 : 정적멤버를 사용하기 위해서... 정적메소드와 동일한 형식
public static int Generation
{
get{return Person.generation;}
set{Person.generation = value;}
}
}
class MainClass
{
[STAThread]
static void Main(string[] args)
{
Person hong = new Person();
hong.LastName = "길동";
//hong.FirstName = "홍"; //읽기전용이기 때문에 에러
hong.BirthYear = 1970;
Console.WriteLine(hong.FirstName + " " + hong.LastName);
Console.WriteLine(hong.Age);
Console.WriteLine("계산전 : "+Person.Generation);
Person.Generation++; //메소드인데 일반변수처럼 사용됨.
Console.WriteLine("계산전 : "+Person.Generation);
}
}
}
인덱서(Indexer)
- 객체가 배열을 사용할때 객체 자체가 배열인 것 처럼 접근 가능
- Smart Array
- System.String
인덱서 선언
- 프로퍼티 선언과 유사
- this 키워드, 배열 첨자 추가
- get, set, value 사용
- 프로퍼티는 static일수도 있지만 인덱서는 반드시 인스턴스 멤버로만 존재 (static은 인덱서 선언에 사용불가)
- 인덱서는 프로퍼티와 마친가지로 실제값을 가지고 있지 않기 때문에 ref, out과 같은 접근자를 사용할수없다.
public string this [int index]
{
get{return array[index];
set {array[index]=value;}
}
- 반드시 첨자가 정수일 필요는 없다
using System;
namespace CSharpStudy
{
class MyString
{
private string [] data; //인덱서를 이용해서 접근할 멤버 변수(배열)
//배열 크기 초기화
public MyString() : this(10) {} //기본생성자
public MyString(int size) //기본생성자 오버로딩
{
this.data = new string[size];
}
//인덱서
public string this[int index] //하나만 사용가능, 시그너처(차원)가 다를경우 오버로딩 가능
{
//다른필드처럼 인스턴스 뒤에 점연산자를 사용하지 않고
//그 클래스 자체가 배열로 사용하기 때문에 this키워드가 인덱서의 이름으로 사용된다.
get
{
//첨자 범위 체크
if (index > -1 && index < data.Length)
return data[index];
else
{
return null; //예외처리부
}
}
set
{
//첨자 범위 체크
if(index >-1 && index<data.Length)
data[index] = value;
else
throw new IndexOutOfRangeException();
//일반적으로 try~catch의 예외처리는 해당메소드를 호출한곳에서 처리하도록 한다.
}
}
public int Length //배열의 크기는 한번정해지면 수정할수 없기 때문에 읽기전용만 가능
{
get {return data.Length;}
}
}
class MainClass
{
[STAThread]
static void Main(string[] args)
{
MyString s = new MyString(5);
//인덱서 호출 -> 객체명[인덱서]를 사용하기만 하면 인덱서가 호출된다.
//인덱서 값 할당
s[0]= "A";
s[1]= "BC";
s[2]= "DEF";
s[3]= "GHIJ";
s[4]= "KLMNO";
//인덱서 값 읽음
for(int i=0; i<s.Length;i++)
Console.WriteLine("s[{0}]={1}", i, s[i]);
}
}
}
인덱서 & 배열
- 인덱서는 모든 데이터 형식을 첨자로 사용가능
- 인덱서는 값에 의한 전달만 가능
- 인덱서는 오버로딩 가능
- 인덱서는 값의 추가 처리 가능
* 첨자를 문자열로 사용한 예제
using System;
namespace CSharpStudy
{
class MyString
{
private string data1 = "ABCDE";
private string data2 = "가나다라마";
private int [] nums = new int[5];
//Indexer
public int this[int index]
{
get
{
return nums[index];
}
set
{
this.nums[index] = value;
}
}
//indexer 오버로딩 가능
public string this[string index]
{
get
{
//첨자 확인
if (index == "ENGLISH")
return data1;
else if (index == "KOREAN")
return data2;
else
return null;
}
set
{
if (index == "ENGLISH")
this.data1 = value;
else if (index == "KOREAN")
this.data2 = value;
else
throw new IndexOutOfRangeException();
}
}
}
class MainClass
{
public static void Main()
{
MyString s = new MyString();
s["ENGLISH"] = "I'm American";
s["KOREAN"] = "나는 한국인입니다";
Console.WriteLine("ByEnglish : {0}", s["ENGLISH"]);
Console.WriteLine("ByKorean : {0}", s["KOREAN"]);
s[0] = 100;
Console.WriteLine(s[0]);
}
}
}
인덱서 & 프로퍼티
- 둘다 get, set사용
- void불가
- 인덱서만 오버로딩 가능(프로퍼티는 인자리스트X)
- 프로퍼티는 정적 구현 가능
SSISO Community