구현 상속
- 부모의 코드를 자식이 그대로 물려받는 것이며 클래스 간의 상속이 그 예이다
- 자식은 부모의 코드를 물려받아 그대로 사용하거나 아니면 재정의라는 방법을 통해 동작을 어느정도 수정할수 있다
- 코드의 재사용 측면에서는 굉장히 효율적이지만 자식이 부모에게 종속된다는 문제가 있다
- 부모의 동작이 바뀌면 이 동작을 상속받는 자식들도 영향을 받으며 상속 관계가 깊을 때는 굉장히 많은 클래스들이 영향을 받는다
- 부모 클래스에 버그가 있으면 자식클래스에도 파생된다

인터페이스 상속
- 구현 코드는 물려받지 않고 구현해야할 메소드의 목록만 상속받는 것이다
- 부모 메소드는 목록만 제공할 뿐이며 이 메소드는 어떻게 구현하는가는 자식이 알아서 결정가능
- 목록만 받으므로 종속성이 없고 혼란스럽지도 않다
- 추상메소드는 인터페이스 상속의 한예이며 인터페이스로부터 클래스를 상속할때는 모든 메소드가 상속된다

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;
 
namespace ICreature
{
    interface ICreature
    {
        void Propagate();
    }
 
    interface IPlant : ICreature
    {
        void Flower();
    }
 
    interface IAnimal : ICreature
    {
        void Move();
    }
 
    class Lion : IAnimal
    {
        public void Move()
        {
            Console.WriteLine("어슬렁");
        }
 
        public void Propagate()
        {
            Console.WriteLine("번식");
        }
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Lion L = new Lion();
 
            L.Propagate();
            L.Move();
        }
    }
}




- 인터페이스 상속


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
using System;
 
namespace MusicPhone
{
    interface IMP3
    {
        void PlayMusic();
    }
 
    interface ICamera
    {
        void TakePhoto();
    }
 
    class HandPhone
    {
        public virtual void Send()
        {
            Console.WriteLine("handphone send");
        }
 
        public virtual void Receive()
        {
            Console.WriteLine("handphone receive");
        }
    }
 
    class MusicPhone : HandPhone, IMP3, ICamera
    {
        public override void Send()
        {
            Console.WriteLine("handphone over");
        }
 
        public void PlayMusic()
        {
            Console.WriteLine("playmusic");
        }
 
        public void TakePhoto()
        {
            Console.WriteLine("takephoto");
        }
    }
 
 
    class Program
    {
        static void Main(string[] args)
        {
            HandPhone H = new HandPhone();
            H.Send();
            H.Receive();
 
            MusicPhone M = new MusicPhone();
            M.Send();
            M.PlayMusic();
            M.TakePhoto();
        }
    }
}




- 다중 상속 (선언문의 뒤쪽에 :을 찍고 그뒤에 한개의 클래스와 여러개의 인터페이스를 부모로 지정)
                 (부모클래스는 반드시 하나만 와야하고, 생략되면 자동으로 object로부터 파생)
                 (부모인터페이스는 필요한 만큼 얼마든지 올 수 있다)
                 (클래스와 인터페이스로부터 다중 상속받을때는 항상 클래스가 선언문의 제일 앞에 와야 한다)


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
using System;
 
namespace MultiInheritance
{
    interface A1
    {
        void a();
    }
 
    interface A2
    {
        void a();
    }
 
    interface B : A1, A2
    {
        void b();
    }
 
    class C : B
    {
        public void a()
        {
            Console.WriteLine("C - a");
        }
 
        public void b()
        {
            Console.WriteLine("C - b");
        }
    }
 
    class Program
    {
        static void Method(B b)
        {
           ((A1)b).a();
        }
 
        static void Main(string[] args)
        {
            C c = new C();
            c.a();
            Method(c);
        }
    }
}




- C는 일종의 B이므로 인수로 전달하는 것 자체는 문제가 없지만
Method의 b.a() 호출문이 문제가 되며 이 줄에서 에러가 발생
B 인터페이스 타입의 b 객체로 a 메소드를 호출하면 이게 A1으로부터 상속받은 a를 의미하는 것인지 아니면 A2로부터
상속받은 a를 의미하는 것인지 모호해서 어떤 메소드를 호출해야 할지 모르겠다는 뜻
캐스팅을 해야한다

Posted by 코딩하는 야구쟁이
,