2024.01.26(금)
프로그램을 기능중심으로 바라보는 방식으로 "무엇을 어떤 절차로 할 것인가?"가 핵심이 된다. 즉, 어떤 기능을 어떤 순서로 처리하는가에 초점을 맞춘다.
기능이 아닌 객체가 중심이 되며 "누가 어떤 일을 할 것인가?"가 핵심이 된다. 즉, 객체를 도출하고 각각의 역할을 정의해 나가는 것에 초점을 맞춘다.
추상화(abstraction)💭
객체들의 공통적인 특징(기능, 속성)을 도출하는 것
캡슐화(encapsulation)💊
객체가 독립적으로 역할을 할 수 있도록 데이터와 기능을 하나로 묶어 관리하는 것
상속성(inheritance)👑
하나의 클래스가 가진 특징(함수, 데이터)을 다른 클래스가 그대로 물려받는 것
다형성(polymorphism)🎭
약간 다른 방법으로 동작하는 함수를 동일한 이름으로 호출하는 것
부모클래스의 메소드와 같은 이름을 사용하며 매개변수도 같되 내부 소스를 재정의하는 것
덮어쓰기
상속 개념 기반
수직적
class Dog {
public Dog() {
eyes = 0;
nose = 0;
mouse = 0;
ears = 0;
}
protected int eyes, nose, mouse, ears;
**virtual** public void bark() {
Console.WriteLine("Bow-wow!");
}
}
class Pudle : Dog {
public Pudle() {
base.eyes = 1;
base.nose = 2;
base.mouse = 3;
base.ears = 4;
}
public **override** void bark() { // 부모클래스의 bark 메소드 오버라이딩
Console.WriteLine("Woof-woof");
}
}
같은 이름의 함수를 여러 개 정의한 후 매개변수의 타입이나 개수를 다르게 하여 같은 이름을 경우에 따라 호출하여 사용하는 것
쌓기
수평적
int Plus(int a, int b) {
return a + b;
}
int Plus(int a, int b, int c) {
return a + b + c;
}
double Plus(double a, double b) {
return a + b;
}
동적 바인딩(Dynamic Binding)🔗
멤버 변수와 멤버 함수(메소드)로 구성 (
사용자 정의 데이터 타입
)
class 클래스명 { // 클래스 선언
접근지정자 클래스명() {…} // 생성자
접근지정자 ~클래스명() {…} // 소멸자
접근지정자 자료형 멤버변수(필드) // 변수 선언
접근지정자 자료형 메소드() {…} // 메소드
}
class Dog {
public Dog() {…}
public ~Dog() {…}
protected int eyes, nose, mouse, ears;
public void bark() {…}
}
접근 지정자 | 의미 |
---|---|
public | 누구나 접근 가능 |
protected | 상속 관계에 있을 때 상속 받은 자식 클래스에서만 접근 가능 (외부에서는 private처럼, 자식은 public처럼 사용 가능) |
internal | 같은 어셈블리(프로젝트) 내의 모든 클래스가 접근 가능 |
protected internal | protected와 internal의 의미를 모두 포함 |
private | 내 클래스 내부에서만 접근 가능하고, 외부에서는 절대 접근 불가능 |
Dog a = new Dog();
new
연산자가 malloc
과 비슷한 역할을 한다고 생각하면 됨객체 생성 시 자동으로 호출되는 초기화 전용 메소드
객체가 소멸할 때 자동 호출되는 메소드
free
와 비슷한 역할을 한다고 생각하면 됨접근지정자 클래스명 : 부모클래스명
{
// 멤버 목록
}
메소드의 목록만을 가지고 있는 명세(Specification) (
사용자 정의 데이터 타입
)
extends
)implements
)의 의미가 강함접근지정자 interface 이름 (: 기반인터페이스) {
// 메소드 목록
}
접근 지정자 class 자식클래스명 : 인터페이스명 {
// 메소드 오버라이딩
}
using System;
public interface IUnit { // interface의 경우 이름에 prefix로 I를 붙이는 관습이 있다.
void Attack();
void Move();
}
public class Zergling : IUnit {
public void Attack() {
Console.WriteLine("저글링 : 공격한다.");
}
public void Move() {
Console.WriteLine("저글링 : 이동한다.");
}
}
public class Dragoon : IUnit {
public void Attack() {
Console.WriteLine("드라군 : 공격한다.");
}
public void Move() {
Console.WriteLine("드라군 : 이동한다.");
}
}
class HelloWorld {
static void Main() {
Zergling zerg = new Zergling();
zerg.Attack();
zerg.Move();
Dragoon dragoon = new Dragoon();
dragoon.Attack();
dragoon.Move();
}
}
malloc
)하고 해제(free
)해주어야 함new
연산자로 필요한만큼 객체나 메모리를 할당해서 쓰다가 그냥 나가 버리면 됨void func() {
int[] ar = new int[10];
DateTime Now = new DateTime(1970, 6, 29);
// 객체를 실컷 사용한다.
}
💡 힙은 항상 관리중이어서 객체의 번지는 고정되어 있지 않고 힙의 어딘가를 떠 돌아 다닌다.
그래서 포인터를 쓸 수 없지만 대신 객체와 함께 갱신되는 참조자를 통해 액세스할 수 있다.
응용 프로그램 입장에서 컴팩션은 투명하다.
- 참고 자료
메소드를 미리 정의하지 않고 사용할 때 정의
코드가 간결해짐
별도의 메소드를 만들지 않으므로 코딩 오버헤드를 줄임
내용 자체가 복잡하면 안됨
람다식에서 사용됨
using System;
class HelloWorld {
static int Add(int a) {
return a + 1;
}
delegate int CalcDele(int x); // delegate 키워드는 함수 포인터라고 생각하면 됨
static void Main() {
Console.WriteLine(Add(1)); // 2
CalcDele d = delegate (int x) {
return x + 1;
};
Console.WriteLine(d(1)); // 2
}
}
기존 익명 메소드를 더욱 간결하게 만드는 문법
코드를 짧고 간결하게 표현하는 것이 목적
델리게이트 본체를 람다식으로 표현
델리게이트와 인수의 개수 및 타입은 일치해야 함
delegate
키워드는 사라지며 람다식을 의미하는 =>
기호로 대체됨
(파라미터) => 표현식 또는 명령문
delegate (int x, int y) {return x + y;} ––→ **(x, y) => x + y;**
using System;
class HelloWorld {
static int Add(int a) {
return a + 1;
}
delegate int CalcDele(int x); // delegate 키워드는 함수 포인터라고 생각하면 됨
static void Main() {
Console.WriteLine(Add(1)); // 2
CalcDele d = x => x + 1; // 람다식 표현 사용
Console.WriteLine(d(1)); // 2
}
}
이번 주까지해서 타입스크립트를 배우기 전 기초 내용을 강사님께서 설명해주셨는데 정말 만족스러웠다. C#은 잘 모르지만 강사님께서 개념이 어떻게 쓰이는지 쉽게 알려주셔서 후에 타입스크립트를 처음 배울 때 도움이 많이 될 것 같다. 그래도 오늘 내 생일 날까지 공부를 하니 조금 눈물이...ㅋㅋㅋ🥲