... | ... | @@ -2,7 +2,7 @@ |
|
|
---
|
|
|
|
|
|
### **클래스**
|
|
|
**클래스(Class)**에는 *Field*, *Method*, *생성자*, *소멸자*와 같은 *멤버(Member)*들을 포함할 수 있다. *Filed*는 클래스 내부에 선언된 속성으로 임의 형식의 변수를 말한다. 클래스의 멤버들을 선언할 때 접근 한정자(`private`, `protected`, `public`)를 생략하면 `private`으로 정의된다. 객체를 생성할 때는 **Reference Type**으로 할당되며, `new` 키워드를 사용한다. C#에서는 `delete`와 같은 키워드가 없어 의도적으로 할당 해제를 할 수 없다. 하지만 **Garbage Collector**에서 사용되고 있지 않는 객체를 할당 자동으로 해제하는 역할을 한다. 이때 *소멸자*가 호출되며 자동으로 해제되므로 그 시기를 알 수 없다. **클래스**에서 `this` 키워드를 사용하여 자신의 객체를 참조할 수 있다.
|
|
|
**클래스(Class)**에는 *Field*, *Method*, *생성자*, *소멸자*와 같은 *멤버(Member)*들을 포함할 수 있다. *Filed*는 클래스 내부에 선언된 속성으로 임의 형식의 변수를 말한다. 클래스의 멤버를 선언할 때 접근 한정자(`private`, `protected`, `public`)를 생략하면 `private`으로 정의된다. 객체를 생성할 때는 **Reference Type**으로 할당되며, `new` 키워드를 사용한다. C#에서는 `delete`와 같은 키워드가 없어 의도적으로 할당 해제를 할 수 없다. 하지만 **Garbage Collector**에서 사용되고 있지 않은 객체를 할당 자동으로 해제하는 역할을 한다. 이때 *소멸자*가 호출되며 자동으로 해제되므로 그 시기를 알 수 없다. **클래스**에서 `this` 키워드를 사용하여 자신의 객체를 참조할 수 있다.
|
|
|
|
|
|
```javascript
|
|
|
class Person
|
... | ... | @@ -110,10 +110,10 @@ interface IMouse |
|
|
{
|
|
|
void click();
|
|
|
}
|
|
|
class Computer : IKeyboard, IMouse
|
|
|
class Computer : IKeyboard, IMouse // 다중 상속 가능
|
|
|
{
|
|
|
public pressed() { }
|
|
|
public click() { }
|
|
|
public void pressed() { }
|
|
|
public void click() { }
|
|
|
}
|
|
|
```
|
|
|
|
... | ... | @@ -127,7 +127,7 @@ class Computer : IKeyboard, IMouse |
|
|
**상속(Inheritance)**은 기존 클래스에서 이미 정의된 것들을 다른 클래스에서 사용하거나, 추가 또는 재정의할 수 있도록 한 것이다. 여기서 기존 클래스는 *기반(Based) 클래스*라고 하고, 상속받은 다른 클래스는 *파생(Derived) 클래스*라고 부른다. *파생 클래스*는 하나의 기반 클래스만 상속 받을 수 있으며, *파생 클래스*가 다른 클래스의 *기반 클래스*가 될 수도 있다. C#에서는 `Base` 키워드를 사용하여 *기반 클래스*의 생성자나 Method를 호출할 수 있다.
|
|
|
|
|
|
```javascript
|
|
|
public class BaseClass
|
|
|
class BaseClass
|
|
|
{
|
|
|
private string a;
|
|
|
|
... | ... | @@ -137,7 +137,7 @@ public class BaseClass |
|
|
}
|
|
|
}
|
|
|
|
|
|
public class DerivedClass : BaseClass
|
|
|
class DerivedClass : BaseClass
|
|
|
{
|
|
|
private int b;
|
|
|
|
... | ... | @@ -149,28 +149,21 @@ public class DerivedClass : BaseClass |
|
|
```
|
|
|
|
|
|
### **다형성**
|
|
|
**다형성(Polymorphism)**이란 객체는 여러 형태를 가질 수 있음을 의미한다. 클래스가 상속관계일 때 *Override*, *Overload*, *추상 클래스*, *인터페이스*, *Casting*와 같은 형태에서 **다형성**을 적용시킬 수 있다.
|
|
|
|
|
|
다형성은 같은 메시지에 다른 동작이 가능하게 하는 인데요
|
|
|
|
|
|
C#에서는 *Boxing*, *Unboxing*, *Delegate* 등 **다형성**에 대한 다양한 기능들을 제공한다.
|
|
|
형성의 실현은 자신으로부터 상속받아 만들어진 파생 클래스를 통해 이루어진다.
|
|
|
|
|
|
파생 클래스에 따라 다양하게 재정의
|
|
|
**다형성(Polymorphism)**이란 객체를 여러 형태로 가질 수 있다는 객체지향 개념 중 하나이다. 클래스 간에 상속관계일 때 **Method Override**, **Method Overload**, **추상 클래스**, **인터페이스**와 같은 형태에서 **다형성**을 적용할 수 있다. C#에서는 *Boxing*, *Unboxing*, *Delegate* 등 **다형성**에 대한 다양한 기능들을 제공한다.
|
|
|
|
|
|
#### **Method Override**
|
|
|
**Method Override**는 *기반 클래스*에서 상속받은 *Method*를 *파생 클래스*에서 사용할 기능으로 재정의하는 것이다. *기반 클래스*의 Method에 `virtual` 키워드를 사용하면 *가상 Method*로 정의된다. *파생 클래스*에서 `override` 키워드를 사용하여 상속받은 Method를 재정의 하며, 반드시 *가상 Method*와 같은 형태로 정의해야 한다.
|
|
|
**Method Override**는 *기반 클래스*에서 상속받은 *Method*를 *파생 클래스*에서 사용할 기능으로 재정의하는 것이다. *기반 클래스*의 Method에 `virtual` 키워드를 사용하면 *가상 Method*로 정의된다. *파생 클래스*에서 `override` 키워드를 사용하여 상속받은 Method를 재정의하며, 반드시 *가상 Method*와 같은 형태로 정의해야 한다.
|
|
|
|
|
|
```javascript
|
|
|
public class BaseClass
|
|
|
class BaseClass
|
|
|
{
|
|
|
public virtual void printClassInfo()
|
|
|
public virtual void printClassInfo() // 가상 Method
|
|
|
{
|
|
|
Console.WriteLine("Base Class");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public class DerivedClass : BaseClass
|
|
|
class DerivedClass : BaseClass
|
|
|
{
|
|
|
public override void printClassInfo()
|
|
|
{
|
... | ... | @@ -191,7 +184,7 @@ d.printClassinfo(); // 출력 결과 : Derived Class |
|
|
> 현재 멤버가 해당 구현을 재정의하도록 하려면 override 키워드를 추가하십시오. 그렇지 않으면 new 키워드를 추가하십시오.
|
|
|
|
|
|
```javascript
|
|
|
public class DerivedClass : BaseClass
|
|
|
class DerivedClass : BaseClass
|
|
|
{
|
|
|
public new void printClassInfo()
|
|
|
{
|
... | ... | @@ -200,7 +193,7 @@ public class DerivedClass : BaseClass |
|
|
}
|
|
|
```
|
|
|
|
|
|
* **Property**로 정의 된 Method도 재정의를 할 수 있다.
|
|
|
* **Property**로 정의된 Method도 `override` 키워드를 사용해 재정의할 수 있다.
|
|
|
|
|
|
```javascript
|
|
|
class Item
|
... | ... | @@ -212,7 +205,7 @@ class Item |
|
|
}
|
|
|
}
|
|
|
|
|
|
public class UsedItem : Item
|
|
|
class UsedItem : Item
|
|
|
{
|
|
|
public override int price
|
|
|
{
|
... | ... | @@ -221,7 +214,7 @@ public class UsedItem : Item |
|
|
}
|
|
|
```
|
|
|
|
|
|
* .Net Framework의 모든 클래스는 Object라는 기본 클래스를 상속받는다. Object에 기본적으로 포함되어 있는 Method도 Override를 할 수 있다.
|
|
|
* .Net Framework의 모든 클래스는 Object라는 기본 클래스를 상속받는다. Object에 기본적으로 포함된 Method도 Override를 할 수 있다.
|
|
|
|
|
|
```javascript
|
|
|
class MyClass
|
... | ... | @@ -256,7 +249,7 @@ class Mathematics |
|
|
}
|
|
|
```
|
|
|
|
|
|
* **연산자 Overload**
|
|
|
#### **연산자 Overload**
|
|
|
**연산자 Overload**는 *정적 Method*에 `+`, `-`, `*`, `/` 등과 같은 연산자를 `operator` 키워드를 사용해 다중 정의(Overloading)하는 것이다.
|
|
|
|
|
|
```javascript
|
... | ... | @@ -284,14 +277,34 @@ Adder result = number1 + number2; |
|
|
Console.WriteLine(result.value); // 출력 결과 : 5
|
|
|
```
|
|
|
|
|
|
#### 추상 클래스
|
|
|
|
|
|
#### **추상 클래스**
|
|
|
**추상 클래스**는 *기반 클래스*에 **추상 Method**를 정의하여 **Method Overload**와 같은 역할을 할 수 있게 한다. **Method Overload**를 상속받은 Method는 `override`와 `new` 키워드를 사용하여 재정의 여부를 정할 수 있지만, **추상 Method**를 상속받은 Method는 반드시 재정의해야 하므로 `override` 키워드를 사용해야 한다. **추상 클래스**를 정의할 때는 `class` 앞에 `abstract` 예약어를 사용하며, **추상 클래스**는 객체로 선언해 사용할 수 없다. 또한, **추상 클래스**의 모든 멤버가 **추상 Method**로 정의되어 있으면 **인터페이스**와 같은 역할을 한다.
|
|
|
```javascript
|
|
|
abstract class AbstractClass
|
|
|
{
|
|
|
private string _name;
|
|
|
public string name
|
|
|
{
|
|
|
get { return _name; }
|
|
|
}
|
|
|
|
|
|
public abstract void printClassInfo(); // 추상 Method
|
|
|
}
|
|
|
|
|
|
#### Casting
|
|
|
class MyClass : AbstractClass
|
|
|
{
|
|
|
public virtual void printClassInfo()
|
|
|
{
|
|
|
Console.WriteLine("My Class");
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
#### **인터페이스**
|
|
|
(이미 현재 문서에 포함된 내용이다.)
|
|
|
|
|
|
### **Property**
|
|
|
**클래스**에서 *Field* 값을 읽고 쓰기 위해 *접근자 Method*를 사용한다. 하지만 *Field*를 생성할 때마다 일일이 정의해야 하고, 코드가 길어져 가독성이 떨어진다. **Property**를 사용하여 이를 단순화 시킬 수 있다.
|
|
|
**클래스**에서 *Field* 값을 읽고 쓰기 위해 *접근자 Method*를 사용한다. 하지만 *Field*를 생성할 때마다 일일이 정의해야 하고, 코드가 길어져 가독성이 떨어진다. **Property**를 사용하면 이를 단순화 시킬 수 있다.
|
|
|
|
|
|
* `get`과 `set` 접근자를 사용하여 **Property**를 사용할 수 있다. `set` 접근자에는 매개변수 대신에 `value` 키워드를 사용한다.
|
|
|
|
... | ... | @@ -312,7 +325,7 @@ person.age = "김선욱"; |
|
|
Console.WriteLine(person.name); // 출력 결과 : 김선욱
|
|
|
```
|
|
|
|
|
|
* C# 3.0부터는 자동구현 **Property**를 제공하여 더 간결하게 정의할 수 있다.
|
|
|
* C# 3.0부터는 *자동구현 Property**를 제공하여 더 간결하게 정의할 수 있다.
|
|
|
|
|
|
```javascript
|
|
|
class Person
|
... | ... | @@ -347,8 +360,8 @@ public partial class Project |
|
|
}
|
|
|
```
|
|
|
|
|
|
#### **Partial Mothod**
|
|
|
**Partial Method**는 **Partial Type**의 Method를 나누어 정의하는 것이다. Method를 *선언*과 *본문*으로 나누며 `void`로 반환해야 한다. 접근 한정자를 사용할 수 없지만, 암묵적으로 `private`로 선언된다.
|
|
|
#### **Partial Method**
|
|
|
**Partial Method**는 **Partial Type**의 Method를 나누어 정의하는 것이다. Method를 *선언*과 *본문*으로 나누며 반드시 `void`로 반환해야 한다. **Partial Method**은 암묵적으로 `private`로 선언되므로 접근 한정자를 따로 사용할 수 없다.
|
|
|
|
|
|
```javascript
|
|
|
partial class Project
|
... | ... | |