25.09.27 개발일지 / C# 2(1) (Chapter07, Chapter08)

2025. 11. 11. 10:32·LMS 7/개발일지

Chapter07. 클래스

더보기

1. 객체지향 프로그래밍(OOP)와 클래스(class)

> C# 에서는 모든 것이 클래스로 이루어져 있음

> 클래스는 데이터(필드)와 메서드를 품을 수 있는 집합체이자, 하나의 데이터 형식이라고 볼 수 있음

int a;

// C에서는 int는 자료형, a는 변수
// C#에서는 int는 클래스이며 a는 객체

 

2. this()

> this()는 this가 객체 본인을 가르키는 키워드의 역할을 하는 것처럼 객체 본인의 생성자를 가르키는 역할을 함

class MyClass
{
    int a, b;
    public MyClass()
    {
        this.a = 5425;
    }
    // MyClass(int b) 생성자는 this()를 통해 MyClass()를 호출하여 a를 초기화(이니셜라이저)하고, 본문을 통해 b를 초기화함
    public MyClass(int b) : this()
    {
        this.b = b;
    }
}

 

3. base

> base는 상속 관계에서 기반 클래스를 가르킬 수 있는 키워드임

class First
{
    public void FirstMethod() { }
}

class Second : First
{
    public void SecondMethod()
    {
        base.FirstMethod(); // base 키워드로 기반 클래스의 메서드에 접근
    }
}

3.1 base()

> base()는 상속 관계에서 기반 클래스의 생성자를 가르킬 수 있는 생성자임

class First
{
    protected string Name;
    public First(string Name)
    {
        this.Name = Name;
    }
}

class Second : First
{
    public Second(string Name) : base(Name) { } // base() 생성자로 기반 클래스의 생성자에 접근
}

 

4. is

> is는 객체를 원하는 형식과 비교하여 결과를 bool로 반환함

// 클래스 정의
class Mammal
{
    public void Nurse() {}
}
class Dog : Mammal
{
    public void Bark() {}
}

Mammal mammal = new Dog();
Dog dog;
// mammal 객체가 Dog 형식인지 검사 후 맞다면 True를, 아니라면 False로 반환함
if (mammal is Dog) {
    dog = (Dog)mammal;
    dog.Bark();
}
 

4.1 as

> as는 형식 변환 연산자로써 객체를 원하는 형식으로 형 변환하되, 실패한 경우 참조 객체를 null 값으로 채움

class Mammal
{
    public void Nurse() {}
}
class Cat : Mammal
{
    public void Meow() {}
}

Mammal mammal = new Cat();
Cat cat = mammal as Cat; // mammal 객체를 Cat 형식으로 형 변환하되, 실패시에는 참조 객체인 cat을 null 값으로 채움

if (cat != null) {
    cat.Meow();
}

 

5. 메서드 숨기기(new)

> 메서드 숨기기는 명시적으로 같은 이름의 기반 클래스의 메서드를 무시할 때 사용한다

> 하지만 오버라이딩과는 아예 다른 개념이기 때문에, 정적 바인딩인 경우(virtual, override를 사용하지 않는 경우를 말함) 컴파일 시점에서 생성된 객체의 타입이 기반 클래스인 경우에는 기반 클래스의 메서드가 사용되므로 주의해야 함

class Base
{
    public void MyMethod() { }
}
class Derived : Base
{
    public new void MyMethod() { } // new 키워드가 사용됨
}

// 파생 클래스 형식으로 생성된 객체
Derived derived = new Derived();
derived.MyMethod(); // 기반 클래스의 메서드를 무시한다

// 기반 클래스 형식으로 생성된 객체
Base base = new Derived();
Base.MyMethod(); // 정적 바인딩인 경우 base 객체의 형식을 기준으로 판단하므로 Base 클래스의 메서드가 사용됨

 

6. 오버라이딩 봉인(seald)

> 오버라이딩을 할 수 없도록 막아놓는 걸 말한다.

> 기반 클래스가 virtual 선언을 해놓은 것만을 대상으로 한다

> 기반 클래스 작성자의 virtual 선언 의도는 명백히 파생 클래스들의 오버라이딩인데, 1차 파생 클래스 작성자는 자신 이후의 오버라이딩을 원하지 않을 수 있으므로 선택을 할 수 있도록 만들어놓은 키워드라 할 수 있다.

class Base
{
    public virtual void Seal(){ } // 오버라이딩 목적을 위한 virtual 선언
}
class Derived : Base
{
    public sealed override Seal(){ } // 오버라이딩 후 sealed 키워드를 통해 이후의 오버라이딩 봉인
}
class Overrrid : Derived
{
    public override void seal(){ } // 오버라이딩 금지되었음에도 시도하여 이 부분에서 컴파일 에러가 발생함
}
 

7. 읽기전용(readonly)

> const 키워드와 비슷처럼 한번 값을 지정 후 변경할 수 없는 것이 특징임

private readonly int num;

 

8. 확장 메서드

> 확장 메서드는 클래스 및 형식에 메서드를 추가하는 것을 의미함

namespace 네임스페이스
{
    public static class 클래스 // static 키워드 필요함
    {
        public static 반환형식 메서드(this 형식 식별자, 매개변수) { // static 키워드 필요함

        }
    }
}
using System;

namespace Extension
{
    public static class AppendExtension
    {
        // 확장 메서드 정의
        public static string Append(this string str, string toAppend)
        {
            return str + toAppend;
        }
    }
}

> string이라는 클래스에 Append 라는 메서드를 사용자 정의로 추가할 수 있다.

 

9. 튜플

1) 명명되지 않은 튜플

var tuple = (123, 789); // var을 쓰는 이유는 컴파일러가 튜플을 알아서 해석할 수 있도록 하기 위함

> C# 컴파일러는 명명되지 않은 튜플을 저장할 때 item1 부터 인덱스를 붙여 순서대로 저장한다.

> item1 : 123, item2 : 789 가 되는 것

2) 명명된 튜플

var tuple = (firstNum : 123, secondNum : 789);

3) 분해

> 인수가 같아야 함

var tuple = (firstNum : 123, secondNum : 789);
var (thirdNum, fourthNum) = tuple;

> thirdNum : 123, fourthNum : 789 가 됨


Chapter08. 인터페이스와 추상 클래스

1. 인터페이스(Interface)

1) 인터페이스?

> 인터페이스는 다른 파생클래스들의 상속대상이 될 수 있으며, 다른 파생클래스들이 지켜야 할 약속들을 사전에 정의해놓고 파생클래스들이 재정의하도록 강제 시킨다.

> 여기서 지켜야 할 약속들은 인터페이스가 정의한 멤버를 반드시 구현해야 한다는 약속이다.

2) 기본사용

interface 인터페이스
{
메서드
메서드
...
}
interface ILogger
{
    void WriteLog(string message);
}

▲ 위 처럼 정의할 수 있다.

ILogger logger = new ILogger() // (x)
ILogger logger = new ConsoleLogger(); // (o), ConsoleLogger은 ILogger 인터페이스를 상속하는 파생 클래스

▲ 위 처럼 인터페이스는 직접 객체를 생성할 수는 없지만 참조는 만들 수 있다.

3) 파생 클래스에서 사용

interface ILogger // 인터페이스 ILogger
{
    void WriteLog(string message); // 사전에 정의한 WriteLog 메서드
}

class ConsoleLogger : ILogger // 인터페이스 ILogger를 상속하는 ConsoleLogger 클래스
{
    // 인터페이스가 정의한 약속들을 구현할 의무가 있는 ConsoleLogger 클래스는 WirteLog 메서드를 목적에 맞게 정의한다.
    public void WirteLog(string message)
    {
        Console.WriteLine("{0} {1}", DateTime.Now.ToLocalTime(), message);
    }
}

class ClimateMonitor
{
    // ClimateMonitor 클래스는 인터페이스인 ILogger형 객체를 가지고 초기화를 진행한다
    private ILogger logger;
    public ClimateMonitor(ILogger logger)
    {
        this.logger = logger;
    }
    public void start()
    {
        while(true)
        {
            Console.Write("온도를 입력하세요 : ");
            string temperature = Console.ReadLine();
            if(temperature == "") break;

            logger.WriteLog("현재 온도 : " + temperature);
        }
    }
}
ClkimateMonitor monitor = new ClimateMonitor(new ConsoleLogger()); // ILogger logger = new ConsoleLogger()
monitor.start(); // start() 함수에서 logger.WriteLog는 ConsoleLogger 클래스 안의 WriteLog 메서드가 됨

4) 의문점

> 그냥 클래스에 정의하고 쓰면 되는 거 아닌가? 라는 의문점이 많이 들었다.

> 하지만 아래와 같은 사례로 인터페이스는 유용하다.

class ClimateMonitor{
    private ConsoleLogger logger;
    public ClimateMonitor(ConsoleLogger logger){
        this.logger = logger;
    }
}

▲ 위 처럼 정의하면 ClimateMonitor는 ConsoleLogger 형 객체만을 사용하는 단순한 클래스가 된다.

 

반면

class ClimateMonitor {
    private ILogger logger;

    public ClimateMonitor(ILogger logger) {
        this.logger = logger;
    }
}

▲ 위 처럼 정의하면 ClimateMonitor는 ConsoleLogger 형 뿐만 아니라 인터페이스를 상속하여 앞으로 확장할 수 있는 FileLogger, DbLogger 등 여러가지 형의 객체도 받아들일 수 있는 상태가 된다.

> 따라서 인터페이스는 원하는 동작을 약속해놓고, 이를 상속한 파생 클래스들의 목적에 따라 다른 로직으로 분기시키기 위해서 사용된다.

> 같은 이름의 메서드(=> WriteLog)지만 파생 클래스마다 다른 행동을 가지고 있는 메서드(=> ConsoleLogger의 WirteLog / FileLogger의 WriteLog)는 어떤 클래스로 초기화했느냐에 따라(=> ILogger logger = new ConsoleLogger / ILogger logger = new FileLogger) 전혀 다른 결과를 만들어내는 것이다.

> 이는 같은 WriteLog 호출이지만 실제 동작은 객체 종류에 따라 달라진다는 다형성을 충족시킨다.

 

2. 추상 클래스(abstract class)

1) 추상 클래스?

> 추상 클래스는 인터페이스처럼 약속을 정의하고, 상속하는 파생 클래스들에게 강제시킬 수 있음과 동시에 클래스와 유사한 특징(기본 private 선언)을 가지는 클래스이다.

> 인터페이스는 기본적으로 public 선언이 되는 것과 차이점이 있다.

> 하지만 기본적인 private 선언 때문에 파생 클래스들이 접근을 할 수 없다면 약속의 의미가 없으므로, C#에서는 public, proteced 등의 한정자 중 하나로 수식을 할 것을 강요한다.

2) 사용법

abstract class 클래스
{
    // 필드
    // 메서드
}
abstract class AbstractBase
{
    public abstract void SomeMethod(); // 추상 클래스의 메서드도 abstract 한정자를 사용해야 함.
}

class Derived : AbstractBase // 추상 클래스 AbstractBase를 상속하는 Derived 파생 클래스
{
    public override void SomeMethod(){} // 약속이 강제되어 SomeMethod 메서드를 오버라이드해서 재정의함.
}

'LMS 7 > 개발일지' 카테고리의 다른 글

25.09.29 개발일지 / C# 2(3) (Chapter11, Chapter12)  (0) 2025.11.11
25.09.28 개발일지 / C# 2(2) (Chapter09, Chapter10)  (0) 2025.11.11
25.09.26 개발일지 / C# 1(1) (Chapter02~Chapter03)  (0) 2025.11.11
25.09.25 개발일지  (0) 2025.11.04
25.09.24 개발일지 / Windows Git  (0) 2025.11.04
'LMS 7/개발일지' 카테고리의 다른 글
  • 25.09.29 개발일지 / C# 2(3) (Chapter11, Chapter12)
  • 25.09.28 개발일지 / C# 2(2) (Chapter09, Chapter10)
  • 25.09.26 개발일지 / C# 1(1) (Chapter02~Chapter03)
  • 25.09.25 개발일지
m_Dev
m_Dev
  • m_Dev
    m_Dev
    m_Dev
  • 전체
    오늘
    어제
    • 분류 전체보기
      • MAIN STUDY
        • 정보보안
        • 빅데이터
        • 정보처리
        • 컴퓨터 구조
        • 기타
      • JOB
        • Study
        • Project
      • LMS 7
        • 개발일지
      • FRAMEWORK
        • Qt
        • MFC
        • Winform
        • WPF
        • MAUI
      • NETWORK
        • Study
        • Assignment
      • PYTHON
        • Set
        • Study
        • Assignment
        • Project
      • C
        • Set
        • Study
        • Assignment
        • Project
      • C++
        • Set
        • Study
        • Assignment
        • Project
      • C#
        • Set
        • Study
        • Assignment
        • Project
      • DATABASE
        • MySQL
        • SQLite
      • IDE
        • VisualStudioCode
        • VisualStudio
        • Pycharm
        • Colab
      • 기타
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.4
m_Dev
25.09.27 개발일지 / C# 2(1) (Chapter07, Chapter08)
상단으로

티스토리툴바