객체 지향 프로그래밍
코드 내의 모든 것을 객체(Object)로 표현하고자 하는 프로그래밍 패러다임
객체는 데이터(속성)와 기능(메소드)로 이루어짐
6장까지 다룬 내용으로는 절차적 프로그래밍 패러다임으로 코딩 가능
프로그램을 바라보는 관점
절차적 프로그래밍 코드의 순차적인 실행
객체지향 프로그래밍 객체 간의 상호 작용
클래스와 객체
클래스는 객체를 만들기 위한 청사진
클래스 객체
형식 또는 설계도 메모리에 적재된 실체
각 형식/클래스 별로 하나만 존재 이론적으로는 무한대로 생성 가능하며, 메모리를 차지함
객체가 어떤 데이터 항목을 가지는지 정의 선언된 데이터 항목에 실제 데이터 저장
어떤 메소드를 가질지를 정의 정의되어 있는 메소드를 실행
클래스 선언
class 키워드 이용
속성 -> 클래스의 변수 -> 필드(Field)
기능 -> 메소드
객체 생성
new 연산자와 생성자 이용
객체의 멤버(필드 및 메소드 등등)에 접근할 때는 .연산자 사용
생성자와 종료자
생성자 : 객체가 생성될 때 호출됨
종료자 : 객체가 소멸될 때 호출됨
생성자와 종료자의 명시적 구현은 선택 사항
this
접근한정자
오버라이딩
기반클래스에서 오버라이딩할 메소드를 virutual로
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | using System; namespace OOP001 { class Dog { public string Name; public string Color; // default 생성자(Constructor) public Dog() { } public Dog(string Name, string Color) { this.Name = Name; this.Color = Color; } public virtual void Bark() { Console.WriteLine("멍멍!!"); } // 오버로딩 public virtual void Bark(string direct) { Console.WriteLine($"{direct}방향을 향해 멍멍!!"); } } class Chiwawa : Dog { // 오버라이딩 public override void Bark() { Console.WriteLine("왈왈!!"); } } class Program { static void Main(string[] args) { Dog samy = new Dog(); samy.Name = "새미"; samy.Color = "하얀색"; samy.Bark(); Console.WriteLine($"{samy.Name} : {samy.Color}"); Console.WriteLine(); Dog bomi = new Dog(Name : "보미", Color : "핑크색"); bomi.Bark("동쪽"); Console.WriteLine($"{bomi.Name} : {bomi.Color}"); Console.WriteLine(); Chiwawa kei = new Chiwawa(); kei.Bark(); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | using System; namespace Quiz_Vehicle { class Vehicle { public virtual void run() { Console.WriteLine("차가 달린다."); } } class Taxi : Vehicle { public override void run() { Console.WriteLine("택시가 달린다."); } } class Truck : Vehicle { public override void run() { Console.WriteLine("트럭이 달린다."); } } class Bus : Vehicle { public override void run() { Console.WriteLine("버스가 달린다."); } } class Program { static void Main(string[] args) { Vehicle vehicle = new Vehicle(); vehicle.run(); Taxi taxi = new Taxi(); taxi.run(); Truck truck = new Truck(); truck.run(); Bus bus = new Bus(); bus.run(); } } } | cs |
오버라이딩할 때 Alt + Enter -> 재정의 생성 -> 재정의할 메소드 클릭
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | using System; namespace Quiz_Vehicle { class Vehicle { public virtual void run() { Console.WriteLine("차가 달린다."); } } class Taxi : Vehicle { public override void run() { Console.WriteLine("택시가 달린다."); } } class Truck : Vehicle { public override void run() { Console.WriteLine("트럭이 달린다."); } } class Bus : Vehicle { public override void run() { Console.WriteLine("버스가 달린다."); } } class Program { static void Main(string[] args) { Vehicle vehicle = new Vehicle(); vehicle.run(); Taxi taxi = new Taxi(); taxi.run(); Truck truck = new Truck(); truck.run(); Bus bus = new Bus(); bus.run(); vehicle = new Taxi(); vehicle.run(); vehicle = new Truck(); vehicle.run(); vehicle = new Bus(); vehicle.run(); } } } | cs |
오버라이딩 봉인하기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | using System; namespace SealedMethod { class Vehicle { public virtual void Run() { Console.WriteLine("탈것이 달린다."); } } class Taxi : Vehicle { public sealed override void Run() // 재정의 불가 키워드 { } } //class SuperTaxi : Taxi //{ // public override void Run() // Error 발생 // { // Console.WriteLine("수퍼택시가 달린다."); // } //} class Program { static void Main(string[] args) { } } } | cs |
중첩 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | using System; using System.Collections.Generic; namespace NestedClass { // OuterClass class Configuration { // 멤버 변수 List<ItemValue> listConfig = new List<ItemValue>(); // 생성자가 없다. // 디폴트 생성자가 컴파일 시 자동으로 만들어집니다. // 멤버 메소드 public void SetConfig(string item, string value) { ItemValue iv = new ItemValue(); iv.SetValue(this, item, value); } public string GetConfig(string item) { foreach (ItemValue iv in listConfig) { if (iv.GetItem() == item) return iv.GetValue(); } return ""; } // Inner Class private class ItemValue { private string item; private string value; public void SetValue(Configuration config, string item, string value) { this.item = item; this.value = value; bool found = false; for (int i = 0; i < config.listConfig.Count; i++) { if (config.listConfig[i].item == item) { config.listConfig[i] = this; found = true; break; } } if (found == false) config.listConfig.Add(this); } public string GetItem() { return item; } public string GetValue() { return value; } } } class Program { static void Main(string[] args) { Configuration config = new Configuration(); config.SetConfig("Version", "V 5.0"); config.SetConfig("Size", "655,324 KB"); Console.WriteLine(config.GetConfig("Version")); Console.WriteLine(config.GetConfig("Size")); config.SetConfig("Version", "V 5.0.1"); Console.WriteLine(config.GetConfig("Version")); } } } | cs |
분할 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | using System; namespace PartialClasss_01 { partial class MyClass { public void Method() { Console.WriteLine("Method1"); } public void Method2() { Console.WriteLine("Method2"); } } partial class MyClass { public void Method3() { Console.WriteLine("Method3"); } public void Method4() { Console.WriteLine("Method4"); } } class Program { static void Main(string[] args) { MyClass mc = new MyClass(); mc.Method(); mc.Method2(); mc.Method3(); mc.Method4(); } } } | cs |
분할 클래스를 각각 하나의 파일로 분할
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PartialClasss_01 { partial class MyClass { public void Method() { Console.WriteLine("Method1"); } public void Method2() { Console.WriteLine("Method2"); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PartialClasss_01 { partial class MyClass { public void Method3() { Console.WriteLine("Method3"); } public void Method4() { Console.WriteLine("Method4"); } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using System; namespace PartialClasss_01 { class Program { static void Main(string[] args) { MyClass mc = new MyClass(); mc.Method(); mc.Method2(); mc.Method3(); mc.Method4(); } } } | cs |
확장 메소드
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | using System; using MyExtension; // using ~~~!!! namespace MyExtension { public static class IntegerExtension { public static int Square(this int myInt) { return myInt * myInt; } public static int Power(this int myInt, int exponent) { int result = myInt; for (int i = 1; i < exponent; i++) result = result * myInt; return result; } } } namespace ExtensionMethod { class Program { static void Main(string[] args) { Console.WriteLine(3.Square()); Console.WriteLine(3.Power(4)); Console.WriteLine(2.Power(10)); } } } | cs |
287페이지
튜플
파이썬에서는 튜플 변경 불가능, C#에서는 튜플 변경가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | using System; namespace TupleTest { class Program { /* * 튜플(Tuple) 여러 필드를 담을 수 있는 "구조체" * 프로그램 전체에 사용할 형식을 선언할 때가 아니라 * 즉석에서 사용할 복합 데이터 형식을 선언할 때 적합 */ static void Main(string[] args) { var a = ("슈퍼맨", 999); Console.WriteLine($"{a.Item1}:{a.Item2}"); a.Item1 = "홍길동"; a.Item2 = 800; Console.WriteLine($"{a.Item1}:{a.Item2}"); // 명명된 튜플 var b = (Name: "이순신", Age: 17); Console.WriteLine($"{b.Item1}:{b.Item2}"); // 분해 var (name, age) = b; Console.WriteLine($"{name}:{age}"); // 분해2 var (name2, age2) = ("박문수", 34); Console.WriteLine($"{name2}:{age2}"); // 명명된 튜플 = 명명되지 않은 튜플 b = a; Console.WriteLine($"{b.Name}:{b.Age}"); } } } | cs |
290페이지는 접어두고 문법이 강화되면 다시 돌아오기
293페이지 연습문제 2번
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | using System; namespace chap7_exam02 { class A { } class B:A { } class Program { static void Main(string[] args) { A a = new A(); B b = new B(); A c = new B(); // 가능합니다. // B d = new A(); // Error a = b; b = (B)a; // DownCasting } } } | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | using System; namespace OOP_003 { class Mammal { } class Dog:Mammal { } class Chiwawa : Dog { } class Program { static void Main(string[] args) { Mammal mammal = new Mammal(); Dog dog = new Dog(); Chiwawa chiwawa = new Chiwawa(); Dog dog2 = new Chiwawa(); Mammal mammal2 = new Dog(); Object obj1 = new Chiwawa(); Object obj2 = new Dog(); Object obj3 = new Mammal(); chiwawa = (Chiwawa)obj1; dog = (Dog)obj2; } } } | cs |
인터페이스, 추상클래스
인터페이스는 청사진
클래스는 객체의 청사진
인터페이스는 클래스의 청사진
인터페이스 선언하기
interface 키워드를 이용하여 선언
대개 interface의 I로 시작하는 이름으로 명명
인터페이스는 (기본적으로) 메소드 구현을 갖지 않음
인터페이스는 필드를 갖지 않음
인터페이스는 약속
인터페이스를 상속하는 실체 클래스는 반드시 인터페이스에서 선언된 메소드를 모두 구현해야 함
실체 클래스가 어떤 인터페이스의 파생클래스인지를 알고 있다면 그 클래스가 어떤 public 메소드를 제공하는지도 파악할 수 있음
인터페이스는 커넥터
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using System; namespace OOP_Interface_001 { // 상속은 is-a 관계 class Horse { } interface IWing { public void fly(); // interface에 만들어진 메소드는 무조건 자식 클래스에서 구현되어야 한다. } class Unicon : Horse, IWing { public void fly() { Console.WriteLine("날다"); } } class Program { static void Main(string[] args) { Unicon unicon = new Unicon(); unicon.fly(); } } } | cs |
인터페이스를 특별한 클래스라고 생각.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | 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 { // has-a 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 Program { static void Main(string[] args) { // FileLogger fileLogger = new FileLogger("MyLog.txt"); // 한 번만 사용할거라 변수를 생략함. ClimateMonitor monitor = new ClimateMonitor(new FileLogger("MyLog.txt")); monitor.start(); } } } | cs |
인터페이스도 상속 가능
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | using System; namespace OOP_interface_002 { class Horse { } interface IWing { public void fly(); } interface ITank { } interface ISuperTank : ITank { public void superRunnable(); } class Unicon : Horse, IWing { public void fly() { } } interface IAdvancedTank { public void superRunnable(); } class Semicon : Horse, ISuperTank { public void superRunnable() { throw new NotImplementedException(); } } class Program { static void Main(string[] args) { } } } | cs |
인터페이스 상속 교재에서는 307, 308페이지
현업에서 타 회사들과 같이 일할 때 코드를 덜어내고 추가할 때 인터페이스가 유용함.
여러 인터페이스 한 번에 상속하기
310페이지
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | using System; namespace MultiinterfaceInheritance { interface IRunnable { void Run(); } interface IFlyable { void Fly(); } class FlyingCar : IRunnable, IFlyable { public void Fly() { throw new NotImplementedException(); } public void Run() { throw new NotImplementedException(); } } class Program { static void Main(string[] args) { FlyingCar car = new FlyingCar(); car.Run(); car.Fly(); ///////////////////////////////// IRunnable runnable = car as IRunnable; runnable.Run(); IFlyable flyable = car as IFlyable; flyable.Fly(); } } } | cs |
추상 클래스 : 인터페이스와 클래스 사이
추상클래스 선언하기
abstract class 키워드를 이용하여 선언
구현체를 갖지 않는 메소드는 abstract 한정자로 수식
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | using System; namespace abstractClass { abstract class Shape { public abstract void Draw(); } class Rectangle : Shape { public override void Draw() { Console.WriteLine("사각형을 그리다."); } } class Triangle : Shape { public override void Draw() { Console.WriteLine("삼각형을 그리다."); } } class Circle : Shape { public override void Draw() { Console.WriteLine("원을 그리다."); } } class Program { static void Main(string[] args) { //Shape shape = new Shape(); // Error Circle c = new Circle(); c.Draw(); } } } | cs |
추상클래스는 강연결, 인터페이스는 유연
두 문법이 유사함.
인터페이스를 90% 정도로 많이 씀.
'C#' 카테고리의 다른 글
| 스마트팩토리 4주 15일차 C# 9일차 (0) | 2021.05.17 |
|---|---|
| 스마트팩토리 3주 14일차 C# 8일차 (0) | 2021.05.14 |
| 스마트팩토리 3주 12일차 C# 6일차 (0) | 2021.05.12 |
| 스마트팩토리 3주 11일차 C# 5일차 C# (0) | 2021.05.11 |
| 스마트팩토리 3주 10일차 C# 4일차 C# (0) | 2021.05.10 |




최근댓글