본문 바로가기

내일배움캠프/꾸준CS과제

[TIL 24.07.05] 05. 상속과 인터페이스

.

 

목   차

     

    확인 문제

    using System;
    
    // 상위 클래스 A
    public class A
    {
        public virtual void Display()
        {
            Console.WriteLine("Class A Display");
        }
    }
    
    // 클래스 B는 클래스 A를 상속받음
    public class B : A
    {
        public override void Display()
        {
            Console.WriteLine("Class B Display");
        }
    }
    
    // 클래스 C는 클래스 A를 상속받음
    public class C : A
    {
        public override void Display()
        {
            Console.WriteLine("Class C Display");
        }
    }

     

    1. 위와 같은 코드에서, 다음과 같이 다중 상속을 하는 것이 가능할까요? 가능/불가능하다면 이유는 무엇일까요?

    public class D : B, C
    {
        
    }

    불가능하다. C#에서는 클래스의 다중상속을 지원하지 않는다. 

    2. 만약 C#에서 다중 상속이 지원되었다면, 클래스 D는 어떤 문제에 직면하게 될까요?

    B 클래스와 C 클래스는 A 클래스를 공통의 부모로 두고 있고, 각각 Display 메서드를 오버라이딩하고 있다.

    이 상황에서 D 클래스가 B와 C를 동시에 상속받는다면, Display 메서드를 오버라이드할 때 어느 클래스의 것을 기준으로 해야 할지 모호해진다.

    이 모호성은 코드의 예측가능성을 떨어트리고, 유지보수가 어렵게 하며 잠재적 버그를 초래할 수 있다.


     

    설명 문제

    1. 클래스를 다른 클래스로 상속하기 위한 방법은 무엇인가요?

    자식클래스의 이름 옆에 콜론을 달고 그 다음 상속할 클래스의 이름을 적는다.

    ex) public class ChildClass : ParentClass

    2. 클래스 상속에서 다이아몬드 문제(diamond problem)가 발생하는 이유와 이를 해결하는 방법에 대해 설명해주세요.

    다이아몬드 문제는 같은 부모를 둔 자식클래스들을 다시 하나의 클래스가 동시에 상속받는 데에서 발생한다. 

    클래스의 다중상속을 금지하면 이 문제는 발생하지 않는다.

     

    3. 인터페이스란 무엇인가요?

    인터페이스는 구현을 제공하지 않되 상속받는 클래스에게 특정 메서드의 구현을 강제하는 코드이다. 다만, C# 8.0 이후로 default 메서드 구현이 가능해졌다. 이 메서드는 자식에서 수정할 수 없다. 

    4. 인터페이스와 추상클래스의 차이는 무엇인가요?

    인터페이스는 기본적으로 메서드의 구현을 제공하지 않고, 필드도 가지지 않는다. 다만, 프로퍼티를 가질 수는 있다. 

    인터페이스는 다중 상속이 가능하다.

     

    추상 클래스는 구현이 포함될 수 있으며, 추상 메서드가 아닌 다른 메서드 또는 필드 역시 있을 수 있다.

    추상 클래스는 다중 상속이 불가능하다.


     

    실습 문제

    
    namespace _05.상속과_인터페이스_실습
    {
        interface ILogger
        {
            void WriteLog(string message);
            void WriteError(string error)
            {
                WriteLog($"Error: {error}");
            }
        }
    
        class ConsoleLogger : ILogger
        {
            // TODO : ConsoleLogger가 현재 시간과 메시지를 콘솔에 출력하는 기능을 추가
            // HINT : DateTime.Now.ToLocalTime() 함수를 이용합니다.
            public void WriteLog(string message)
            {
                Console.WriteLine(DateTime.Now.ToLocalTime() + message);
            }
        }
    
        class FileLogger : ILogger
        {
            private StreamWriter writer;
    
            public FileLogger(string path)
            {
                writer = File.CreateText(path);
                writer.AutoFlush = true;
            }
    
            // TODO : FileLogger가 현재 시간과 메시지를 파일에 기록하는 기능을 추가
            // HINT : writer.WriteLine() 함수를 이용합니다.
            public void WriteLog(string message)
            {
                writer.WriteLine(DateTime.Now.ToLocalTime() + message);
            }
        }
    
        class ClimateMonitor
        {
            private List<ILogger> loggers = new List<ILogger>();
    
            // TODO : ConsoleLogger또는 FileLogger의 기능을 가질 수 있는 ClimateMonitor를 작성
            public ClimateMonitor(ILogger logger)
            {
                loggers.Add(logger);
            }
    
            public void AddLogger(ILogger logger)
            {
                loggers.Add(logger);
            }
    
    
            public void Start()
            {
                while (true)
                {
                    Console.Write("온도를 입력해주세요. : ");
                    string temperature = Console.ReadLine();
                    if (temperature == "")
                    {
                        WriteAllError("공백을 입력받았습니다.");
                        break;
                    }
    
                    WriteAllLog("현재 온도 : " + temperature);
                }
            }
    
            private void WriteAllLog(string message)
            {
                foreach (var logger in loggers)
                    logger.WriteLog(message);
            }
    
            private void WriteAllError(string error)
            {
                foreach (var logger in loggers)
                    logger.WriteError(error);
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                ClimateMonitor monitor = new ClimateMonitor(new ConsoleLogger());
                monitor.Start();
    
                Console.WriteLine("이제부터 파일에도 기록됩니다.");
    
                monitor.AddLogger(new FileLogger("MyLog.txt"));
                monitor.Start();
            }
        }
    }

    .