// 상속 종료자
using System;
namespace Inheritance
{
class Base
{
protected string Name;
public Base(string Name)
{
this.Name = Name;
Console.WriteLine($"{this.Name}.Base()");
}
~Base()
{
Console.WriteLine($"{this.Name}.-Base()");
}
public void BaseMethod()
{
Console.WriteLine($"{Name}.BaseMethod()");
}
}
class Derived : Base
{
public Derived(string Name) : base(Name)
{
Console.WriteLine($"{this.Name}.Derived()");
}
~Derived()
{
Console.WriteLine($"{this.Name}.-Derived()");
}
public void DerivedMethod()
{
Console.WriteLine($"{Name}.DerivedMethod()");
}
}
class MainApp
{
static void Main(string[] args)
{
Base a = new Base("a");
a.BaseMethod();
Derived b = new Derived("b");
b.BaseMethod();
b.DerivedMethod();
}
}
}

상속 종료자
// 클래스 is as 연산자
using System;
namespace TypeCasting
{
class Mammal
{
public void Nurse()
{
Console.WriteLine("Nurse()");
}
}
class Dog : Mammal
{
public void Bark()
{
Console.WriteLine("Bark()");
}
}
class Cat : Mammal
{
public void Meow()
{
Console.WriteLine("Meow()");
}
}
class MainApp
{
static void Main(string[] args)
{
Mammal mammal = new Dog();
Dog dog;
if (mammal is Dog)
{
dog = (Dog)mammal;
dog.Bark();
}
Mammal mammal2 = new Cat();
Cat cat = mammal2 as Cat;
if (cat != null)
cat.Meow();
Cat cat2 = mammal as Cat;
if (cat2 != null)
cat2.Meow();
else
Console.WriteLine("cat2 is not a Cat");
}
}
}
클래스 자료형을 비교연산자로 활용하는 is as문

// 오버라이딩 형식
using System;
namespace Overriding
{
class ArmorSuite
{
public virtual void Initialize()
{
Console.WriteLine("Armored");
}
}
class IronMan : ArmorSuite
{
public override void Initialize()
{
base.Initialize();
Console.WriteLine("Repulsor Rays Armed");
}
}
class WarMachine : ArmorSuite
{
public override void Initialize()
{
base.Initialize();
Console.WriteLine("Double-Barrel Cannons Armed");
Console.WriteLine("Micro-Rocket Launcher Armed");
}
}
class MainApp
{
static void Main(string[] args)
{
Console.WriteLine("Creating ArmorSuite...");
ArmorSuite armorsuite = new ArmorSuite();
armorsuite.Initialize();
Console.WriteLine("\nCreating IronMan...");
ArmorSuite ironman = new IronMan();
ironman.Initialize();
Console.WriteLine("\nCreating WarMachine...");
ArmorSuite warmachine = new WarMachine();
warmachine.Initialize();
}
}
}
중요! 오버라이딩
버츄얼을 활용한 오버라이딩으로, 선언한 자료형을 쫓아가지 않는 오버라이딩 예제

// 메소드 숨기긱기
using System;
namespace MethodHiding
{
class Base
{
public void MyMethod()
{
Console.WriteLine("Base.MyMethod()");
}
}
class Derived : Base
{
public new void MyMethod()
{
Console.WriteLine("Derived.MyMethod()");
}
}
class MainApp
{
static void Main(string[] args)
{
Base baseObj = new Base();
baseObj.MyMethod();
Derived derivedObj = new Derived();
derivedObj.MyMethod();
Base baseOrDerived = new Derived();
baseOrDerived.MyMethod();
}
}
}

메소드 숨기기인데, 사실 이것도 오버라이딩이다. 버츄얼을 안 쓰면 이렇게 선언한 곳을 쫓아가서 함수를 보여준다.
// 봉인 메소드 sealed (실행 결과 없음)
using System;
namespace MethodHiding
{
class Base
{
public virtual void SealMe()
{
}
}
class Derived : Base
{
public sealed override SealMe()
{
}
}
class WantToOverride : Derived
{
public override void SealMe()
{
}
}
class MainApp
{
static void Main(string[] args)
{
}
}
}
프라이빗처럼 상속되지 않는 sealed 기능
봉인된 메소드가 있다고 하며 출력 오류문이 뜬다.
// 구조체
using System;
namespace Structure
{
struct Point3D
{
public int x, y, z;
public Point3D(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public override string ToString()
{
return string.Format($"{x}, {y}, {z}");
}
}
class MainApp
{
static void Main(string[] args)
{
Point3D p3d1;
p3d1.x = 10;
p3d1.y = 20;
p3d1.z = 40;
Console.WriteLine(p3d1.ToString());
Point3D p3d2 = new Point3D(100, 200, 300);
Point3D p3d3 = p3d2;
p3d3.z = 400;
Console.WriteLine(p3d2.ToString());
Console.WriteLine(p3d3.ToString());
}
}
}

구조체의 형태
여기서는 구조체에서도 퍼블릭을 쓸 수 있던데, 그래도 클래스와는 다른 점이 있는게 클래스는 값을 참조한다는 것과 구조체는 상속이 불가능하다는 점이 있다.

사진 설명을 입력하세요.
// 인터페이스
using System;
using System.IO;
namespace Interface
{
interface ILogger
{
void WriteLog(string message);
}
class ConsoleLogger : ILogger
{
public void WriteLog(string message)
{
Console.WriteLine(
"{0} {1}",
DateTime.Now.ToLocalTime(), message);
}
}
class FileLogger : ILogger
{
private StreamWriter writer;
public FileLogger(string path)
{
writer = File.CreateText(path);
writer.AutoFlush = true;
}
public void WriteLog(string message)
{
writer.WriteLine("{0} {1}", DateTime.Now.ToShortTimeString(), message);
}
}
class ClimateMonitor
{
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);
}
}
}
class MainApp
{
static void Main(string[] args)
{
ClimateMonitor monitor = new ClimateMonitor(
new FileLogger("MyLog.txt"));
monitor.start();
}
}
}
인터페이스 기능
위 코드는 입력한 값을 파일에 넣는다.


bin 파일에 들어가보면 텍스트 파일이 만들어져있는 걸 볼 수 있다.
// 프로퍼티
using System;
namespace Property
{
class BirthdayInfo
{
private string name;
private DateTime birthday;
public string Name
{
get { return name; }
set { name = value; }
}
public DateTime Birthday
{
get { return birthday; }
set { birthday = value; }
}
public int Age
{
get
{
return new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year;
}
}
}
class MainApp
{
static void Main(string[] args)
{
BirthdayInfo birth = new BirthdayInfo();
birth.Name = "서현";
birth.Birthday = new DateTime(1991, 6, 28);
Console.WriteLine($"Name : {birth.Name}");
Console.WriteLine($"Birthday : {birth.Birthday.ToShortDateString()}");
Console.WriteLine($"Name : {birth.Age}");
}
}
}

프로퍼티는 접근 불가능한 프라이빗에 접근해서 값을 수정할 수 있게 해주는 기능이다.
퍼블릭을 남용하지 않아도 될 것 같다.
과제 진행도
using System;
using System.Runtime.InteropServices;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace DYclass
{
// 대장로 클래스
class Search
{
// 프라이빗 변수
private string input;
private string number;
private Dictionary<int, string> List = new Dictionary<int, string>()
{
{0, "종료"},
{1, "구황작물"},
{2, "600족 포켓몬"}
};
// 생성자
public Search()
{
this.input = "";
}
// 메소드
public void Menu()
{
Console.WriteLine($"보고 싶은 메뉴를 선택해");
Console.WriteLine($"-------------------------");
foreach(KeyValuePair<int, string> item in List)
{
Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
}
}
public string Search_choice()
{
while (true)
{
number = Console.ReadLine();
foreach (int Key in List.Keys)
{
string stringKey = Key.ToString();
if (stringKey == number)
{
return (string)List[Key];
}
}
Console.WriteLine("다시 선택");
}
}
}
class Food
{
// 프라이빗 변수
private string number;
private string Name;
private int Cal;
private Dictionary<int, string> List = new Dictionary<int, string>()
{
{0, "뒤로가기"},
{1, "고구마"},
{2, "감자"},
{3, "옥수수"},
{4, "콩"},
{5, "조"},
{6, "토란"},
{7, "칡"},
{8, "메밀"}
};
private string choice;
// 생성자
public Food()
{
this.Name = "선택되지 않음";
this.Cal = 0;
}
// 메소드
public void Menu()
{
Console.WriteLine($"보고 싶은 메뉴를 선택해");
Console.WriteLine($"-------------------------");
foreach (KeyValuePair<int, string> item in List)
{
Console.WriteLine("[{0}:{1}]", item.Key, item.Value);
}
Console.WriteLine($"-------------------------");
}
public virtual void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
public string Food_choice()
{
while (true)
{
number = Console.ReadLine();
foreach (int Key in List.Keys)
{
string stringKey = Key.ToString();
if (stringKey == number)
{
return (string)List[Key];
}
}
Console.WriteLine("다시 선택");
}
}
}
제일 큰 분류의 클래스
딕셔너리도 써보고 뭔가 새롭게 구조를 짜보고 싶어서 클래스 내에서 값을 받아서 리턴하는 형식으로 해봄
class SweetPotato : Food
{
private string Name;
private int Cal;
public SweetPotato()
{
this.Name = "고구마";
this.Cal = 130;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Potato : Food
{
private string Name;
private int Cal;
public Potato()
{
this.Name = "감자";
this.Cal = 77;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Corn : Food
{
private string Name;
private int Cal;
public Corn()
{
this.Name = "옥수수";
this.Cal = 92;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Bean : Food
{
private string Name;
private int Cal;
public Bean()
{
this.Name = "콩";
this.Cal = 180;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Millet : Food
{
private string Name;
private int Cal;
public Millet()
{
this.Name = "조";
this.Cal = 350;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Taro : Food
{
private string Name;
private int Cal;
public Taro()
{
this.Name = "토란";
this.Cal = 71;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Kudzu : Food
{
private string Name;
private int Cal;
public Kudzu()
{
this.Name = "칡";
this.Cal = 137;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
class Buckwheat : Food
{
private string Name;
private int Cal;
public Buckwheat()
{
this.Name = "메밀";
this.Cal = 281;
}
public override void Food_info()
{
Console.WriteLine($"음식 이름 : {Name}");
Console.WriteLine($"칼로리(100g) : {Cal}");
}
}
Food 클래스에서 상속 받은 자식 클래스들
음식들의 정보가 들어있고 다 오버라이딩 하는중
class MainApp
{
static void Main(string[] args)
{
Search search = new Search();
Food food = new Food(); // 클래스 호출
while (true)
{
search.Menu();
string selected = search.Search_choice();
if (selected == "종료")
{
break;
}
else if (selected == "구황작물")
{
while (true)
{
food.Menu();
food.Food_info();
string food_selected = food.Food_choice();
if (food_selected == "뒤로가기")
{
food = new Food(); // 부모 클래스 동적할당 해줌
break;
}
else if (food_selected == "고구마")
{
food = new SweetPotato(); // 고구마 데이터 동적할당
}
else if (food_selected == "감자")
{
food = new Potato(); // 감자 데이터 동적할당
}
else if (food_selected == "옥수수")
{
food = new Corn(); // 옥수수 데이터 동적할당
}
else if (food_selected == "콩")
{
food = new Bean(); // 콩 데이터 동적할당
}
else if (food_selected == "조")
{
food = new Millet(); // 조 데이터 동적할당
}
else if (food_selected == "토란")
{
food = new Taro(); // 토란 데이터 동적할당
}
else if (food_selected == "칡")
{
food = new Kudzu(); // 칡 데이터 동적할당
}
else if (food_selected == "메밀")
{
food = new Buckwheat(); // 메밀 데이터 동적할당
}
}
}
else if (selected == "600족 포켓몬")
{
continue;
}
}
}
}
}
메인쪽
조건문에 따라 동적할당을 다르게 해서 버츄얼 오버라이딩 활용
결과



일단 음식은 구현완료.
글을 작성하고 보니 clear 기능을 써서 깔끔하게 만들어야겠다.
'C#' 카테고리의 다른 글
LMS5_Project08 C# WPF 프로젝트 - Resource Monitoring Tool (0) | 2025.02.22 |
---|---|
C# WPF 데이터베이스 연결 (0) | 2025.02.05 |
C# 문제풀이 2 (0) | 2025.01.24 |
C# 문제풀이 1 (3) | 2025.01.24 |
C# 클래스 과제 마무리 (0) | 2025.01.24 |