본문으로 바로가기
반응형

오버라이딩

오버로딩

void test( )    // 인자가 없는거는 보이드형임

void test(int A)

void test(string A)

이름은 같은데 인자값으로 비교한다.

 

오버라이딩

void test(int A)   // 부모

void test(int A)   // 자식

 

지난번 예제에서 오버라이드를 사용해보자.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_001
{
    class Mammal
    {
        public void Move()   //
        {
            Console.WriteLine("이동한다");
        }
    }
    class Lion : Mammal
    {
        public void Move()
        { 
            Console.WriteLine("네 발로 움직인다.");
        }
    }
    class Whale : Mammal
    {
        public void Move()
        {
            Console.WriteLine("수영한다.");
        }
    }
    class Human : Mammal
    {
        public void Move()
        {
            Console.WriteLine("두 발로 움직인다");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Mammal aMammal = new Mammal();
            aMammal.Move();
 
            aMammal = new Lion();   // 이렇게 해놓고 출력은 Mammal이 뜬다 그래서 버츄얼을 사용
            aMammal.Move();
 
            aMammal = new Whale();
            aMammal.Move();
 
            aMammal = new Human();
            aMammal.Move();
        }
}
}
cs

지난번 예제랑 다르게

Mammal one = new Mammal();

            one.Move();

 

            Lion lion = new Lion();

            lion.Move();

 

            Whale whale = new Whale();

            whale.Move();

 

            Human human = new Human();

            human.Move();

 

Main 코드부분에 

 

Mammal aMammal = new Mammal();

            aMammal.Move();

 

            aMammal = new Lion();  

            aMammal.Move();

 

            aMammal = new Whale();

            aMammal.Move();

 

            aMammal = new Human();

            aMammal.Move();

으로 수정된 것을 주목해보자. 이때 출력하면 '이동한다'만 4번 출력되는 것을 확인할 수 있다.

실행은 잘되는데 비쥬얼 스튜디오는 초록줄이뜨며 new 키워드를 사용하라고 추천한다
new를 적어둔 코드
new를 적어서 초록줄은 없앴지만 출력결과는 똑같다

 지금처럼 사용자가 메서드를 만들었는데 부모한테 있는 메서드가 동일하게 만들수도 있다. 예제를 VS에 붙여넣기를해서보면 각 Move()메서드에 초록줄이 그어져있는 것을 확인할 수 있다. 자식 타입이 부모 타입으로 형변환이 되긴했지만, 이때문에 Move()가 겹쳐서 동작이 의도하지 않은 동작을 할 수도있다. 즉, Main의 Lion을 봤을때 기본적으로 Lion 인스턴스가 이동했기 때문에 Lion 클래스의 Move가 호출 돼야하고 결과는 "네 발로 움직인다."가 출력됐어야하지만 그렇지 않았다.

 

 그래서 이걸 구분하기위해 가상 메서드(virtual method)라는 것이 제공된다. 일반 메서드를 가상 메서드로 바꾸려면 virtual이라는 예약어를 적어준다. 그리고 자식 클래스에서는 해당 메서드가 다형성을 띠도록 명시적으로 override 예약어를 지정해준다.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_001
{
    class Mammal
    {
        public virtual void Move()
        {
            Console.WriteLine("이동한다");
        }
    }
    class Lion : Mammal
    {
        public override void Move()
        { 
            Console.WriteLine("네 발로 움직인다.");
        }
    }
    class Whale : Mammal
    {
        public override void Move()
        {
            Console.WriteLine("수영한다.");
        }
    }
    class Human : Mammal
    {
        public override void Move()
        {
            Console.WriteLine("두 발로 움직인다");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Mammal aMammal = new Mammal();
            aMammal.Move();
 
            aMammal = new Lion(); 
            aMammal.Move();
 
            aMammal = new Whale();
            aMammal.Move();
 
            aMammal = new Human();
            aMammal.Move();
        }
}
}
cs

virtual이랑 override를 새로 추가한 것에 주목해보자

 

 초록줄이 있던 예제에서 정의한 Move메서드는 부모와 자식 클래스에서 이름만 같을뿐 전혀 상관없는 동작을 개별 클래스에서 정의한 것이었다. 하지만 virtual/override예약어를 적용함으로써 부모에서 정의한 Move라는 동작에 대해 자식 클래스의 인스턴스에 따라 다양하게 재정의(override)될 수 있었고, 인스턴스가 어떤 타입으로 형변환돼도 그 특징이 유지되는 것을 볼 수 있다. 이를 다형성의 한 사례로 메서드 오버라이드(method override)라고한다.

 

 override는 대신하겠다라고 번역되고, 부모가 없으면 에러가 난다.(override가 부모랑 구분지을라고했는데 이름이 다르면 오류가난다. 예를들어, Move( )가 아니라 Move1( )처럼 오타가 나면 new로 인식)

(C#에서 예약어는 파란색이라서 변수이름으로 쓸 수 없는것을 참고해보자)

 new를 적으면 존재하지않는 새로운 메서드를 만들겠다는 뜻임, Mammal의 무브는 new타입이다(object를 상속받는거임)

 

 virtual을 안쓰면 override를 쓰면 컴파일 오류가 나기때문에 new 예약어밖에 쓸 수 없다.(초록줄에 마우스를 갖다대서 확인해보자) 반대로, virtual을쓰면 new, override를 쓸 수 있다

 

 

virtual : 이 메서드는 객체 타입에 맞게 호출된다.

aMammal                   Mammal타입

ㅁ         ------>     ㅁ Mammal(Move)

       

                                 Lion 타입

                         ㅁ Lion  (Move)

                         ㅁ Mammal  (Move)

 

 

aMammal                 Mammal 타입

ㅁ         ---(x)--->     ㅁMammal(Move)

ㅡㅡㅡㅡㅡㅡ>            Lion타입

                         ㅁ Lion  Move(override)

                         ㅁ Mammal  Move(virtual)

 

virtual을 적으면 점의 왼쪽을 체크하지않고 힙이 무슨 타입인지 검사한다.

new 타입은 .왼쪽의 타입을 검사하기때문에 aMammal의 객체 타입은 Mammal이되고, 

aMammal = new Lion();

aMammal.Move();

 

virtual을 적었을때 .오른쪽을 검사하기때문에 Move()의 타입의 객체 타입은 Lion이 된다.

aMammal = new Lion();

aMammal.Move(); 

 

그래서 밑에 오버라이드를 출력하면 '이동한다'가 아닌 '네발로 이동한다'가 출력된다.

 

 

 

 

배열객체

aMammal이 Mammal에 속해있기때문에 다 묶어서 관리할 수 있다

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_002
{
    class Mammal
    {
        public virtual void Move()
        {
            Console.WriteLine("이동한다");
        }
    }
    class Lion : Mammal
    {
        public override void Move()
        {
            Console.WriteLine("네 발로 움직인다.");
        }
    }
    class Whale : Mammal
    {
        public override void Move()
        {
            Console.WriteLine("수영한다.");
        }
    }
    class Human : Mammal
    {
        public override void Move()
        {
            Console.WriteLine("두 발로 움직인다");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Mammal[] aMammal = new Mammal[4]
                                { new Mammal(),
                                  new Whale(),
                                  new Lion(),
                                  new Human() 
                                };
            foreach(Mammal Temp in aMammal)   // 객체가 100개가 되도 foreach 코드는 같다.
            {
                Temp.Move();
            }
 
            /*
            Mammal[] aMammal = new Mammal[4] 
                                { new Mammal(), 
                                  new Whale(), 
                                  new Lion(), 
                                  new Human() };
            aMammal[0].Move();
            aMammal[1].Move();
            aMammal[2].Move();
            aMammal[3].Move();
            */
 
            /*
            Mammal[] aMammal = new Mammal[4];   // 배열 4개 생성
            aMammal[0] = new Mammal();
            aMammal[1] = new Whale();
            aMammal[2] = new Lion();
            aMammal[3] = new Human();
            aMammal[0].Move();
            aMammal[1].Move();
            aMammal[2].Move();
            aMammal[3].Move();
            */
        }
    }
}
cs

Main부분에서 배열을 생성하는 부분을 지금까지 배운 문법들로 3가지로 해보았다. 같은 코드라도 효율적이게 짤 수 있는 코드를 더 생각해보자.

 

 

부모와 자식 클래스에서 동일한 이름의 메서드를 사용하려면 

(1) 메서드 오버라이드를 원하면 virtual/override를 사용

(2) 단순히 자식 클래스에서 동일한 이름의 메서드가 필요하면 new를 사용

(3) 아무것도 안쓰면 2번으로 간주한다.

 

base를 이용한 메서드 재사용

부모 클래스와 자식 클래스에 중복되는 코드를 줄일 수 있다.(base를 사용)

 

object 기본 메서드 확장

1. Tostring

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_005
{
    public 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;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Point pt = new Point(510);
            Console.WriteLine(pt.ToString());
        }
    }
}
 
cs

 

Tostring의 경우 클래스의 인스턴스 값을 적절하게 표현하는 내용으로 재정의하는 것이 보통이다. 위의 예제처럼 Tostring에서 X, Y 좌푯값을 출력하는 코드를 작성했다. 이렇게하면 로그를 남기거나 통합 개발 환경에서 디버깅할때 ToString에서 반환된 결과가 유용하게 쓰일 수 있다.

 

 

2. Equals

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_006
{
    class Book
    {
        decimal isbn13;
        string title;
        string contents;
 
        public Book(decimal isbn13, string title, string contents)
        {
            this.isbn13 = isbn13;
            this.title = title;
            this.contents = contents;
        }
        public override bool Equals(object obj)
        {
            if(obj == null)
            {
                return false;
            }
 
            Book book = obj as Book;
            if(book == null)
            {
                return false;
            }
            return this.isbn13 == book.isbn13;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Book book1 = new Book(9788998139018"리버스 엔지니어링 바이블""......");
            Book book2 = new Book(9788998139018"리버스 엔지니어링 바이블""......");
            Book book3 = new Book(9788992939409"파이썬 3.6 프로그래밍""......");
 
            Console.WriteLine("book1 == book2: " + book1.Equals(book2));
            Console.WriteLine("book1 == book3: " + book1.Equals(book3));
        }
    }
}
 
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_007
{
    class Mathmatics
    {
        public int Abs(int value)
        {
            return (value >= 0) ? value : -value;
        }
        public double Abs(double value)
        {
            return (value >= 0) ? value : -value;
        }
        public decimal Abs(decimal value)
        {
            return (value >= 0) ? value : -value;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Mathmatics math = new Mathmatics();
            Console.WriteLine(math.Abs(-5));
            Console.WriteLine(math.Abs(-10.052));
            Console.WriteLine(math.Abs(-20.01m));
        }
    }
}
 
cs

 첫번째 Console.WriteLine 메서드에서는 Abs 메서드가 반환하는 값의 타입이 int타입인 반면,두세 번째 호출에서는 각각 double, decimal 타입의 값이 Console.WriteLine 메서드로 반환되어 출력한다. 즉, Console.WriteLine도 다양한 타입의 값을 받을 수 있게 정의된 메서드 오버로드(method overload)의 한 예다. 이름이 같고 인자가 다르면 오버로딩이 되는 것을 볼 수 있는데, 이를 통해 사용자의 편의가 더 좋아질 수 있다.

 

 

연산자 오버로드

(자바에는 없다) 연산자를 오퍼레이터라고함

Mammal 타입의 Move메서드가 자식 클래스에서 동작 방식이 달라지는 것을 알아봤는데 메서드만 의미가 달라지는 것이 아니다. 연산자 역시 타입별로 재정의할 수 있는데, 대표적인 사례로 +(더하기)를 예로들어보자.

 

1
2
3
4
5
6
7
int n1 = 5;
int n2 = 10;
int sum = n1+n2 // sum 값은 15
 
string txt1 = "123";
string txt2 = "456";
Console.WriteLine(txt1 + txt2); // 출력결과 123456
cs

정수형 타입에는 정수 연산 '+'로 숫자값을 더해주는 반면, 문자열 타입에서는 말 그대로 문자열을 이어 붙이는 역할을 한다.

 

string 타입이 더하기 연산자를 재정의한 것처럼 우리가 만드는 어떠한 타입도 그렇게 할 수 있다. 실습을 위해 가게1, 가게2를 정의하고 가게1+가게2를 가게3으로 정의하는 예제를 들어보자.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_008
{
    class Market
    {
        public int iApple;
        public int iOrange;    
    }
    class Program
    {
        static void Main(string[] args)
        {
            Market 가게1 = new Market();
            Market 가게2 = new Market();
 
            가게1.iApple = 10;
            가게1.iOrange = 10;
 
            가게2.iApple = 100;
            가게2.iOrange = 100;
 
            Market 가게3 = new Market();
 
            가게3 = 가게1 + 가게2;
            가게3.iApple = 가게2.iApple + 가게1.iApple;
            가게3.iOrange = 가게2.iOrange + 가게1.iOrange;
 
            Console.WriteLine("가게3.iApple : {0} ", 가게3.iApple);
            Console.WriteLine("가게3.iOrange : {0} ", 가게3.iOrange);   
        }
    }
}
cs

 

 

가게1, 가게2, 가게3 객체를 선언했지만 가게3 = 가게1 + 가게2; 의 연산을 컴파일 오류가 뜬 것을 확인할 수 있다. 만약 연산자 오버로드 없이 더하기 연산을 해야 한다면 일반적인 메서드를 이용해 각 기능을 구현해야할 것이다.

 

반면, 메서드에 대해 연산자 오버로드를 이용하면 +연산자에 의미를 부여할 수 있는데 그 방법은 다음과 같다

public static 타입 operator 연산자(타입1 변수명1, 타입2 변수명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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_008
{
    class Market
    {
        public int iApple;
        public int iOrange;
        public static Market operator +(Market Obj1, Market Obj2)
        {
            Market obj3 = new Market();
            Console.WriteLine("operator 호출됨");
            return obj3;
        }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Market 가게1 = new Market();
            Market 가게2 = new Market();
 
            가게1.iApple = 10;
            가게1.iOrange = 10;
 
            가게2.iApple = 100;
            가게2.iOrange = 100;
 
            Market 가게3 = new Market();
 
            가게3.iApple = 가게2.iApple + 가게1.iApple;
            가게3.iOrange = 가게2.iOrange + 가게1.iOrange;
 
            Console.WriteLine("가게3.iApple : {0} ", 가게3.iApple);
            Console.WriteLine("가게3.iOrange : {0} ", 가게3.iOrange);
            가게3 = 가게1 + 가게2;
        }
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_008
{
    class Market
    {
        public int iApple;
        public int iOrange;
 
        public override string ToString()
        {
            return "{iApple = " + iApple + ", iOrange = "+iOrange+"}";
        }
        public static Market operator +(Market Obj1, Market Obj2)
        {
            Console.WriteLine("1=========================");
            Market obj3 = new Market();
            Console.WriteLine("Obj1" + Obj1);
            Console.WriteLine("Obj2" + Obj2);
            Console.WriteLine("operator + 호출됨");
            Console.WriteLine("2=========================");
            return obj3;
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Market 가게1 = new Market();
            Market 가게2 = new Market();
 
            가게1.iApple = 10;
            가게1.iOrange = 10;
 
            가게2.iApple = 100;
            가게2.iOrange = 100;
 
            Market 가게3 = new Market();
 
            가게3.iApple = 가게2.iApple + 가게1.iApple;
            가게3.iOrange = 가게2.iOrange + 가게1.iOrange;
 
            Console.WriteLine("가게1" + 가게1);
            Console.WriteLine("가게2" + 가게2);
            Console.WriteLine("가게3" + 가게3);
      
            가게3 = 가게1 + 가게2;  // 이때 operator 메서드로가서 구문을 시작함

            // -, *도 정의해주면 할 수 있다.
            // 가게1에 10넣었고 가게2에 100을 넣었기 때문에 Obj1이 가게1, Obj2가 가게2인것을 알 수 있다.
            // Tostring을 잘 만들줄알면 편리해지니까 잘 익혀두자
        }
    }
}
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_008
{
    class Market
    {
        public int iApple;
        public int iOrange;
 
        public override string ToString()
        {
            return "{iApple = " + iApple + ", iOrange = "+iOrange+"}";
        }
        public static Market operator +(Market Obj1, Market Obj2)
        {
            Market obj3 = new Market();
            obj3.iApple = Obj1.iApple + Obj2.iApple;
            obj3.iOrange = Obj1.iOrange + Obj2.iOrange;
            return obj3;
        }  
    }
    class Program
    {
        static void Main(string[] args)
        {
            Market 가게1 = new Market();
            Market 가게2 = new Market();
            가게1.iApple = 10;
            가게1.iOrange = 10;
            가게2.iApple = 100;
            가게2.iOrange = 100;
 
            Market 가게3 = 가게1 + 가게2;
            Console.WriteLine("가게1" + 가게1);
            Console.WriteLine("가게2" + 가게2);
            Console.WriteLine("가게3" + 가게3);
        }
    }
}
cs

 

가게 예제는 정수일때만 메서드를 만들어서 더한것이고, 만약 복소수를 더할때 어떻게 할까?

예를들어 (3+2i)+(5+7i) = (8+9i)이다.

이렇게 실수는 실수끼리, 허수는 허수끼리 사칙연산을하는(나누기는 빼고..) 코드를 작성해보자

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace _20200603_009
{
    class Complex
    {
        int Real;
        int Image; // 참고로 클래스 변수는 초기화안하면 0이 들어가있다.
        public Complex(int Real, int Image)
        {
            this.Real = Real;
            this.Image = Image;
        }
        public override string ToString()
        {
            return "{ " + Real + " + " + Image + "i } ";
        }
        public static Complex operator +(Complex A, Complex B)
        {
            Complex C = new Complex(00);   // 더하기 연산값을 저장할 공간 생성
            C.Real = A.Real + B.Real;
            C.Image = A.Image + B.Image;
 
            return C;
// return new Complex((A.Real + B.Real), (A.Image + B.Image));
            // 위처럼 한줄로 줄여서 쓸 수도있다(이건 책에있는 방식)
        }
        public static Complex operator -(Complex A, Complex B)
        {
            Complex C = new Complex(00);
            C.Real = A.Real - B.Real;
            C.Image = A.Image - B.Image;
 
            return C;
        }
        public static Complex operator *(Complex A, Complex B)
        {
            Complex C = new Complex(00);
            C.Real = (A.Real * B.Real) - (A.Image * B.Image);
            C.Image = (A.Real * B.Image) + (A.Image * B.Real);
 
            return C;
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Complex Num1 = new Complex(34);
            Complex Num2 = new Complex(56);
            Complex Num3 = Num1 + Num2;  // 컴파일러는 Complex라는 클래스를 처음봐서 덧셈을 할줄모르니 오류가 뜬다
                                         // Num1 + Num2가 C로 변함 -> Num3에 C를 대입
            Complex Num4 = Num1 - Num2;
            Complex Num5 = Num1 * Num2;
            Console.WriteLine(Num1);
            Console.WriteLine(Num2);
            Console.WriteLine(Num3);
            Console.WriteLine(Num4);
            Console.WriteLine(Num5);
        }
    }
}
cs

(3+4i), (5+6i)의 덧셈, 뺄셈, 곱셈의 결과를 확인할 수 있다

 

각 메서드마다 스택에 C를 저장했는데 프로그램 종료될때 스택은 삭제되므로 문제가없다.

 

 

반응형