24년 1월 26일 강의를 들은 내용을 기록한 글입니다.
클래스
- 사용자 정의 데이터타입
- 추상적인 데이터타입
- 구조체와 비슷
클래스 = 멤버변수 + 멤버 함수
📘클래스 구조
- 사물의 특성을 정리하여 필드와 메소드로 표현하는 과정 => 추상화
- 추상된 결과를 하나의 클래스에 포함시키고 스스로 보호하는 것이 캡슐화
■ 예제
1. 사람
- 상태(필드): 피부색, 키, 나이, 성별, 이름 …
- 행동(메소드): 생각한다, 공부한다, 걷는다, 말한다, 먹는다 …
2. 노트북
- 상태(필드): CPU, 메모리 크기, 하드디스크 …
- 행동(메소드): 부팅한다. 충전한다. CD-ROM을 읽는다 …
📘클래스 선언 형식
1
2
3
4
5
| class 클래스이름{
접근 지정자 클래스 이름(){...}
접근 지정자 데이터형 멤버변수(필드);
접근 지정자 데이터형 메소드(){...}
}
|
■ 예제
1
2
3
4
| class Dog {
private int eyes, nose, mouth , ears;
public void bark(){}
}
|
📘접근지정자 종류
- public: 누구나 접근 가능
- protected: 상속 관계에서 상속 받은 자식 클래스에서 접근 가능, 그 외에는 접근 불가
- private: 내 클래스에서만 접근이 가능하고, 외부에서는 절대 접근 불가
- internal: 같은 프로젝트 내의 모든 클래스가 접근 가능
- protected internal: protected + internal
📘클래스를 통해 객체 선언 및 생성
- 클래스를 통해 선언한 변수를 객체라고 함
new
연산자를 사용하여 객체를 생성함
■ 예제
1
2
3
4
5
6
7
8
9
| class Dog {
private int eyes, nose, mouth , ears;
public void bark(){
Console.WriteLine("개 짖는 소리");
}
};
Dog a = new Dog();
a.bark(); // 개 짖는 소리
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| using System;
class Dog {
private int eyes, nose, mouth , ears;
public void bark(){
Console.WriteLine("개 짖는 소리");
}
};
class HelloWorld {
static void Main() {
Dog a = new Dog();
a.bark();
}
}
|
📘생성자
모든 변수는 선언이 되면 초기화를 해야 한다. 객체도 변수이므로 선언되면 초기화를 해야 한다
=> 객체 생성시 초기화시켜주는 메소드가 바로 생성자(constructor)
- 클래스 이름과 동일한 이름의 함수
- 초기화 전용이기때문에 리턴타입을 작성하지 않아도 됨
1
2
3
4
5
6
7
8
9
| class Dog {
private int eyes, nose, mouth, ears;
public Dog(){
eyes = 2;
nose = 1;
mouth = 1;
ears = 2;
}
};
|
상속성
이미 완성된 클래스를 다른 클래스에서 상속시킬 수 있음
■ 예제
개를 상속받아서 눈의 개수 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
| class Dog {
protected int eyes, nose, mouth, ears;
public virtualvoid bark(){
Console.WriteLine("개 짖는 소리");
}
public Dog(){
eyes = 0;
nose = 1;
mouth = 1;
ears = 2;
}
};
class Pudle : Dog {
public Pudle(){
base.eyes = 2;
Console.WriteLine("푸들 눈: {0}", eyes);
}
public override void bark(){
Console.WriteLine("왈왈");
}
};
class HelloWorld {
static void Main() {
Dog a = new Dog();
a.bark(); // 개 짖는 소리
Pudle pd = new Pudle(); // 푸들 눈: 2
pd.bark(); // 왈왈
}
}
|
다형성
- 함수의 이름이 같더라도 전달인자의 타입이나 개수에 따라 구분됨
📘오버로딩 (overloading)
메서드 중복 정의
한 클래스 안에 같은 이름의 메소드를 여러개 정의하는 것
■ 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| public class Animal{
public void Overload(int rabbit){
Console.WriteLine("토끼 {0}마리", rabbit);
}
public void Overload(int rabbit, int panda){
Console.WriteLine("토끼 {0}마리 + 판다 {1}마리", rabbit, panda);
}
public void Overload(int rabbit, int panda, int cat){
Console.WriteLine("토끼 {0}마리 + 판다 {1}마리 + 고양이 {2}마리", rabbit, panda, cat);
}
public void Overload(string rabbit){
Console.WriteLine("토끼 {0}색", rabbit);
}
};
class HelloWorld {
static void Main() {
Animal ani = new Animal();
ani.Overload(10); // 토끼 10마리
ani.Overload(10,3); // 토끼 10마리 + 판다 3마리
ani.Overload(10,3,5); // 토끼 10마리 + 판다 3마리 + 고양이 5마리
ani.Overload("핑크"); // 토끼 핑크색
}
}
|
📘오버라이딩 (Overriding)
상속받은 메서드를 그대로 사용하는 것이 아니라,
재정의해서 사용하는 것
■ 예제
- Pudle 클래스에서 override 키워드를 사용해서 Dog 클래스에서 상속받은
bark()
내용을 변경
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| class Dog {
protected int eyes, nose, mouth, ears;
public virtual void bark(){
Console.WriteLine("개 짖는 소리");
}
public Dog(){
eyes = 0;
nose = 1;
mouth = 1;
ears = 2;
}
};
class Pudle : Dog {
public Pudle(){
base.eyes = 2;
Console.WriteLine("푸들 눈: {0}", eyes);
}
public override void bark(){
Console.WriteLine("왈왈");
}
};
class HelloWorld {
static void Main() {
Dog dog = new Dog();
dog.bark(); // 개 짖는 소리
Pudle pd = new Pudle(); // 푸들 눈: 2
pd.bark(); // 왈왈
dog = new Pudle();
dog.bark(); // 왈왈
}
}
|
인터페이스
- 사용자 정의 타입
- 메소드 목록만을 가지고 있는 명세
- 메소드 목록만 선언하고, 구현은 하지 않음 (스펙만 작성)
- 독립적으로 사용할 수 없음
📘인터페이스 형태
1
| 접근지정자 interface 이름 : 기반인터페이스{}
|
1
| 접근지정자 class 자식클래스이름 : 인터페이스 {}
|
📘인터페이스를 사용하는 이유
- 기능을 추가하거나 수정의 개념보다는 동일한 개념의 기능을 새롭게 구현하는 기능
- 공동작업 시 표준을 정하는 역할
■ 추상 클래스를 상속하는 경우
- 일반적으로 클래스를 상속하는 이유는 기능 확장이 목적
- 기존 기능을 재정의하거나, 새로운 기능을 추가
1
2
3
4
5
6
7
8
9
10
11
12
| class 스마트폰기본(){
통화기능
문자메세지기능
와이파이기능
}
class 갤럭시 : 스마트폰기본 {
통화기능
문자메세지기능
와이파이기능
멀티미디어기능
블루투스기능
}
|
■ 인터페이스를 상속하는 경우
- 기존 기능을 어떻게 정의할 것인지 명세
- 자식클래스에서 상속
1
2
3
4
5
6
7
8
9
10
11
12
13
| interface 통화기능{}
interface 문자메세지기능{}
interface 와이파이기능{}
interface 멀티미디어기능{}
interface 블루투스기능{}
class 스마트폰_기본 : 통화기능, 문자메세지기능, 와이파이기능, 멀티미디어기능, 블루투스기능 {
// 통화 기능 구현
// 문자메세지 기능 구현
// 와이파이 기능 구현
// 멀티미디어 기능 구현
// 블루투스 기능 구현
}
|
■ 인터페이스 사용방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| public interface IUnit {
void Attack();
void move();
}
public class Rabbit : IUnit {
public void Attack(){
Console.WriteLine("토끼 앞발 공격!");
}
public void move(){
Console.WriteLine("토끼 뛴다!");
}
}
public class Panda : IUnit {
public void Attack(){
Console.WriteLine("판다 앞발 공격!");
}
public void move(){
Console.WriteLine("판다 뛴다!");
}
}
class HelloWorld {
static void Main() {
Rabbit rabbit = new Rabbit();
rabbit.Attack(); // 토끼 앞발 공격!
rabbit.Move(); // 토끼 뛴다!
Panda panda = new Panda();
panda.Attack(); // 판다 앞발 공격!
panda.Move(); // 판다 뛴다!
}
}
|
■ 인터페이스 메모리 관리
- 가바지 컬렉터가 메모리를 자동 관리
- 사용되지 않는 메모리는 삭제됨(회수)