C#

C# 클래스와 객체

anvil925 2025. 2. 13. 21:03
728x90
반응형
using System;

class ClassAndObject
{
    // C# 클래스와 객체
    
    // 객체지향 프로그래밍(OOP)의 특징
    // 1. 캡슐화(Encapsulation)
        // - 객체의 속성(필드)과 행위(메서드)를 하나로 묶고, 실제 구현 내용 일부를 외부에 감추어 은닉한다.
        // - 정보 은닉을 통해 객체의 내부 데이터는 외부에서 직접 접근할 수 없고, 메서드를 통해서만 접근할 수 있다.
    // 2. 상속(Inheritance)
        // - 부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있게 하는 것
        // - 코드의 중복을 줄이고, 재사용성을 높인다.
        // - 부모 클래스를 상속받은 자식 클래스는 부모 클래스의 멤버를 사용할 수 있지만, 부모 클래스는 자식 클래스의 멤버를 사용할 수 없다.
    // 3. 다형성(Polymorphism)
        // - 하나의 메서드나 클래스가 다양한 방식으로 동작하는 것
        // - 오버로딩(Overloading) : 같은 이름의 메서드를 매개변수의 타입이나 개수를 다르게 하여 여러 개 정의하는 것
        // - 오버라이딩(Overriding) : 상속 관계에서 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것
    // 4. 추상화(Abstraction)
        // - 복잡한 현실 세계를 단순화시켜 모델링하는 것
        // - 객체의 공통된 특성을 추출하여 클래스로 선언하는 것
    // 5. 클래스(Class)와 객체(Object)
        // - 클래스 : 객체를 만들기 위한 설계도
        // - 객체 : 클래스를 기반으로 만들어진 실체
        // - 클래스로부터 객체를 생성하는 과정을 인스턴스화(Instantiation)라고 한다.
    
    // 클래스의 구성 요소
    // 1. 필드(Field) : 클래스에 포함된 변수
    // 2. 메서드(Method) : 클래스에 포함된 함수
    // 3. 생성자(Constructor) : 객체가 생성될 때 호출되는 메서드
    // 4. 속성(Property) : 객체의 필드를 읽거나 쓰는 메서드

    // 클래스란 무엇인가?
    // - 객체를 생성하기 위한 설계도
    // - 객체의 속성과 행위를 정의한 것
    // - 객체를 생성하기 위한 틀

    // 객체란 무엇인가?
    // - 클래스를 기반으로 만들어진 실체
    // - 클래스의 인스턴스
    // - 객체는 속성과 행위를 가진다.

    // 구조체 vs 클래스
    // - 구조체 : 값 형식, 스택에 할당, 상속 불가능, 구조체 변수는 new 연산자를 사용하지 않고 생성
    // - 클래스 : 참조 형식, 힙에 할당, 상속 가능, 클래스 변수는 new 연산자를 사용하여 생성

    // 접근 제한자(Access Modifier)
    // - public : 모든 곳에서 접근 가능
    // - protected : 같은 클래스 또는 파생 클래스에서만 접근 가능
    // - internal : 같은 어셈블리(어셈블리란 컴파일된 코드를 포함하는 단위)에서만 접근 가능
    // - protected internal : 같은 어셈블리에서만 접근 가능하거나 파생 클래스에서만 접근 가능
    // - private : 같은 클래스에서만 접근 가능
    // - private protected : 같은 클래스 또는 파생 클래스에서만 접근 가능

    // 필드와 메서드
    // - 필드 : 클래스에 포함된 변수
    // - 메서드 : 클래스에 포함된 함수
    // - 필드와 메서드는 클래스의 멤버(Member)라고 한다.
    // - 필드는 객체의 상태를 나타내는 데이터이고, 메서드는 객체의 동작을 나타내는 함수이다.
    
    //필드(Field)
    // - 클래스에 포함된 변수
    // - 객체의 상태를 나타내는 데이터
    // - 필드는 클래스의 멤버이므로 클래스 내부에서 선언되어야 한다.
    // - 필드는 생성자, 메서드에서 사용할 수 있다.
    // - 보통 필드는 private으로 선언하여 외부에서 직접 접근하지 못하도록 한다.

    // 필드 예제
    class Car
    {
        private string name;
        private string color;
        private int year;

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

        public string GetName()
        {
            return name;
        }

        public void SetColor(string newColor)
        {
            color = newColor;
        }

        public string GetColor()
        {
            return color;
        }

        public void SetYear(int newYear)
        {
            year = newYear;
        }

        public int GetYear()
        {
            return year;
        }
    }

    public static void TestField()
    {
        Car car = new Car();
        car.SetName("Sonata");
        car.SetColor("White");
        car.SetYear(2021);

        Console.WriteLine($"Name: {car.GetName()}, Color: {car.GetColor()}, Year: {car.GetYear()}");
    }

    // 메서드(Method)
    // - 클래스에 포함된 함수
    // - 객체의 동작을 나타내는 함수
    // - 메서드는 클래스의 멤버이므로 클래스 내부에서 선언되어야 한다.
    // - 메서드는 필드를 사용하여 객체의 동작을 구현한다.
    // - 보통 메서드는 public으로 선언하여 외부에서 호출할 수 있도록 한다.

    // 메서드 예제

    class Calculator
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public int Subtract(int a, int b)
        {
            return a - b;
        }

        public int Multiply(int a, int b)
        {
            return a * b;
        }

        public int Divide(int a, int b)
        {
            return a / b;
        }
    }

    public static void TestMethod()
    {
        Calculator calculator = new Calculator();
        Console.WriteLine(calculator.Add(3, 5));
        Console.WriteLine(calculator.Subtract(3, 5));
        Console.WriteLine(calculator.Multiply(3, 5));
        Console.WriteLine(calculator.Divide(3, 5));
    }

    // 생성자(Constructor)
    // - 객체가 생성될 때 호출되는 메서드
    // - 생성자는 클래스 이름과 동일하다.
    // - 생성자는 리턴 타입이 없다.
    // - 생성자는 객체의 초기화를 담당한다.
    // - 생성자는 객체가 생성될 때 필드를 초기화한다.
    // - 오버로딩(Overloading)을 통해 여러 개의 생성자를 정의할 수 있다.
    // - 디폴트 생성자(Default Constructor) : 매개변수가 없는 생성자
    // - 생성자를 정의하지 않으면 컴파일러가 디폴트 생성자를 자동으로 생성한다.

    // 생성자 예제
    class Person
    {
        private string name;
        private int age;

        // 매개변수가 없는 디폴트 생성자
        public Person()
        {
            name = "Unknown";
            age = 0;
        }

        // 매개변수를 받는 생성자
        public Person(string newName, int newAge)
        {
            name = newName;
            age = newAge;
            Console.WriteLine("Person 생성");
        }

        public void PrintInfo()
        {
            Console.WriteLine($"Name: {name}, Age: {age}");
        }
    }

    public static void TestOOP()
    {
        Person person1 = new Person();
        Person person2 = new Person("Tom", 28);
        person1.PrintInfo();
        person2.PrintInfo();
    }

    // 소멸자(Destructor)
    // - 객체가 소멸될 때 호출되는 메서드
    // - 소멸자는 클래스 이름 앞에 ~를 붙인다.
    // - 소멸자는 리턴 타입이 없다.
    // - 소멸자는 객체가 소멸될 때 필요한 정리 작업을 한다.
    // - 소멸자는 GC(Garbage Collector)에 의해 호출된다.
    // - 소멸자는 클래스당 하나만 정의할 수 있다.
    // - 소멸자는 생성자와 달리 매개변수를 가질 수 없다.
    // - 소멸자는 클래스 내부에서 직접 호출할 수 없다.
    // - 오버로딩(Overloading)을 통해 여러 개의 소멸자를 정의할 수 없다.
    // - 소멸자는 GC가 호출할 때만 실행되므로 객체가 소멸될 때 언제 실행될지 정확히 알 수 없다.

    // 소멸자 예제
    class Person2
    {
        private string name;
        private int age;

        public Person2(string newName, int newAge)
        {
            name = newName;
            age = newAge;
            Console.WriteLine("Person 생성");
        }

        ~Person2()
        {
            Console.WriteLine("Person 소멸");
        }

        public void PrintInfo()
        {
            Console.WriteLine($"Name: {name}, Age: {age}");
        }
    }

    public static void TestDestructor()
    {
        Person2 person = new Person2("Tom", 28);
        person.PrintInfo();
    }

    // 프로퍼티(Property)
    // - 객체의 필드를 읽거나 쓰는 메서드
    // - 필드를 외부에서 직접 접근하지 않고 프로퍼티를 통해 접근한다.
    // - 프로퍼티는 필드를 읽는 Getter와 필드를 쓰는 Setter로 구성된다.
    // - 프로퍼티는 필드를 읽거나 쓰는 것처럼 사용할 수 있지만, 실제로는 메서드이다.
    // - 프로퍼티는 필드를 읽거나 쓰는 로직을 추가할 수 있다.

    // 프로퍼티 예제
    class Student
    {
        private string name;
        private int age;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        public void PrintInfo()
        {
            Console.WriteLine($"Name: {name}, Age: {age}"); 
        }
    }

    public static void TestProperty()
    {
        Student student = new Student();
        student.Name = "Alice";
        student.Age = 20;
        student.PrintInfo();
    }

    // 인덱서(Indexer)
    // - 객체를 배열처럼 인덱스로 접근할 수 있게 하는 프로퍼티
    // - 인덱서는 this 키워드를 사용하여 정의한다.
    // - 인덱서는 배열처럼 인덱스를 사용하여 객체의 요소에 접근할 수 있다.
    // - 인덱서는 객체의 요소를 읽거나 쓰는 Getter와 Setter로 구성된다.
    // - 인덱서는 인덱스의 타입과 개수를 지정하여 정의한다.

    // 인덱서 예제
    class IndexerExample
    {
        private string[] names = new string[3];

        public string this[int index]
        {
            get { return names[index]; }
            set { names[index] = value; }
        }
    }

    public static void TestIndexer()
    {
        IndexerExample indexerExample = new IndexerExample();
        indexerExample[0] = "Alice";
        indexerExample[1] = "Bob";
        indexerExample[2] = "Charlie";

        for (int i = 0; i < 3; i++)
        {
            Console.WriteLine(indexerExample[i]);
        }
    }

    // 정적 멤버(Static Member)
    // - 클래스의 인스턴스와 관계없이 사용할 수 있는 멤버
    // - 정적 필드, 정적 메서드, 정적 생성자, 정적 클래스로 구성된다.
    // - 정적 멤버는 클래스 이름으로 접근한다.
    // - 정적 멤버는 객체를 생성하지 않고 사용할 수 있다.

    // 정적 필드(Static Field)
    // - 클래스의 인스턴스와 관계없이 사용할 수 있는 필드
    // - 정적 필드는 static 키워드로 선언한다.
    // - 정적 필드는 모든 객체가 공유한다.
    
    // 정적 필드 예제
    class StaticFieldExample
    {
        public static int count = 0;
    }

    public static void TestStaticField()
    {
        StaticFieldExample.count++;
        Console.WriteLine(StaticFieldExample.count);
    }

    // 정적 메서드(Static Method)
    // - 클래스의 인스턴스와 관계없이 사용할 수 있는 메서드
    // - 정적 메서드는 static 키워드로 선언한다.
    // - 정적 메서드는 객체를 생성하지 않고 사용할 수 있다.
    // - 정적 메서드는 객체의 상태를 변경하지 않는 메서드에 사용한다.

    // 정적 메서드 예제
    class StaticMethodExample
    {
        public static int Add(int a, int b)
        {
            return a + b;
        }
    }

    public static void TestStaticMethod()
    {
        Console.WriteLine(StaticMethodExample.Add(3, 5));
    }

    // 정적 생성자(Static Constructor)
    // - 클래스가 로드될 때 호출되는 생성자
    // - 정적 생성자는 static 키워드로 선언한다.
    // - 정적 생성자는 클래스가 로드될 때 한 번만 호출된다.
    // - 정적 생성자는 인스턴스 생성과 상관없이 호출된다.
    // - 정적 생성자는 클래스의 정적 멤버를 초기화하는 역할을 한다.
    // - 정적 생성자는 클래스당 하나만 정의할 수 있다.
    // - 정적 생성자는 인스턴스 생성과 상관없이 호출되므로 접근 제한자를 사용할 수 없다.

    // 정적 생성자 예제
    class StaticConstructorExample
    {
        public static int count;

        static StaticConstructorExample()
        {
            count = 0;
            Console.WriteLine("Static Constructor");
        }
    }

    public static void TestStaticConstructor()
    {
        Console.WriteLine(StaticConstructorExample.count);
    }

    // 정적 클래스(Static Class)
    // - 정적 멤버만 포함하는 클래스

    // 정적 클래스 예제
    static class StaticClassExample
    {
        public static int Add(int a, int b)
        {
            return a + b;
        }
    }

    public static void TestStaticClass()
    {
        Console.WriteLine(StaticClassExample.Add(3, 5));
    }

    // 상속(Inheritance)
    // - 부모 클래스의 속성과 메서드를 자식 클래스가 물려받아 사용할 수 있게 하는 것
    // - 코드의 중복을 줄이고, 재사용성을 높인다.
    // - 부모 클래스를 상속받은 자식 클래스는 부모 클래스의 멤버를 사용할 수 있지만, 부모 클래스는 자식 클래스의 멤버를 사용할 수 없다.
    // - 상속은 콜론(:)을 사용하여 정의한다.
    // - C#은 단일 상속만 지원한다.

    // 상속 예제
    class Animal
    {
        public void Eat()
        {
            Console.WriteLine("먹다");
        }

        public void Sleep()
        {
            Console.WriteLine("자다");
        }
    }

    class Dog : Animal
    {
        public void Bark()
        {
            Console.WriteLine("짖다");
        }
    }

    public static void TestInheritance()
    {
        Dog dog = new Dog();
        dog.Eat();
        dog.Sleep();
        dog.Bark();
    } 
}
728x90
반응형

'C#' 카테고리의 다른 글

C# 인터페이스와 열거형  (0) 2025.03.03
C# 고급 문법과 기능  (0) 2025.02.20
C# 메서드(Method)와 구조체(Structures)  (0) 2025.02.11
C# 배열과 컬렉션  (1) 2025.02.10
C# 조건문과 반복문  (0) 2025.02.10