컴퓨터/C#

[C#] 클래스 간의 형변환(implicit, explicit), 추상 클래스, 추상 메서드, 델리게이트

아기상어  2020. 6. 4. 16:43

클래스 간의 형변환

 

implicit 연산자

암시적 연산자 implicit operator로 오버로드 할수 있고 암시적, 명시적 형변환 둘다 가능하다.

 

 

explicit 연산자

명시적 연산자. 반드시 개발자가 의도한 형변환만 가능하도록 제한을 둘 수 있다.

 

 

 

 

예제) 'Yen'과 'Dollar'를 'Won'으로 implicit과 explicit을 이용하여 형변환 하기.

 

    public class Currency
    {
        decimal money;
        public decimal Money
        {
            get
            {
                return money;
            }
        }
        public Currency(decimal money)
        {
            this.money = money;
        }
    }

    public class Won : Currency
    {
        public Won(Decimal money) : base(money)
        {
        }

        public override string ToString()
        {
            return Money + "Won";
        }
    }

    public class Dollar : Currency
    {
        public Dollar(decimal money) : base(money)
        {

        }

        public override string ToString()
        {
            return Money + "Dollar";
        }

        static public explicit operator Won(Dollar dollar)
        {
            return new Won(dollar.Money * 1200m);
        }
    }

    public class Yen : Currency
    {
        public Yen(decimal money) : base(money)
        {

        }

        public override string ToString()
        {
            return Money + "Yen";
        }

        static public implicit operator Won(Yen yen)
        {
            return new Won(yen.Money * 13m);
        }
    }
            Won won = new Won(1000);
            Dollar dollar = new Dollar(1);
            Yen yen = new Yen(13);

            won = yen;
            won = (Won)yen; //  implicit은 암시적 명시적 변환 가능

            Console.WriteLine(won);

            // won = dollar;
            won = (Won)dollar;  //  explicit은 명시적 변환만 가능

            Console.WriteLine(won);

 

C#의 클래스 확장

 

추상 클래스

추상 - 실체가 없는

 

설계 가이드(창문은 네모로 다용도실 만들기) -> 설계 도면(창문 가로70cm, 세로 60cm)(클래스) -> 아파트(객체)

설계 가이드 = 추상클래스

 

필수적으로 가져야 할것들을 적어놓고 상속받아 두면 강제하게 할 수 있다.

ex)

[스마트폰]

-(전화하기)

-(앱실행하기)

-( ...)

 

예제)

    class Point
    {
        int x, y;

        public Point(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        public override string ToString()
        {
            return "X : " + x + ", Y : " + y;
        }
    }
    abstract class DrawingObject    // 추상 클래스
    {
        public abstract void Draw();    // 추상 메서드(코드 없는 가상 메서드)

        public void Move() { Console.WriteLine("Move"); }   //  일반메서드도 사용가능
    }

    class Line : DrawingObject
    {
        Point pt1, pt2;
        public Line(Point pt1, Point pt2)
        {
            this.pt1 = pt1;
            this.pt2 = pt2;
        }

        public override void Draw()
        {
            Console.WriteLine("Line " + pt1.ToString() + " ~ " + pt2.ToString());
        }
    }
            DrawingObject line = new Line(new Point(10, 10), new Point(20, 20));
            line.Draw();

 

델리게이트

메서드의 주소를 담을수 있는 메서드 참조 변수

메서드를 여러개 담아놓는 새로운 자료형이다.

메서드를 가리키는데 그 메서드와 시그니처가 같아야함.

+=, -= 연산자를 이용해 메서드를 델리게이트 인스턴스에 추가, 제거 할 수 있음

 

        delegate void CarDeal();    //  반환이 void이고 인자가 없는 메서드만 담김
        delegate void CarDeal2(int z);  //  반환이 void이고 인자가 1개만 있어야 담김

        static void Car()
        {
            Console.WriteLine("메뚜기");
        }

        static void ottogi()
        {
            Console.WriteLine("오뚜기");
        }
        static void Car2(int A)
        {
            Console.WriteLine("메뚜기2 인자값 = "+A);
        }

 

            Car();

            CarDeal Dealer; //  인자가 없는 메서드를 담는 델리게이트
            Dealer = Car;
            Console.Write("델리게이트 CarDeal : ");
            Dealer();//  메서드를 가리킴
            Dealer = ottogi;
            Console.Write("델리게이트 CarDeal : ");
            Dealer();

            CarDeal2 Dealer2;   //  인자가 1개인 메서드를 담는 델리게이트
            Dealer2 = Car2;
            Console.Write("델리게이트 CarDeal2 : ");
            Dealer2(100);

 

 

 

 

 

예제2) 델리게이트에 +=, -= 연산자 써보기

        delegate void CalcDelegate(int x, int y);

        static void Add(int x, int y) { Console.WriteLine(x + y); }
        static void Sub(int x, int y) { Console.WriteLine(x - y); }
        static void Mul(int x, int y) { Console.WriteLine(x * y); }
        static void Div(int x, int y) { Console.WriteLine(x / y); }
            CalcDelegate calc = Add;
            calc += Sub;
            calc += Mul;
            calc += Div;

            calc(10, 5);    //  Add,Sub,Mul,Div 호출

            calc -= Mul;
            calc(10, 5);    //  Add,Sub,DIv 호출

 

 

 

 

에제 3) 델리게이트를 제대로 써보기

 

    public class Mathmatics
    {
        delegate int CalcDelegate(int x, int y);

        static int Add(int x, int y)
        {
            return x + y;
        }
        static int Sub(int x, int y)
        {
            return x - y;
        }
        static int Mul(int x, int y)
        {
            return x * y;
        }
        static int Div(int x, int y)
        {
            return x / y;
        }

        CalcDelegate[] methods;

        public Mathmatics()
        {
            //static 메서드를가리키는 델리게이트 배열 초기화
            methods = new CalcDelegate[] { Mathmatics.Add,
                                            Mathmatics.Sub,
                                            Mathmatics.Mul,
                                            Mathmatics.Div };
        }

        public void Calculate(char opCode, int operand1, int operand2)
        {
            switch (opCode)
            {
                case '+':
                    Console.WriteLine("+: " + methods[0](operand1, operand2));
                    break;

                case '-':
                    Console.WriteLine("-: " + methods[1](operand1, operand2));
                    break;

                case '*':
                    Console.WriteLine("*: " + methods[2](operand1, operand2));
                    break;

                case '/':
                    Console.WriteLine("/: " + methods[3](operand1, operand2));
                    break;
            }
        }
    }
        delegate void WorkDelegate(char arg1, int arg2, int arg3);
        
        static void Main(string[] args)
        {
            Mathmatics math = new Mathmatics();
            WorkDelegate work = math.Calculate;

            work('+', 10, 5);
            work('-', 10, 5);
            work('*', 10, 5);
            work('/', 10, 5);
        }