ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 객체 지향 프로그래밍 (OOP)
    C# 2023. 8. 14. 17:00

    객체 지향 프로그래밍 (Object-Oriented Programming)

     : 컴퓨터 프로그램을 여러 명령어의 목록으로 보지 않고 여러 개의 독립된 객체들의 집합으로 파악하는 프로그래밍 기법.

     

     I. 객체, 클래스, 인스턴스

      A. 객체 (object)

      : 객체 지향 프로그래밍(OOP) 에서 클래스(class)가 실제로 구현된 인스턴스(instance)

        혹은 클래스(class)에서 구현하기 위한 추상적인 개념

     

      : 프로그램에서 사용되는 데이터 혹은 식별자에 의해 참조되는 공간

     

     

       ex) 고양이라는 개념

     

      B. 클래스 (class)

       : 객체 지향 프로그래밍(OOP)에서 특정 객체를 생성하기 위해 변수와 메소드를 정의하는 템플릿

       : 클래스에서는 해당 객체의 속성(state)는 변수(variable)로, 기능(behavior)은 메서드(method)로 정의함.

        ex) 고양이라는 객체를 프로그램상 나타내기 위해 변수와 메서드를 정의

        internal class Cat
        {
            // 속성 정의
            public string catName;                                 // 이름은 뭔지
            public string catSpecies;                              // 묘종은 뭔지..
            public string color;                                   // 색은 뭔지..
            public int catAge;                                     // 나이는 몇 살인지..
    
            // 기능 정의
            public void meow()                                    // 야옹하고 울기
            {
                Console.WriteLine("Meow!");
            }
    
            public void moving()
            {
                Console.WriteLine(catName + " is moving...");      // 이동하기
            }
    
    
            public void jump()
            {
                Console.WriteLine("...Jump!");                      // 점프하기
            }
        }

     

      C. 인스턴스 (instance)

       : 객체 지향 프로그래밍(OOP)에서 클래스에 소속된 개별적인 객체.

     

       : 정의된 클래스에 객체를 생성한 경우, 그 객체는 해당 클래스의 인스턴스가 된다.

       : 하나의 클래스를 사용하여 유사한 성질을 가진 수많은 인스턴스를 생성할 수 있다.

     

         ex) 고양이 "냬옹스(Nyeaons)"는 Cat 클래스의 인스턴스

    Nyeaons

        internal class Program
        {
            static void Main(string[] args)
            {
                Cat Nyeaons = new Cat();
                Nyeaons.catName = "Nyeaons";                     // 고양이의 이름은 냬옹스다.
                Nyeaons.catSpecies = "스코티시폴드";             // 묘종은 스코티시 폴드.
                Nyeaons.color = "티끌없는 화이트";               // 색깔은 티끌없는 화이트.
                Nyeaons.catAge = 5;                              // 나이는 5살.
    
                Console.WriteLine($"이 고양이의 이름은 {Nyeaons.catName}다. 묘종은 {Nyeaons.catSpecies}이며, {Nyeaons.color}색을 지닌 귀여운 고양이지");
                Console.WriteLine($"나이는 {Nyeaons.catAge.ToString()}살 이다");
                
                
                Console.WriteLine($"{Nyeaons.catName} 물어!");
                Nyeaons.moving();
                Nyeaons.jump();
                Nyeaons.meow();
    
            }
        }

    >

      ** 객체의 정의를 보면, "클래스(class)가 실제로 구현된 인스턴스(instance)". 즉, Nyeaons는 인스턴스이자 객체이다.

          개념의 혼동을 피하기 위해 chatGPT에 물어보았다..

     

    II. OOP의 4가지 속성

      A. 추상화 (Abstraction)

     : 프로그램으로 표현하기 위하여, 실제의 개념을 단순화하고 필요한 부분을 강조하여 표현하는 개념.

     

     !! 위에서 고양이에 대한 개념을

        속성(Property) : 고양이 이름, 묘종, 색깔, 나이의 데이터로 고양이의 정보를 표현

        메서드(Methods) : 우는 행동, 이동하는 것, 점프하는 것으로 고양이의 행동을 나타내는 기능을 표현함.

        internal class Cat
        {
            // 속성 정의
            public string catName;                                 // 이름은 뭔지
            public string catSpecies;                              // 묘종은 뭔지..
            public string color;                                   // 색은 뭔지..
            public int catAge;                                     // 나이는 몇 살인지..
    
            // 기능 정의
            public void meow()                                    // 야옹하고 울기
            {
                Console.WriteLine("Meow!");
            }
    
            public void moving()
            {
                Console.WriteLine(catName + " is moving...");      // 이동하기
            }
    
    
            public void jump()
            {
                Console.WriteLine("...Jump!");                      // 점프하기
            }
        }

     

      B. 캡슐화 (Encapuslation)

       : 데이터와 해당 데이터를 다루는 메서드를 하나의 단위로 묶어, 외부의 접근을 제어하고, 데이터를 보호하는 개념.

      

       !! 접근 제한자 (Access Modifier)
       : 객체 지향 프로그래밍에서 클래스의 멤버(필드, 메서드, 속성 등)에 대한 접근 권한을 지정하는 키워드
         
         1. public : 모든 외부의 접근을 허가함.
         2. private : 같은 클래스 내에서만 접근을 허가함.
         3. protected : 같은 클래스 내부와 파생 클래스에서 접근을 허가함.
         4. internal : 같은 **어셈블리 내에서 접근을 허가함.

          **어셈블리 (assembly)
           : NET 런타임 환경에서 실행할 수 있는 코드와 리소스, 메타데이터를 포장하고 배포하는 단위

     

         !! 위에서 고양이의 정보(데이터) 와 행동(메서드) 을 하나의 단위로 캡슐화(Cat 클래스) 하였고, 외부 코드(Main) 에서 Cat 클래스를 사용하여 고양이를 다룸.

     

      : 데이터의 보호를 위해서는 데이터의 선언을 필드로 직접 접근하기 보다는 속성(property) 으로 해야한다.

    internal class Cat
    {
        public string catName;     // !! 필드로 직접 접근하는 방식 : 외부 필드에서 변형이 가능하다.
        
        private string _catAge     // !! 속성으로 접근하는 방식 : 클래스 내에 _catAge 라는 속성을 추가.
        public string catAge       // !! 클래스 외부에서 private 필드에 접근하지 않고 속성을 통해 접근 가능해짐.
        {
            get { return _catAge; }
            set { _catAge = value; }
        }

     

      : 클래스의 속성을 통해, 외부에서 Cat 클래스의 인스턴스를 생성하거나 속성을 설정할 때, 원하는 방식으로 데이터 처리가 가능해진다.

    internal class Cat
    {
        public string catName;     // !! 필드로 직접 접근하는 방식 : 외부 필드에서 변형이 가능하다.
        
        private string _catAge     // !! 속성으로 접근하는 방식 : 클래스 내에 _catAge 라는 속성을 추가.
        public string catAge       // !! 클래스 외부에서 private 필드에 접근하지 않고 속성을 통해 접근 가능해짐.
        {
            get { return _catAge; }
            //set { _catAge = value; }
            set
            {
                if (value > 0)
                {
                    _catAge = value;
                }
                else
                {
                    console.WriteLine("유효하지 않는 나이입니다.");  // !! set 접근자의 조건문에 의해 나이가 잘못된 경우를 처리할 수 있게 됨.
                    _catAge = 99;
                }
            }
        }
    }

     

      C. 상속 (Inheritance)

      : 기존 클래스의 속성과 메서드를 새로운 클래스에서 재사용하거나 확장할 수 있게 해주는 개념.

     

      !! 고양이와 비슷한 맥락으로 강아지의 클래스를 만듦.

        internal class Dog
        {
            // 속성 정의
            private string name;
            public string Name                                  // 이름은 뭔지..
            {
                get { return name; }
                set { name = value; }
            }
    
    
            private string dogBreed;
            public string DogBreed                              // 견종은 뭔지..
            {
                get;                                            // !! 생략 가능함.
                set;
            }
    
    
            private string color;
            public string Color                                  // 색은 뭔지..
            {
                get;
                set;
            }
    
            
            private int age;
            public int Age                                       // 나이는 뭔지..
            {
                get { return age; }
                set
                {
                    if (value > 0)
                    {
                        age = value;
                    }
                    else
                    {
                        Console.WriteLine("유효하지 않은 나이입니다.");
                        age = 99;
                    }
                }
            }
            // 기능 정의
            public void bark()                                    // 왈!하고 울기
            {
                Console.WriteLine("Bark!");
            }
    
            public void moving()
            {
                Console.WriteLine(Name + " is moving...");        // 이동하기
            }
    
    
            public void jump()
            {
                Console.WriteLine("...Jump!");                    // 점프하기
            }
        }

    >

     !! 고양이 클래스와 비교해보았을 때, 다음의 클래스 멤버는 공통적으로 사용이 가능함을 알 수 있다.

           속성 : 이름, 나이, 색
           메서드 : 이동, 점프

     !! 고양이와 강아지의 개념의 공통점은 동물이라는 점이다.

     

    ==> 해당하는 공유가능한 속성과 메서드를 상위 클래스(Animal) 로 추상화 시킨다면, 상위 클래스로부터 확장된 여러 개의 하위 클래스(Dog, Cat)에서 해당 속성과 메서드들을 간편하게 사용할 수 있다.

     

    class Animal
    {
        // properties
        private string name;
        public string Name
        {
            get;
            set;
        }
    
        private string color;
        public string Color
        {
            get;
            set;
        }
        
        private string age;
        public string Age
        {
            get;
            set;
        }
        
        // methods
        public void moving()
        {
            Console.WriteLine($"{Name}이 움직이기 시작합니다."};
        }
        
        
        public void jump()
        {
            Console.WriteLine("...JUMP!"};
        }
    }

     

     

      !! 하위 클래스의 선언은 하위 클래스 : 상위 클래스 로 하여, 상속이 이루어지게 한다.

        internal class Dog : Animal
        {
            // properties
            private string dogBreed;
            public string DogBreed                              // 견종은 뭔지..
            {
                get;                                            // !! 생략 가능함.
                set;
            }
    
            // methods
            public void bark()                                    // 왈!하고 울기
            {
                Console.WriteLine("Bark!");
                Console.WriteLine($"{Name}은 발랄하게 가서 물었다");
            }
        }
        
        
        internal class Cat : Animal
        {
            // properties
            private string _catSpecies;
            public string catSpecies                              // 묘종은 뭔지..
            {
                get;
                set;
            }
    
            // methods
            public void meow()                                    // 야옹하고 울기
            {
                Console.WriteLine("Meow!");
                Console.WriteLine("아무 일도 일어나지 않았다.");
            }
        }

     

     !! Main에서 실행

    Nyeaons & Mungs

        internal class Program
        {
            static void Main(string[] args)
            {
                Cat Nyeaons = new Cat();
                Nyeaons.Name = "Nyeaons";                     // 고양이의 이름은 냬옹스다.
                Nyeaons.catSpecies = "스코티시폴드";          // 묘종은 스코티시 폴드.
                Nyeaons.Color = "티끌없는 화이트";            // 색깔은 티끌없는 화이트.
                Nyeaons.Age = 5;                              // 나이는 5살.
    
                Console.WriteLine($"이 고양이의 이름은 {Nyeaons.Name}다. 묘종은 {Nyeaons.catSpecies}이며, {Nyeaons.Color}색을 지닌 귀여운 고양이지");
                Console.WriteLine($"나이는 {Nyeaons.Age.ToString()}살 이다\n\n");
                
                
                Console.WriteLine($"{Nyeaons.Name} 물어!");
                Nyeaons.moving();
                Nyeaons.jump();
                Nyeaons.meow();
                Console.WriteLine("\n\n");
    
    
                Dog Mungs = new Dog();
                Mungs.Name = "Mungs";                         // 강아지의 이름은 멍스다.
                Mungs.DogBreed = "웰시코기";                  // 견종은 웰시코기
                Mungs.Color = "갓 구운 빵과 같은 풍부한 브라운"; // 색깔은 이하 동문
                Mungs.Age = 3;                                // 나이는 3살
    
                Console.WriteLine($"이 강아지의 이름은 {Mungs.Name}다. 견종은 {Mungs.DogBreed}이며, {Mungs.Color}색을 지닌 귀여운 강아지라구");
                Console.WriteLine($"나이는 {Mungs.Age.ToString()}살 이다\n\n");
    
                Console.WriteLine($"{Mungs.Name} 물어!");
                Mungs.moving();
                Mungs.jump();
                Mungs.bark();
                Console.WriteLine("\n\n");
            }
        }

    >

     

      D. 다형성 (Polymorphism)

    : 어떤 객체의 속성이나 기능이 그 맥락에 따라 다른 역할을 수행할수 있는 객체 지향의 특성

     

    메서드 오버라이딩 (Method Overriding)
    : 상속 관계에서 자식 클래스가 부모 클래스의 메서드를 재정의하여 사용하는 것.
    : 같은 이름의 기능이 다른 역할을 수행할 때 사용.

    ex) 위의 코드에서 고양이와 강아지에게 물어! 라고 시켰는데 다른 결과가 나옴. 이를 동일한 이름으로 재정의 한 후, 메서드 오버라이딩을 수행 했을 때.
    class Animal
    {
        // properties
        private string name;
        public string Name
        {
            get;
            set;
        }
        
        // methods
        public virtual void Command()                                     // 해당 메서드는 오버라이드 가능하다 선언.
        {
            Console.WriteLine("동물에게 명령해보았다.");
            Console.WriteLine($"{Name}이 움직이기 시작합니다.");
            Console.WriteLine("...JUMP!");
        }
    }
    
    class Dog : Animal
    {
        public override void Command()                                    // 왈!하고 울기
        { 
            Console.WriteLine($"{Name} 물어!");
            Console.WriteLine($"{Name}이 움직이기 시작합니다.");
            Console.WriteLine("...JUMP!");
            Console.WriteLine("Bark!");
            Console.WriteLine($"{Name}은 발랄하게 가서 물었다");
        }
    }
    
    class Cat : Animal
    {
        public override void Command()                                   // 야옹하고 울기
        {
            Console.WriteLine($"{Name} 물어!");
            Console.WriteLine($"{Name}이 움직이기 시작합니다.");
            Console.WriteLine("...JUMP!");
            Console.WriteLine("Meow!");
            Console.WriteLine("아무 일도 일어나지 않았다.");
        }
    }


    ==> Main에서 사용하는 명령 부분을 상당히 줄일 수 있었다.
            static void Main(string[] args)
            {
                Cat Nyeaons = new Cat();
                Nyeaons.Name = "Nyeaons";                     // 고양이의 이름은 냬옹스다.
                Nyeaons.catSpecies = "스코티시폴드";          // 묘종은 스코티시 폴드.
                Nyeaons.Color = "티끌없는 화이트";            // 색깔은 티끌없는 화이트.
                Nyeaons.Age = 5;                              // 나이는 5살.
    
                Console.WriteLine($"이 고양이의 이름은 {Nyeaons.Name}다. 묘종은 {Nyeaons.catSpecies}이며, {Nyeaons.Color}색을 지닌 귀여운 고양이지");
                Console.WriteLine($"나이는 {Nyeaons.Age.ToString()}살 이다\n\n");
    
    
                Nyeaons.Command();
                /* 이하의 부분이 생략됨.
                Console.WriteLine($"{Name} 물어!");
                Console.WriteLine($"{Name}이 움직이기 시작합니다.");
                Console.WriteLine("...JUMP!");
                Console.WriteLine("Meow!");
                Console.WriteLine("아무 일도 일어나지 않았다.");
                Console.WriteLine("\n\n");
                */
                
                // 생략...​


    인터페이스 (Interface)
    : 메서드의 이름, 매개변수, 반환 유형만을 선언없이 정의함으로써, 상속받는 클래스에 해당 메서드를 강제함.
    : 다중 상속이 가능함.
    : 클래스 간의 관계를 유연하게 설계할 수 있음.

    ex) 각 동물의 소개를 Iintroduce라는 인터페이스를 활용하여 Main에 적용
        // 소개문 인터페이스
        internal interface Iintroduce
        {
            string Introduce();
        }
        
        internal class Dog : Animal, Iintroduce
        {
            //.. 생략
            
            public string Introduce()
            {
                return ($"이 강아지의 이름은 {Name}다. 견종은 {DogBreed}이며, {Color}색을 지닌 귀여운 강아지라구\n나이는 {Age.ToString()}살 이다\n\n");
            }
        }
        
        internal class Cat : Animal, Iintroduce
        {
            //.. 생략
            
            public string Introduce()
            {
                return ($"이 고양이의 이름은 {Name}다. 묘종은 {catSpecies}이며, {Color}색을 지닌 귀여운 고양이지\n나이는 {Age.ToString()}살 이다\n\n");
            }
        }​


    ==> 마찬가지로, main에서 일일히 적용시켜주지 않아도 됨.

        internal class Program
        {
            static void Main(string[] args)
            {
                Cat Nyeaons = new Cat();
                Nyeaons.Name = "Nyeaons";                     
                Nyeaons.catSpecies = "스코티시폴드";          
                Nyeaons.Color = "티끌없는 화이트";            
                Nyeaons.Age = 5;                              
    
                Console.WriteLine(Nyeaons.Introduce());       // 인터페이스로 인한 소개문 생략
                Nyeaons.Command();                            // 오버라이드로 인한 명령 부분 생략
    
    
                Dog Mungs = new Dog();
                Mungs.Name = "Mungs";                       
                Mungs.DogBreed = "웰시코기";                 
                Mungs.Color = "갓 구운 빵과 같은 풍부한 브라운";
                Mungs.Age = 3;                               
    
                Console.WriteLine(Mungs.Introduce());
                Mungs.Command();
            }
        }

    >

     

     

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

    조건문과 반복문  (0) 2023.08.15
    변수와 자료형  (0) 2023.08.15
    C# 개요  (0) 2023.08.14
    20230801-temp  (0) 2023.08.01
    20230726-임시  (0) 2023.07.26
Designed by Tistory.