... | @@ -2,7 +2,7 @@ |
... | @@ -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`으로 정의된다. 객체를 생성할 때는 `new` 키워드를 사용하며 **Reference Type**으로 할당된다. 단, C#에서는 `delete`와 같은 키워드가 없어서 의도적으로 할당 해제를 할 수 없다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class Person
|
|
class Person
|
... | @@ -11,7 +11,7 @@ class Person |
... | @@ -11,7 +11,7 @@ class Person |
|
|
|
|
|
public Person() // 기본 생성자(매개변수가 없는 생성자)
|
|
public Person() // 기본 생성자(매개변수가 없는 생성자)
|
|
{
|
|
{
|
|
this.name = "이름 없음";
|
|
this.name = "이름 없음"; // this 키워드를 사용하여 객체 참조
|
|
}
|
|
}
|
|
|
|
|
|
public Person(string name) // 매개변수가 있는 생성자
|
|
public Person(string name) // 매개변수가 있는 생성자
|
... | @@ -44,7 +44,7 @@ class Person |
... | @@ -44,7 +44,7 @@ class Person |
|
|
|
|
|
#### **정적 멤버, 인스턴스 멤버**
|
|
#### **정적 멤버, 인스턴스 멤버**
|
|
* **인스턴스 멤버** : `new` 키워드를 사용해서 메모리에 할당된 객체의 멤버이다.
|
|
* **인스턴스 멤버** : `new` 키워드를 사용해서 메모리에 할당된 객체의 멤버이다.
|
|
* **정적 멤버** : `static` 키워드를 사용하여 객체를 생성하지 않고도 전역으로 사용할 수 있는 멤버로 *정적 Filed*, *정적 Method*, *정적 생성자*가 있다. 객체에 *정적 생성자* 있으면 이 생성자를 실행하기 전에 *정적 멤버*가 초기화되며, *정적 생성자*가 없으면 *정적 멤버*를 처음 사용하기 전에 초기화가 된다.
|
|
* **정적 멤버** : `static` 키워드를 사용하여 객체를 생성하지 않고도 전역으로 사용할 수 있는 멤버이다. **정적 멤버**로 사용할 수 있는 멤버로는 *Filed*, *Method*, *생성자*가 있다. 객체에 *정적 생성자* 있으면 이 생성자를 실행하기 전에 *정적 멤버*가 초기화되며, *정적 생성자*가 없으면 *정적 멤버*를 처음 사용하기 전에 초기화가 된다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class Person
|
|
class Person
|
... | @@ -99,7 +99,7 @@ Monitor monitor = new Monitor(); |
... | @@ -99,7 +99,7 @@ Monitor monitor = new Monitor(); |
|
```
|
|
```
|
|
|
|
|
|
### **인터페이스**
|
|
### **인터페이스**
|
|
**인터페이스(Interface)**는 세부적인 내용은 구현하지 않고, 객체가 기본적으로 가져야 할 공통적인 기능들만 정의한 것이다. 정의된 기능들은 객체에서 상속받으면 반드시 재정의해야 하고 그 안에서 세부적인 내용을 추가한다. **인터페이스**의 멤버로는 **Method**, **Property**, **Event**, **Indexer**을 사용할 수 있다.
|
|
**인터페이스(Interface)**는 세부적인 내용은 구현하지 않고, 객체가 기본적으로 가져야 할 공통적인 기능들만 정의한 것이다. 정의된 기능들은 **인터페이스**를 상속받은 객체에서 반드시 재정의해야 하고, 그 안에서 세부적인 내용을 추가한다. **인터페이스**에는 **Method**, **Property**, **Event**, **Indexer**를 멤버로 사용할 수 있다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
interface IKeyboard
|
|
interface IKeyboard
|
... | @@ -121,10 +121,10 @@ class Computer : IKeyboard, IMouse // 다중 상속 가능 |
... | @@ -121,10 +121,10 @@ class Computer : IKeyboard, IMouse // 다중 상속 가능 |
|
* 기본적으로 `public`과 `abstract`는 묵시적으로 적용된다.
|
|
* 기본적으로 `public`과 `abstract`는 묵시적으로 적용된다.
|
|
* **인터페이스**를 상속받으면 자식 객체에서 구현할 때 반드시 `public`을 사용해야 한다.
|
|
* **인터페이스**를 상속받으면 자식 객체에서 구현할 때 반드시 `public`을 사용해야 한다.
|
|
* 접근 한정자(`private`, `protected`, `public`) 또는 `abstract`, `virtual`, `override`, `new` 등의 키워드를 사용할 수 없다.
|
|
* 접근 한정자(`private`, `protected`, `public`) 또는 `abstract`, `virtual`, `override`, `new` 등의 키워드를 사용할 수 없다.
|
|
* **클래스**는 다중 상속이 불가능하지만, **인터페이스**는 다중 상속을 허용된다.
|
|
* **클래스**는 다중 상속이 불가능하지만, **인터페이스**는 다중 상속을 허용한다.
|
|
|
|
|
|
### **상속**
|
|
### **상속**
|
|
**상속(Inheritance)**은 기존 클래스에서 이미 정의된 것들을 다른 클래스에서 사용하거나, 추가 또는 재정의할 수 있도록 한 것이다. 여기서 기존 클래스는 *기반(Based) 클래스*라고 하고, 상속받은 다른 클래스는 *파생(Derived) 클래스*라고 부른다. *파생 클래스*는 하나의 기반 클래스만 상속 받을 수 있으며, *파생 클래스*가 다른 클래스의 *기반 클래스*가 될 수도 있다. C#에서는 `Base` 키워드를 사용하여 *기반 클래스*의 생성자나 Method를 호출할 수 있다.
|
|
**상속(Inheritance)**은 기존 클래스에서 이미 정의된 것들을 다른 클래스에서 사용하거나, 추가 또는 재정의할 수 있도록 한 것이다. 여기서 기존 클래스는 *기반(Based) 클래스*라고 하고, 상속받은 다른 클래스는 *파생(Derived) 클래스*라고 부른다. *파생 클래스*는 하나의 기반 클래스만 상속 받을 수 있으며, *파생 클래스*가 다른 클래스의 *기반 클래스*가 될 수도 있다. C#에서는 `base` 키워드를 사용하여 *기반 클래스*의 생성자나 Method를 호출할 수 있다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class BaseClass
|
|
class BaseClass
|
... | @@ -149,15 +149,15 @@ class DerivedClass : BaseClass |
... | @@ -149,15 +149,15 @@ class DerivedClass : BaseClass |
|
```
|
|
```
|
|
|
|
|
|
### **다형성**
|
|
### **다형성**
|
|
**다형성(Polymorphism)**이란 객체를 여러 형태로 가질 수 있다는 객체지향 개념 중 하나이다. 클래스 간에 상속관계일 때 **Method Override**, **Method Overload**, **추상 클래스**, **인터페이스**와 같은 형태에서 **다형성**을 적용할 수 있다.
|
|
**다형성(Polymorphism)**이란 객체를 여러 형태로 가질 수 있다는 객체지향 개념 중 하나이다. **Method Override**, **Method Overload**, **Abstract 클래스**, **인터페이스**와 같은 형태에 적용할 수 있다.
|
|
|
|
|
|
#### **Method Override**
|
|
#### **Method Override**
|
|
**Method Override**는 *기반 클래스*에서 상속받은 *Method*를 *파생 클래스*에서 사용할 기능으로 재정의하는 것이다. *기반 클래스*의 Method에 `virtual` 키워드를 사용하면 *가상 Method*로 정의된다. *파생 클래스*에서 `override` 키워드를 사용하여 상속받은 Method를 재정의하며, 반드시 *가상 Method*와 같은 형태로 정의해야 한다.
|
|
**Method Override**는 *기반 클래스*의 Method를 *파생 클래스*에 적합한 Method로 재정의하는 것이다. *기반 클래스*의 Method를 *가상 Method*로 정의하기 위해 `virtual` 키워드를 사용한다. *파생 클래스*에서 *Virtual Method*와 같은 형태로 Method를 선언한 후 `override` 키워드를 사용하면 Method를 재정의할 수 있다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class BaseClass
|
|
class BaseClass
|
|
{
|
|
{
|
|
public virtual void printClassInfo() // 가상 Method
|
|
public virtual void printClassInfo() // Virtual Method
|
|
{
|
|
{
|
|
Console.WriteLine("Base Class");
|
|
Console.WriteLine("Base Class");
|
|
}
|
|
}
|
... | @@ -179,7 +179,7 @@ b.printClassinfo(); // 출력 결과 : Base Class |
... | @@ -179,7 +179,7 @@ b.printClassinfo(); // 출력 결과 : Base Class |
|
d.printClassinfo(); // 출력 결과 : Derived Class
|
|
d.printClassinfo(); // 출력 결과 : Derived Class
|
|
```
|
|
```
|
|
|
|
|
|
* *파생 클래스*에서 재정의할 목적이 없을 때 `override`를 사용하지 않으면 다음과 같은 *warning*이 나타난다. 이때 *가상 Method*를 재정의하지 않으려면 `new` 키워드를 사용하면 된다.
|
|
* *파생 클래스*에서 Method를 재정의하지 않기 위해 `override`를 사용하지 않으면, 다음과 같은 *warning*이 나타난다. 이때 *Virtual Method*를 재정의하지 않으려면 `new` 키워드를 사용하면 된다.
|
|
|
|
|
|
> 현재 멤버가 해당 구현을 재정의하도록 하려면 override 키워드를 추가하십시오. 그렇지 않으면 new 키워드를 추가하십시오.
|
|
> 현재 멤버가 해당 구현을 재정의하도록 하려면 override 키워드를 추가하십시오. 그렇지 않으면 new 키워드를 추가하십시오.
|
|
|
|
|
... | @@ -214,7 +214,7 @@ class UsedItem : Item |
... | @@ -214,7 +214,7 @@ class UsedItem : Item |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
* .Net Framework의 모든 클래스는 Object라는 기본 클래스를 상속받는다. Object에 기본적으로 포함된 Method도 Override를 할 수 있다.
|
|
* .Net Framework의 모든 객체는 `Object`라는 기본 클래스를 상속받는다. `Object`에 기본적으로 포함된 Method도 **Override**를 할 수 있다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class MyClass
|
|
class MyClass
|
... | @@ -227,7 +227,7 @@ class MyClass |
... | @@ -227,7 +227,7 @@ class MyClass |
|
```
|
|
```
|
|
|
|
|
|
#### **Method Overload**
|
|
#### **Method Overload**
|
|
* **Method Overload**는 이름만 같은 Method가 매개변수의 개수와 형식만 다르게 다중 정의(Overloading)하는 것이다.
|
|
* **Method Overload**는 이름만 같은 Method가 매개변수의 개수와 형식만 다르게 선언하여 다중 정의(Overloading)한 것이다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class Mathematics
|
|
class Mathematics
|
... | @@ -249,8 +249,9 @@ class Mathematics |
... | @@ -249,8 +249,9 @@ class Mathematics |
|
}
|
|
}
|
|
```
|
|
```
|
|
|
|
|
|
#### **추상 클래스**
|
|
#### **Abstract 클래스**
|
|
**추상 클래스**는 *기반 클래스*에 **추상 Method**를 정의하여 **Method Overload**와 같은 역할을 할 수 있게 한다. **Method Overload**를 상속받은 Method는 `override`와 `new` 키워드를 사용하여 재정의 여부를 정할 수 있지만, **추상 Method**를 상속받은 Method는 반드시 재정의해야 하므로 `override` 키워드를 사용해야 한다. **추상 클래스**를 정의할 때는 `class` 앞에 `abstract` 예약어를 사용하며, **추상 클래스**는 객체로 선언해 사용할 수 없다. 또한, **추상 클래스**의 모든 멤버가 **추상 Method**로 정의되어 있으면 **인터페이스**와 같은 역할을 한다.
|
|
**Abstract 클래스**는 *Abstract Method*가 존재하는 클래스다. *Abstract Method*는 *파생 클래스*에서 반드시 재정의되어야 한다. **Abstract 클래스**의 모든 멤버가 **Abstract Method**로 정의되어 있으면 **인터페이스**와 같은 역할을 한다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
abstract class AbstractClass
|
|
abstract class AbstractClass
|
|
{
|
|
{
|
... | @@ -260,12 +261,12 @@ abstract class AbstractClass |
... | @@ -260,12 +261,12 @@ abstract class AbstractClass |
|
get { return _name; }
|
|
get { return _name; }
|
|
}
|
|
}
|
|
|
|
|
|
public abstract void printClassInfo(); // 추상 Method
|
|
public abstract void printClassInfo(); // Abstract Method
|
|
}
|
|
}
|
|
|
|
|
|
class MyClass : AbstractClass
|
|
class MyClass : AbstractClass
|
|
{
|
|
{
|
|
public virtual void printClassInfo()
|
|
public override void printClassInfo()
|
|
{
|
|
{
|
|
Console.WriteLine("My Class");
|
|
Console.WriteLine("My Class");
|
|
}
|
|
}
|
... | @@ -273,12 +274,12 @@ class MyClass : AbstractClass |
... | @@ -273,12 +274,12 @@ class MyClass : AbstractClass |
|
```
|
|
```
|
|
|
|
|
|
#### **인터페이스**
|
|
#### **인터페이스**
|
|
(이미 현재 문서에 포함된 내용이다.)
|
|
(이미 현재 문서에 포함된 내용)
|
|
|
|
|
|
### **Property**
|
|
### **Property**
|
|
**클래스**에서 *Field* 값을 읽고 쓰기 위해 *접근자 Method*를 사용한다. 하지만 *Field*를 생성할 때마다 일일이 정의해야 하고, 코드가 길어져 가독성이 떨어진다. **Property**를 사용하면 이를 단순화 시킬 수 있다.
|
|
**클래스**에서 *Field*의 값을 읽거나 쓰기 위해 *접근자 Method*를 정의하여 사용한다. 하지만 *Field*를 생성할 때마다 일일이 정의하게 되면 코드가 길어져 가독성이 떨어진다. *접근자 Method* 대신에 **Property**를 사용하면 이를 단순화 시킬 수 있다.
|
|
|
|
|
|
* `get`과 `set` 접근자를 사용하여 **Property**를 사용할 수 있다. `set` 접근자에는 매개변수 대신에 `value` 키워드를 사용한다.
|
|
* `get`과 `set` 접근자를 사용하여 **Property**를 사용할 수 있다. `set` 접근자는 매개변수 대신에 `value` 키워드를 사용한다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
class Person
|
|
class Person
|
... | @@ -308,7 +309,7 @@ class Person |
... | @@ -308,7 +309,7 @@ class Person |
|
|
|
|
|
### **Partial**
|
|
### **Partial**
|
|
#### **Partial Type**
|
|
#### **Partial Type**
|
|
**Partial Type**는 **클래스**, **구조체** 또는 **인터페이스**의 정의를 여러 개로 나누는 것이다. **Partial Type**을 정의할 때는 `partial` 키워드를 사용하며, 여러 파일로도 나누어 정의할 수도 있다.
|
|
**Partial Type**을 사용하여 **클래스**, **구조체** 또는 **인터페이스**의 내용을 여러 개로 나누어 정의할 수 있다. 객체를 구현 할 때 역할에 따라 여러 파일로 나누어 분담할 수 있다.
|
|
|
|
|
|
```javascript
|
|
```javascript
|
|
// Project.model.cs
|
|
// Project.model.cs
|
... | | ... | |