반응형

기존의 http://www.crocus.co.kr/531 내용에서 추가적으로 더 작성하였습니다.


클래스 상속(inheritance)


새로운 클래스를 생성할 때 기존의 클래스가 가지고 있는 필드와 메소드를 물려 받는 방법을 의미한다. 

예를들어 animal이라는 클래스를 생성했다고 생각해보자.

이 animal 클래스에는 int 다리 개수, void 달리기() 등등의 필드와 메소드로 구성되어있을 것이다.

이때 dog라는 클래스를 생성하면서 animal 클래스를 상속 받는다고 한다면, 

dog라는 클래스는 int 다리 개수와 void 달리기()를 이용할 수 있게 된다.

이때 코드에서 상속을 받고자 한다면 class dog extends animal{ ~ }라고 선언하면 된다.





클래스 상속(inheritance) 기본 예제

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
package JavaBasic;
 
class animal{
    
    public int leg;
    
    public void run()
    {
        System.out.println("달리는중");
        System.out.println("참고로 다리 개수는 :: " + leg + "개 입니다.");
    }
}
 
class dog extends animal{
    
    public void eat()
    {
        System.out.println("냠냠냠");
    }
    public void shout()
    {
        System.out.println("왈왈왈");
    }
}
public class Jmain{    
            
    public static void main(String []args)
    {
        dog dg = new dog();
        
        dg.leg = 4;
        dg.eat();
        dg.shout();
        dg.run();
        
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


만약 이때 extends animal없다면?





이렇게 dog 클래스에는 없기때문에 'dog 클래스에는 run()이 없어요. run() 메소드를 만들래요?' 라고 물어보게 된다.






상속시 생성자 호출 과정

만약 부모 클래스(슈퍼 클래스)와 자식 클래스(서브 클래스) 모두에게 생성자가 있다면 어떻게 반응할까?

자식 클래스 생성자가 먼저 호출될까 부모 클래스 생성자가 먼저 호출될까?

답은 부모 클래스 -> 자식 클래스 생성자 순으로 호출된다.

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
package JavaBasic;
 
class animal{
    
    public int leg;
    
    animal()
    {
        System.out.println("부모가 먼저");
    }    
    public void run()
    {
        System.out.println("달리는중");
        System.out.println("참고로 다리 개수는 :: " + leg + "개 입니다.");
    }
}
 
class dog extends animal{
    
    dog()
    {
        System.out.println("자식이 먼저");
    }
    public void eat()
    {
        System.out.println("냠냠냠");
    }
    public void shout()
    {
        System.out.println("왈왈왈");
    }
}
public class Jmain{    
            
    public static void main(String []args)
    {
        dog dg = new dog();
        
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus






상속시 생성자 오버로딩을 했을 때 호출 과정

이 과정에서는 어떻게 출력될까?

1.
부모
자식 :: hello ??

2.
부모 :: hello
자식 :: hello ??

아래 코드의 출력물을 통해 확인해보자.

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
package JavaBasic;
 
class animal{
    
    public int leg;
    
    animal()
    {
        System.out.println("부모");
    }    
    animal(String str)
    {
        System.out.println("부모 :: " + str);
    }
}
 
class dog extends animal{
    
    dog(String str)
    {
        System.out.println("자식 :: " + str);
    }
}
public class Jmain{    
            
    public static void main(String []args)
    {
        dog dg = new dog("hello");
        
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus




결과는 위의 사진과 같다.

그 이유는 인스턴스(객체)를 생성할 때 dog에 "hello"라는 스트링을 보냈으니 자식은 당연히 string을 받게된다.
하지만 부모는 그런것과 관계 없이 생성자를 호출하게 된다.

따라서 부모는 animal()을 호출하게 되고 자식은 dog(String str)을 호출하게 된다.

이때 부모도 animal(String str)을 호출하게 하고 싶다면 아래와 같이 자식 클래스에 

super(str); 이라고 적으면 된다.

1
2
3
4
5
6
7
8
9
10
11
class dog extends animal{
    
    dog(String str)
    {
        super(str);
        System.out.println("자식 :: " + str);
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus






상속시 메소드 오버라이딩

※ 참고 :: 오버로딩과 오버라이딩의 차이

오버로딩은 같은 클래스 내에서 이름은 같고 매개변수 타입 혹은 개수가 다른 메소드들이 정의 될 때를 의미하고,
(ex :: eat(int a, int b)와 eat(String 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
package JavaBasic;
 
class animal{
    
    public int leg;
 
    public void eat()
    {
        System.out.println("매개 변수가 없어서 먹을게 없어요..");
    }
}
 
class dog extends animal{
    
    public void eat(int a)
    {
        System.out.println("냠냠냠");
    }
}
public class Jmain{    
            
    public static void main(String []args)
    {
        dog dg = new dog();
        
        dg.eat();
    }
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus

위의 코드를 보면 animal클래스와 dog 클래스 모두에게 eat라는 메소드가 존재한다.

이때는 오버라이딩에 의해 파라미터가 int형으로 주어진다면 dog 클래스의 eat 메소드가 실행,

파라미터가 없다면 animal의 eat 메소드가 실행된다.

만약, dog 클래스 eat메소드에도 매개 변수를 받지 않는다면

즉, animal도 public void eat()이고, dog도 public void eat()라면 dg.eat();를 호출 시 dog의 메소드가 호출된다.


  (부모 메소드 호출)                  (자식 메소드 호출)








반응형