본문 바로가기
타입스크립트로 함께하는 웹 풀 사이클 개발(React, Node.js)/TIL

데브코스 11주차 Day5 - 클래스, 인터페이스, (상속성, 다형성 - 오버로딩 오버라이딩)

by 슈크림 붕어빵 2024. 1. 29.

접근 지정자

  • 클래스 또는 변수 등 접근할 수 있는 대상을 설정한다.

public: 누구나 접근 가능

protected: 상속관계에 있을 때, 상속 받은 자식 클래스에서 접근 가능

internal: 같은 어셈블리(프로젝트)내의 모든 클래스가 접근 가능

protected internal: protected 와 internal의 의미를 모두 포함

private: 해당 클래스 내부에서만 접근 가능

 

클래스

  • 사용자 정의 데이터 타입이다.
  • 데이터와 메소드로 이루어져 있다.
  • 사물의 특성을 정리하여 필드(변수)와 메소드로 표현하는 과정은 추상화
  • 추상화된 결과를 하나의 클래스에 포함시키고 스스로 보호하는 것을 캡슐화

 

객체 할당하기 - new와 malloc

 

 

객체이기 때문에 class객체는 Haep에, class객체를 가리키는 변수는 stack에 저장된다.

객체지향에서는 new를 통해 객체를 생성한다.

malloc과 차이점은 malloc은 사이즈까지 지정해준다. new는 필요한 공간을 자동으로 계산하여 할당한다.

 

 

 

 

 

 

 

생성자

  • 모든 변수는 선언이 되면 값을 초기화해야한다.
  • 객체 생성시 변수를 초기화하기 위한 것이 생성자이다.
  • 규칙: 클래스의 이름과 같아야한다, 초기화 전용 함수이기 때문에 return 타입이 없다.
  • new로 객체를 만들었고 Student 생성자로 초기화를 했다. 
using System;

class Student {
    protected int age; 
    protected string name; 

    public Student(int num, string stdName){ //생성자
        age = num;
        name = stdName;
    }

    public void SetAge(int num) {
        age = num; 
    }

    public void SetName(string studentName) {
        name = studentName; 
    }

    public void DisplayInfo() {
        Console.WriteLine("name: " + name);
        Console.WriteLine("age: " + age);
    }
}

class Program {
    public static void Main(string[] args) {
        Student std1 = new Student(24,"sungeun");
        std1.SetName("sungeun"); 
        std1.SetAge(24); 

        std1.DisplayInfo(); 

    }
}

상속성

  • 이미 완성된 클래스를 다른 클래스에 상속할 수 있다.
  • 코드 
    1. person을 상속받은 student
    2. student의 생성자는 person의 생성자를 상속받아서 사용한다. student는 나이가 20으로 고정이기 때문에 person과 다르게 name만 인자로 받는다.
    3. student객체는 person class를 상속받았기 때문에 person의 메소드를 사용할 수 있다.
using System;

class Person {
    protected int age; 
    protected string name; 

    public Person(int num, string stdName) { // 생성자
        age = num;
        name = stdName;
    }

    public void SetAge(int num) {
        age = num; 
    }

    public void SetName(string studentName) {
        name = studentName; 
    }

    public void DisplayInfo() {
        Console.WriteLine("name: " + name);
        Console.WriteLine("age: " + age);
    }
}

class Student : Person {
    public Student(string name) : base(20, name){} 
}

class Program {
    public static void Main(string[] args) {
        Student std1 = new Student("sungeun");
        std1.DisplayInfo(); 
    }
}

 

다형성

  • 함수의 이름이 같더라도 전달인자의 타입이나 개수에 따라 구분된다.
  • 객체 지향에서는 대표적으로 오버로딩이나 오버라이딩 기법이 있다.

 

다형성- 오버로딩

  • 이름이 같은 함수일지라도 전달인자 타입이나 개수가 다른 경우이다.
  • 코드
    • 메소드의 매개변수의 개수에 따라 더하기를 하는 class를 만들어보았다.
using System;

public class Cal {
    public void add(int a){
        Console.WriteLine(a);
    }
    public void add(int a,int b){
        Console.WriteLine(a+b);
    }
    public void add(int a,int b, int c){
        Console.WriteLine(a+b+c);
    }
}

class Program {
    public static void Main(string[] args) {

        Cal cal = new Cal();
        cal.add(1);
        cal.add(1,2);
        cal.add(1,2,3);

    }
}

 

다형성 - 오버라이딩

  • 기존 것을 덮어버리는 개념이다.
  • 상속의 개념이 기반이 되어야한다.
  • 코드
    • 다음은 Dog class를 상속받은 Poodle class의 메소드의 오버라이딩 예시이다.
    • 상속받은 poodle class는 bark()함수를 다르게 구현했다.부모 class에서 virtual로 표시를 해주고 자식 class에서 override로 오버라이드를 구현한다. 
class Dog {
    public virtual void bark(){
        Console.WriteLine("mung..");
    }
}
class Poodle : Dog{
    public override void bark(){
        Console.WriteLine("walwal..");
    }
}

class Program {
    public static void Main(string[] args) {
        Dog dog = new Dog();
        dog.bark();
        Poodle poodle = new Poodle();
        poodle.bark();
    }
}

 

인터페이스

  • 인터페이스란 메소드의 목록만을 가지고 있는 명세, 사용자 정의 타입이다.
  • 메소드의 목록만 선언하고 구현은 하지 않는다. ( class와 차이점 )
  • 인터페이스는 다중 상속이 가능하다. ( class와 차이점)
  • 무조건 오버라이딩을 해야한다.
  • 사용하는 이유
    • 동일한 개념의 기능을 새롭게 구현하는 기능..
    • 공동작업시 표준을 정하는 역할
  • 추상클래스를 상속하는 이유 => 주로 기능의 확장
  • 인터페이스를 상속하는 이유 => 여러 기능을 나열, 즉 기능을 명세하고 자식 클래스에서 상속한다.

 

메모리 관리

  • 플랫폼 기반의 객체 지향 언어는 가비지 컬렉터가 메모리를 자동 관리한다.
  • free를 해줄 필요가 없다는 의미이다.

익명메소드, 람다

  • 익명메소드를 사용하면 코드가 간결해진다. but, 내용이 복잡하면 안된다.
  • delegate(int x){ return x + 1; },  x => x + 1 부분이 익명 메서드에 해당, 이를 변수 d,a에 넣는 것이다.
  • 람다식이란 메소드를 "하나의 식"으로 표현한 것이라고 할 수 있다.
  • 하나의 식으로 표현하여 훨씬 간략하게 표현이 가능하게 되며, 메서드의 이름과 반환값이 없어지므로 익명함수라고도 합니다.
  • => 화살표 연산자를 사용하여 람다 식을 만든다. x => x + 1가 람다 표현식에 해당
using System;

class MyCompiler {
        delegate int CalcDele(int x);
        
        public static void Main(string[] args) {

            CalcDele d = delegate(int x){
                return x+1;
            };
            CalcDele a = x =>x+1;
            Console.WriteLine(d(3));
            Console.WriteLine(a(3));
        }
}

 


 

기초부터 탄탄하게 잡아가는 느낌이라 재밌었다. 특히 메모리구조와 할당까지 생각하며 공부하는 게 재밌었다.

객체지향의 기본을 정리할 수 있었던 것 같다.

마지막으로 C#이 오랜만이라 개념마다 하나씩 코드를 짜볼 때마다 오류도 좀 났지만, 만들어보는 과정이 있어서 이해가 더 잘된 것 같다.