클래스 파생클래스 구조체 네임스페이스 [2/50]
클래스 (Class) C# 프로그램의기본단위 재사용성 (reusability), 이식성 (portability), 유연성 (flexibility) 증가 객체를정의하는템플릿 객체의구조와행위를정의하는방법 자료추상화 (data abstraction) 의방법 객체 (Object) 클래스의인스턴스로변수와같은역할 객체를정의하기위해서는해당하는클래스를정의 [3/50]
클래스의선언형태 public, internal, abstract, static, sealed [class-modifier] class ClassName { // member declarations 필드, 메소드, 프로퍼티, 인덱서, 연산자중복, 이벤트 [4/50]
수정자 (modifier) 부가적인속성을명시하는방법클래스수정자 (class modifier) 8 개 public 다른프로그램에서사용가능 internal 같은프로그램에서만사용가능수정자가생략된경우 static 클래스의모든멤버가정적멤버객체단위로존재하는것이아니라클래스단위로존재 abstract, sealed - 파생클래스 (4.2 젃 ) 에서설명 protected, private 4.1.2 젃참조 new 중첩클래스에서사용되며베이스클래스의멤버를숨김 [5/50]
클래스선언의예 Fraction 클래스형 필드 2 개, 메소드계통의멤버 3 개 class Fraction { int numerator; int denominator; // 분수클래스 // 분자필드 // 분모필드 public Fraction Add(Fraction f) { /*... */ public static Fraction operator+(fraction f1, Fraction f2) { /*... */ public void PrintFraction() { /*... */ // 덧셈메소드 // 덧셈연산자 // 출력메소드 [6/50]
객체선언 클래스형의변수선언예 ) Fraction f1, f2; 객체생성 f1, f2 객체를참조 (reference) 하는변수선언 f1 = new Fraction(); Fraction f1 = new Fraction(); 생성자 객체를생성할때객체의초기화를위해자동으로호출되는루틴클래스와동일한이름을갖는메소드 4.1.5젃참고 [7/50]
객체의멤버참조 객체이름과멤버사에에멤버접근연산자인점연산자 (dot operator) 사용 예 ) 필드참조 : f1.numerator 메소드참조 : f1.add(f2) 연산자중복 : 직접수식사용 - 5.3젃참고 멤버의참조형태 objectname.membername [8/50]
필드 (field) 객체의구조를기술하는자료부분 변수의선언으로구성 필드선언형태 [field-modifier] DataType fieldnames; 필드선언예 int aninterger, anotherinteger; public string usage; static long idnum = 0; public static readonly double earthweight = 5.97e24; [9/50]
접근수정자 (access modifier) 다른클래스에서필드의접근허용정도를나타내는속성 접근수정자동일클래스파생클래스네임스페이스모든클래스 private O X X X protected O O X X internal O X O X protected internal O O O X public O O O O 접근수정자의선언예 private int privatefield; // private int noaccessmodifier; // private protected int protectedfield; // protected internal int internalfield; // internal protected internal int pifield; // protected internal public int publicfield; // public [10/50]
private 정의된클래스내에서만필드접근허용 접근수정자가생략된경우 class PrivateAccess { private int iamprivate; int iamalsoprivate; //... class AnotherClass { void AccessMethod() { PrivateAccess pa = new PrivateAccess(); pa.iamprivate = 10; // 에러 pa.iamalsoprivate = 10; // 에러 [11/50]
public 모든클래스및네임스페이스에서자유롭게접근 class PublicAccess { public int iampublic; //... class AnotherClass { void AccessMethod() { PublicAccess pa = new PublicAccess(); pa.iampublic = 10; // OK [12/50]
internal 같은네임스페이스내에서자유롭게접근 네임스페이스 4.4 젃참고 protected 파생클래스에서만참조가능 - 4.2 젃참고 protected internal 또는 internal protected 파생클래스와동일네임스페이스내에서도자유롭게접근 [13/50]
new 상속계층에서상위클래스에서선언된멤버를하위클래스에서새롭게재정의하기위해사용 static 정적필드 (static field) 클래스단위로존재생성객체가없는경우에도존재하는변수정적필드의참조형태 ClassName.staticField [14/50]
[ 예제 4.2 - StaticVsInstanceApp.cs] using System; public class StaticVsInstanceApp { int instancevariable; static int staticvariable; public static void Main() { StaticVsInstanceApp obj = new StaticVsInstanceApp(); obj.instancevariable = 10; //StaticVsInstanceApp.instanceVariable = 10; StaticVsInstanceApp.staticVariable = 20; // ok // error // ok // error //obj.staticvariable = 20; Console.WriteLine("instance variable={0, static variable={1", obj.instancevariable, StaticVsInstanceApp.staticVariable); 실행결과 : instance variable=10, static variable=20 [15/50]
readonly 읽기젂용필드값이변할수없는속성실행중에값에값이결정 const 값이변할수없는속성컴파일시간에값이결정상수멤버의선언형태 [const-modifiers] const DataType constnames; [16/50]
객체의행위를기술하는방법 객체의상태를검색하고변경하는작업 특정한행동을처리하는프로그램코드를포함하고있는함수의형태 [method-modifiers] returntype MethodName(parameterList) { // method body 메소드선언예 class MethodExample { int SimpleMethod() { //... public void EmptyMethod() { [17/50]
메소드수정자 : 총 11 개접근수정자 : public, protected, internal, private static 정적메소드젂역함수와같은역할정적메소드는해당클래스의정적필드또는정적메소드만참조가능정적메소드호출형태 ClassName.MethodName(); abstract / extern 메소드몸체대싞에세미콜론 (;) 이나옴 abstract 메소드가하위클래스에정의 extern 메소드가외부에정의 new, virtual, override, sealed 4.2 젃참조 [18/50]
매개변수 메소드내에서만참조될수있는지역변수 매개변수의종류 형식매개변수 (formal parameter) 메소드를정의할때사용하는매개변수 실매개변수 (actual parameter) 메소드를호출할때사용하는매개변수 매개변수의자료형 기본형, 참조형 void parameterpass(int i, Fraction f) { //... [19/50]
클래스필드와매개변수를구별하기위해 this 지정어사용 this 지정어 - 자기자싞의객체를가리킴 class Fraction { int numerator, denominator; public Fraction(int numerator, int denominator) { this.numerator = numerator; this.denominator = denominator; [20/50]
값호출 (call by value) 실매개변수의값이형식매개변수로젂달 예제 4.4 참조호출 (call by reference) 주소호출 (call by address) 실매개변수의주소가형식매개변수로젂달 C# 에서제공하는방법 매개변수수정자이용 예제 4.5 객체참조를매개변수로사용 예제 4.6 매개변수수정자 ref 매개변수가젂달될때반드시초기화 out 매개변수가젂달될때초기화하지않아도됨 [21/50]
[ 예제 4.4 - CallByValueApp.cs] using System; class CallByValueApp { static void Swap(int x, int y) { int temp; temp = x; x = y; y = temp; Console.WriteLine(" Swap: x = {0, y = {1", x, y); public static void Main() { int x = 1, y = 2; Console.WriteLine("Before: x = {0, y = {1", x, y); Swap(x, y); Console.WriteLine(" After: x = {0, y = {1", x, y); 실행결과 : Before: x = 1, y = 2 Swap: x = 2, y = 1 After: x = 1, y = 2 [22/50]
[ 예제 4.5 - CallByReferenceApp.cs] using System; class CallByReferenceApp { static void Swap(ref int x, ref int y) { int temp; temp = x; x = y; y = temp; Console.WriteLine(" Swap: x = {0, y = {1", x, y); public static void Main() { int x = 1, y = 2; Console.WriteLine("Before: x = {0, y = {1", x, y); Swap(ref x, ref y); Console.WriteLine(" After: x = {0, y = {1", x, y); 실행결과 : Before: x = 1, y = 2 Swap: x = 2, y = 1 After: x = 2, y = 1 [23/50]
[ 예제 4.6 - CallByObjectReferenceApp.cs] using System; class Integer { public int i; public Integer(int i) { this.i = i; class CallByObjectReferenceApp { static void Swap(Integer x, Integer y) { int temp = x.i; x.i = y.i; y.i = temp; Console.WriteLine(" Swap: x = {0, y = {1",x.i,y.i); public static void Main() { Integer x = new Integer(1); Integer y = new Integer(2); Console.WriteLine("Before: x = {0, y = {1",x.i,y.i); Swap(x, y); Console.WriteLine(" After: x = {0, y = {1",x.i,y.i); 실행결과 : Before: x = 1, y = 2 Swap: x = 2, y = 1 After: x = 2, y = 1 [24/50]
매개변수배열 (parameter array) 실매개변수의개수가상황에따라가변적인경우 메소드를정의할때형식매개변수를결정할수없음 매개변수배열정의예 void ParameterArray1(params int[] args) { /*... */ void ParameterArray2(params object[] obj) { /*... */ 호출예 ParameterArray1(); ParameterArray1(1); ParameterArray1(1, 2, 3); ParameterArray1(new int[] {1, 2, 3, 4); [25/50]
[ 예제 4.7 - ParameterArrayApp.cs] using System; class ParameterArrayApp { static void ParameterArray(params object[] obj) { for (int i = 0; i < obj.length; i++) Console.WriteLine(obj[i]); public static void Main() { ParameterArray(123, "Hello", true, 'A'); 실행결과 : 123 Hello True A [26/50]
범용메소드 (generic method) 형매개변수 (type parameter) 를갖는메소드 범용메소드정의예 void Swap<DataType>(DataType x, DataType y) { DataType temp = x; x = y; y = temp; 범용메소드호출예 Swap<int>(a, b); Swap<double>(c, d); // a, b: 정수형 // c, d: 실수형 [27/50]
[ 예제 4.8 - GenericMethodApp.cs] using System; class GenericMethodApp { static void Swap<DataType>(ref DataType x, ref DataType y) { DataType temp; temp = x; x = y; y = temp; public static void Main() { int a = 1, b = 2; double c = 1.5, d = 2.5; Console.WriteLine("Before: a = {0, b = {1", a, b); Swap<int>(ref a, ref b); // 정수형변수로호출 Console.WriteLine(" After: a = {0, b = {1", a, b); Console.WriteLine("Before: c = {0, d = {1", c, d); Swap<double>(ref c, ref d); // 실수형변수로호출 Console.WriteLine(" After: c = {0, d = {1", c, d); 실행결과 : Before: a = 1, b = 2 After: a = 2, b = 1 Before: c = 1.5, d = 2.5 After: c = 2.5, d = 1.5 [28/50]
C# 응용프로그램의시작점 Main 메소드의기본형태 public static void Main(string[] args) { //... 매개변수 - 명령어라인으로부터스트링젂달명령어라인으로부터스트링젂달방법 c:\> 실행파일명인수1 인수2... 인수n args[0] = 인수1, args[1] = 인수2, args[n-1] = 인수n [29/50]
[ 예제 4.9 - CommandLineArgsApp.cs] using System; class CommandLineArgsApp { public static void Main(string[] args) { for (int i = 0; i < args.length; ++i) Console.WriteLine("Argument[{0] = {1", i, args[i]); 실행방법 : C:\> CommandLineArgsApp 12 Medusa 5.26 실행결과 : Argument[0] = 12 Argument[1] = Medusa Argument[2] = 5.26 [30/50]
시그네처 (signature) 메소드를구분하는정보 메소드이름매개변수의개수매개변수의자료형메소드반환형제외 메소드중복 (method overloading) 메소드의이름은같은데매개변수의개수와형이다른경우호출시컴파일러에의해메소드구별 메소드중복예 void SameNameMethod(int i) { /*... */ // 첫번째형태 void SameNameMethod(int i, int j) { /*... */ // 두번째형태 [31/50]
[ 예제 4.10 - MethodOverloadingApp.cs] using System; class MethodOverloadingApp { void SomeThing() { Console.WriteLine("SomeThing() is called."); void SomeThing(int i) { Console.WriteLine("SomeThing(int) is called."); void SomeThing(int i, int j) { Console.WriteLine("SomeThing(int,int) is called."); void SomeThing(double d) { Console.WriteLine("SomeThing(double) is called."); public static void Main() { MethodOverloadingApp obj = new MethodOverloadingApp(); obj.something(); obj.something(526); obj.something(54, 526); obj.something(5.26); 실행결과 : SomeThing() is called. SomeThing(int) is called. SomeThing(int,int) is called. SomeThing(double) is called. [32/50]
생성자 (constructor) 예 ) 객체가생성될때자동으로호출되는메소드 클래스이름과동일하며반환형을갖지않음 주로객체를초기화하는작업에사용 생성자중복가능 예제 4.11 class Fraction { //... public Fraction(int a, int b) { numerator = a; denominator = b; //... Fraction f = new Fraction(1, 2); // 생성자 [33/50]
정적생성자 (static constructor) 수정자가 static으로선언된생성자매개변수와접근수정자를가질수없음클래스의정적필드를초기화할때사용 Main() 메소드보다먼저실행 정적필드초기화방법 정적필드선언과동시에초기화 정적생성자이용 [34/50]
[ 예제 4.12 - StaticConstructorApp.cs] using System; class StaticConstructor { static int staticwithinitializer = 100; static int staticwithnoinitializer; static Constructor() { // 매개변수와접근수정자를가질수없다. staticwithnoinitializer = staticwithinitializer + 100; public static void PrintStaticVariable() { Console.WriteLine("field 1 = {0, field 2 = {1", staticwithinitializer, staticwithnoinitializer); class StaticConstructorApp { public static void Main() { StaticConstructor.PrintStaticVariable(); 실행결과 : field 1 = 100, field 2 = 200 [35/50]
소멸자 (destructor) 예제 4.13 클래스의객체가소멸될때필요한행위를기술한메소드 소멸자의이름은생성자와동일하나이름앞에 ~(tilde) 를붙임 Finalize() 메소드 컴파일시소멸자를 Finalize() 메소드로변환해서컴파일 Finalize() 메소드재정의할수없음객체가더이상참조되지않을때 GC(Garbage Collection) 에의해호출 Dispose() 메소드 예제 4.14 CLR 에서관리되지않은자원을직접해제할때사용 자원이스코프를벖어나면즉시시스템에의해호출 [36/50]
파생클래스개념 상속 (inheritance) 베이스클래스의모든멤버들이파생클래스로젂달되는기능 클래스의재사용성 (reusability) 증가 상속의종류 단일상속 베이스클래스 1 개 다중상속 베이스클래스 1 개이상 C# 은단일상속만지원 [37/50]
파생클래스의정의형태 [class-modifiers] class DerivedClassName : BaseClassName { // member declarations 파생클래스예 class BaseClass { int a; void MethodA{ //... class DerivedClass : BaseClass { int b; void MethodB{ //... [38/50]
파생클래스의필드클래스의필드선언방법과동일베이스클래스의필드명과다른경우 - 상속됨베이스클래스의필드명과동일한경우 - 숨겨짐 base 지정어 베이스클래스멤버참조 - 예제 4.15 파생클래스의생성자형태와의미는클래스의생성자와동일명시적으로호출하지않으면, 기본생성자가컴파일러에의해자동적으로호출 예제 4.16 base() 베이스클래스의생성자를명시적으로호출 예제 4.17 실행과정필드의초기화부분실행베이스클래스의생성자실행파생클래스의생성자실행 [39/50]
메소드재정의 (method overriding) 베이스클래스에서구현된메소드를파생클래스에서구현된메소드로대체 메소드의시그네처가동일한경우 메소드재정의 메소드의시그네처가다른경우 메소드중복 예제 4.18 [40/50]
가상메소드 (virtual method) 지정어 virtual로선언된인스턴스메소드파생클래스에서재정의해서사용할것임을알려주는역할 new 지정어 객체형에따라호출 override 지정어 객체참조가가리키는객체에따라호출 봉인메소드 (sealed method) 수정자가 sealed로선언된메소드파생클래스에서재정의를허용하지않음봉인클래스 모든메소드는묵시적으로봉인메소드 [41/50]
추상클래스 (abstract class) 추상메소드를갖는클래스 추상메소드 (abstract method) 실질적인구현을갖지않고메소드선언만있는경우 추상클래스선언방법 abstract class AbstractClass { public abstract void MethodA(); void MethodB() { //... [42/50]
구현되지않고, 단지외형만을제공 추상클래스는객체를가질수없음다른외부클래스에서메소드를일관성있게다루기위한방법제공다른클래스에의해상속후사용가능 abstract 수정자는 virtual 수정자의의미포함 추상클래스를파생클래스에서구현 override 수정자를사용하여추상메소드를재정의접근수정자항상일치 [43/50]
메소드를파생클래스에서재정의하여사용 C# 프로그래밍에유용한기능 베이스클래스에있는메소드에작업을추가하여새로운기능을갖는메소드정의 base 지정어사용 예제 4.21 파생클래스에서기능을추가하여재정의한프로그램예제 [44/50]
상향식캐스트 ( 캐스팅 - 업 ) 타당한변환 파생클래스형의객체가베이스클래스형의객체로변환 하향식캐스트 ( 캐스팅 - 다운 ) 타당하지않은변환 캐스트연산자사용 예외발생 [45/50]
CLanguage CSharp Java void Dummy(CLanguage obj) { //... //... CSharp cs = new CSharp(); Dummy(cs); // OK void Dummy(CSharp obj) { //... //... CLanguage c = new CLanguage(); Dummy(c); // 에러 dummy((csharp)c) // 예외발생 [46/50]
다형성 (polymorphism) 적용하는객체에따라메소드의의미가달라지는것 C# 프로그래밍 virtual 과 override 의조합으로메소드선언 예제 4.24 CLanguage c = new Java(); c.print(); c 의형은 CLanguage 이지만 Java 클래스의객체를가리킴 [47/50]
구조체 (struct) 클래스와동일하게객체의구조와행위를정의하는방법 클래스 참조형, 구조체 값형 예제 4.25 구조체를선언하여활용한예제 구조체의형태 [struct-modifiers] struct StructName { // member declarations 구조체의수정자 public, protected, internal, private, new [48/50]
구조체와클래스차이점 1 클래스는참조형이고구조체는값형이다. 2 클래스객체는힙에저장되고구조체객체는스택에저장된다. 3 배정연산에서클래스는참조가복사되고구조체는내용이복사된다. 4 구조체는상속이불가능하다. 5 구조체는소멸자를가질수없다. 6 구조체의멤버는초기값을가질수없다. [49/50]
네임스페이스 (namespace) 서로연관된클래스나인터페이스, 구조체, 열거형, 델리게이트, 하위네임스페이스를하나의단위로묶어주는것 예 ) 여러개의클래스와인터페이스, 구조체, 열거형, 델리게이트등을하나의그룹으로다루는수단을제공 클래스의이름을지정할때발생되는이름충돌묷제해결 네임스페이스선언 namespace NamespaceName { // 네임스페이스에포함할항목을정의 네임스페이스사용 using NamespaceName; // 사용하고자하는네임스페이스명시 [50/50]