김루트
EVOLUTION COMPLETE!
김루트
전체 방문자
오늘
어제
  • 분류 전체보기 (45)
    • Dev (37)
      • Vue (5)
      • Python (0)
      • 알고리즘 (0)
      • javascript (5)
      • JAVA (11)
      • Mysql (6)
      • git (3)
      • Error List (6)
    • 인터넷정보 (0)
    • Utility (1)
    • 관련자료 (2)
    • 제품리뷰 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • 글 작성시 키보드 입력이 늦어지는 현상

인기 글

태그

  • 파이썬
  • Vue.js
  • 파이썬 파일읽기
  • router-link
  • Vue공부
  • Vue
  • 파이썬 with
  • 파이썬 파일다루기
  • 파이썬 open
  • router-view
  • 람다
  • 파이썬 파일쓰기
  • 파이썬 파일추가
  • 김루트
  • 함수

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
김루트

EVOLUTION COMPLETE!

JAVA 상속
Dev/JAVA

JAVA 상속

2018. 1. 12. 12:45

1. 상속




상속(Inheritance)이란, 말 그대로 "부모의 유산을 물려받는다."를 의미하고 이는 "자식이 부모의 것을 가진다." 라고 할 수 있다. 객체 지향 프로그래밍에서도 이와 비슷한 개념으로 쓰이는데, 여기서에서는 부모 클래스에 정의된 멤버를 자식 클래스가 물려받는 것을 말한다. 즉, 상속을 통해 기존에 있던 클래스(부모 클래스)를 이용하여 새로운 클래스를 만들 수 있다. 이는 , 기존의 것을 이용하여 만들어내기 때문에 적은 양의 코드로 새로운 클래스를 만들어 낼 수 있다.

상속을 해주는 부모 클래스는 상위 클래스 (슈퍼 클래스,Super Class)또는 기반 클래스 (베이스 클래스, Base Class)라 하며, 상속을 받는 자식 클래스를 하위 클래스(서브 클래스, sub Class)또는 파생 클래스 (유도 클래스, derived Class)라고 한다. 만약 자바에서 상속을 받게 해주면, 새로운 클래스 이름 뒤에 extends와 상속 받고자 하는 클래스를 입력해주면 된다.


예제를 살펴보자.

Animal 클래스를 상속하는 Cat 클래스를 만들어 보자.

Animal.java

1
2
3
4
5
6
7
8
9
10
package home.work.test;
 
public class Animal {
    String name;
    
    public void setName(String name) {
        this.name = name;
    }
}
 
Colored by Color Scripter
cs


Cat.java
1
2
3
4
5
6
7
8
9
10
11
12
package home.work.test;
 
public class Cat extends Animal{
 
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.setName("Nabi");
        System.out.println(cat.name);
    }
 
}
 
Colored by Color Scripter
cs


extends를 이용해서 Cat클래스에 Animal 클래스를 상속시켜 주었다.

Cat 클래스에 name이라는 객체변수와 setName이라는 메소드를 만들지 않았지만 Animal클래스를 상속 받았기 때문에 그대로 사용이 가능하다. Cat 클래스에 위와 같이 main 메소드를 구현하고 실행시키면



위 사진처럼 "Nabi" 라는 문자열이 출력되는것을 확일할 수 있다.

이번에는 Cat 클래스에 Sleep이라는 메소드를 추가 해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package home.work.test;
 
public class Cat extends Animal{
 
    
    public void sleep() {
        System.out.println(this.name+"Zzz");
    }
    public static void main(String[] args) {
        Cat cat = new Cat();
        cat.setName("Nabi");
        System.out.println(cat.name);
        cat.sleep();
    }
 
}
 
Colored by Color Scripter
cs


현재 Cat클래스는 Animal 클래스보다 많은 기능을 가지게 되었다. 보통 부모 클래스를 상속 받은 자식 클래스는 부모 클래스의 기능에 더하여 좀 더 많은 기능을 갖도록 설계한다.


여기서 상속의 특징을 잠깐 살펴보도록 하자.

- 다중 상속이 불가능하다. 즉 2개의 이상의 클래스를 한꺼번에 상속할 수 없다.
- 부모의 생성자는 상속이 되지 않는다.
- 부모 클래스가 가진 멤버변수와 메소드를 모두 상속 받는다.
- 부모 클래스 내에서 멤버 변수 또는 메소드가 private 접근 제한자를 사용하면 멤버 변수는 상속 받으  나 바로 접근이 불가능하며, 메소드는 상속 되지 않는다.
- static 메소드 또는 변수도 상속이 된다.
- 동일한 이름의 변수가 부모 클래스와 자식 클래스에 둘 다 존재할 경우 부모 클래스의 변수는 가려진다.



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
class ParentClass {
 
    public void parentMethod()
 
    {
 
        System.out.println("부모 클래스의 parentMethod가 호출되었습니다.");
 
    }
 
}
 
 
 
class ChildClass extends ParentClass{
 
    public void childMethod()
 
    {
 
        System.out.println("자식 클래스의 childMethod가 호출됬습니다.");
 
        System.out.println("부모 메소드의 parentMethod를 호출했습니다.");
 
        parentMethod();
 
    }
 
}
 
 
 
class InheritanceExample {
 
    public static void main(String[] args)
 
    {
 
        ChildClass child=new ChildClass();
 
 
 
        System.out.println("간단한 자바 상속 예제: ");
 
        System.out.println("자식 클래스의 childMethod를 호출했습니다.");
 
        child.childMethod();
 
    }
 
}
Colored by Color Scripter
cs

결과 : 



위 코드에서 InheritanceExample 클래스 내에 있는 메인 메소드 내용을 보면 ChildClass 객체를 생성한 뒤에, 자식 클래스의 childMethod()를 호출한다. 그리고 자식 클래스 내에서 부모 클래스 parentmethod()를 호출한다. 결과를 보면 '자식 클래스의 childeMethod() 호출 -> childMethod 메소드 내에서 부모 클래스의 parentMethod호출' 됨을 확인할 수 있다.





* 상속에서의 생성자

위 상속의 특징에서  동일한 이름의 변수가 부모 클래스와 자식 클래스에 둘 다 존재할 경우 부모 클래스의 변수는 가려진다고 했었다. 그렇다면 어떻게 부모 클래스의 변수를 이용할 수 있을까? 우리가 이제 보게 될 super라는 예약어로 해결이 가능하다. 이 예약어를 사용하면 상위 클래스의 생성자에도 접근이 가능하다.


바로 예제를 보자.



ParentClass.java

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
package home.work.test;
 
public class ParentClass {
 
    private int x;
 
    private int y;
 
 
 
    public ParentClass(int x, int y) 
 
    {
 
        this.x = x;
 
        this.y = y;
 
    }
 
    public void xyDisplay()
 
    {
 
        System.out.println("ParentClass, x = " + x + ", y = " + y);
 
    }
}
 
Colored by Color Scripter
cs


ChildClass.java

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
package home.work.test;
 
public class ChildClass extends ParentClass {
    private int x;
 
    private int y;
 
 
 
    public ChildClass(int x, int y)
 
    {
 
        super(x * 3, y * 2);
 
        this.x = x;
 
        this.y = y;
 
    }
 
    public void childMethod()
 
    {
 
        super.xyDisplay();
 
        xyDisplay();
 
    }
 
    public void xyDisplay()
 
    {
 
        System.out.println("ChildClass, x = " + x + ", y = " + y);
 
    }
 
}
 
Colored by Color Scripter
cs

InheritanceExample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package home.work.test;
 
public class InheritanceExample {
 
    public static void main(String[] args)
 
    {
 
        ChildClass child=new ChildClass(44, 7);
 
 
 
        child.childMethod();
 
    }
}
 
Colored by Color Scripter
cs


InheritanceExample 클래스 내에 있는 메인 메소드 내용부터 보면 ChildClass 객체를 생성하면서 ChildClass의 생성자를 호출하며 44와 7을 매개변수로 넘긴다. 그러자 ChildClass 생성자 내에서 super라는 예약어를 만나 부모 클래스 생성자를 호출하며 x에 3을 곱한 값과 y에 2를 곱한 값을 넘긴다. 즉 x 44, y는 7이므로 132와 14가 넘어가서 부모 클래스의 멤버변수인 x,y는 132,와 14로 초기화 된다.


그 후에 자식 클래스의 x에 매개변수 x의 값을 넣고 매개변수 x의 값은 44, y의 값은 7이므로 자식 클래스의 멤버 변수에 들어가는 값은 각각 44, 7로 초기화 된다. 여기서 this 키워드는 자기 자신의 멤버를 가르킬 때 사용된다. 즉 this.x와 this.y는 childeClass의 멤버변수 x,y를 의미하게 된다. 그리고 빠져나와 InheritanceExmaple 클래스로 돌아가 Childclass 객체 내의 childeMethod를 호출한다.


childMethod에는 super 예약어를 사용해서 부모 클래스의 xyDisplay 메소드를 호출한다. super 예약어를 이용하는 이유는 자식 클래스의 xyDisplay 메소드에 의해 부모 클래스의 xyDisplay가 가려지기 때문이다. 부모 클래스의 xyDisplay에서 , 부모 클래스의 멤버변수인 x,y의 값을 출력하고 빠져 나온뒤에 자식 클래스의 xyDisplay를 호출한다. 여기서도 자식 클래스의 멤버변수 x,y의 값을 출력하고 빠져나온 뒤에 끝이 난다.


super 예약어를 어떻게 사용하는지 정리해보자.


- 부모 클래스의 멤버 변수 접근 : super.멤버변수

- 부모 클래스의 멤버 메소드 접근 : super:멤버메소드(매개변수);

- 부모 클래스의 생성자 호출 : super(매개변수);


super 예약어를 사용하면서 주의해야할 사항


- 반드시 자식 클래스의 생성자 첫 라인에서 부모의 생성자를 호출해야 함.

- 자식 클래스의 생성자 내에서 반드시 부모의 생성자를 호출해야 함 .

- 명시적으로 자식의 클래스에서 부모의 생성자를 호출하지 않아도 super가 자동 삽입되어 부모 클래스의 생성자를 호출 한다.


주의사항에 첫 항목을 보면 자식 클래스의 생성자 내에서 반드시 부모의 생성자를 호출해야 한다고 말했는데 이제까지 부모의 생성자를 호출하지 않아도 에러가 나지 않았다. 이유는 A라는 부모 클래스와 B라는 자식 클래스가 존재한다고 가정하고, A,B 클래스에서 명시적으로 생성자를 정의하지 않았을 경우에는 가상 머신에 의해서 디폴트 생성자가 알아서 추가된다. A는 내용이 텅 빈 디폴트 생성자가 추가되나, 자식 클래스인 B의 경우에는 super()가 자동으로 삽입된다. 그래서 에러가 나지 않았던 것이다.



* 메소드 오버로딩, 오버라이딩 *


메소드 오버로딩이란, 부모 클래스와 자식 클래스가 서로 서로 상속관계에 있고, 그 두개의 클래스에서 동일한 메소드가 존재하며 인자의 수와 데이터 타입이 다를 경우를 말한다. 아래의 예제를 보자.



ParentClass.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package home.work.test;
 
public class ParentClass {
 
    public void DisplayMethod(String str)
 
    {
 
        System.out.println("ParentClass의 DisplayMethod(String str) 호출: " + str);
 
    }
 
}
 
Colored by Color Scripter
cs


ChildClass.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package home.work.test;
 
public class ChildClass extends ParentClass {
    public void DisplayMethod()
 
    {    
 
        System.out.println("ChildClass의 DisplayMethod() 호출");
 
    }
 
 
}
 
Colored by Color Scripter
cs


InheritanceExample.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package home.work.test;
 
public class InheritanceExample {
 
    public static void main(String[] args)
 
    {
 
        ChildClass child=new ChildClass();
 
 
 
        child.DisplayMethod();
 
        child.DisplayMethod("JAVA!");
 
    }
}
 
Colored by Color Scripter
cs


결과 : 




위의 코드에서 InheritanceExample 클래스 내의 메인 메소드 안을 보면, 객체가 생성되고 그 객체의 DisplayMethod를 호출한다.그런데 하나의 인자가 없는 DisplayMethod를 호출하고 있고, 또 하나는 인자가 있는 DisplayMethod를 호출하고 있다. 인자가 없을 경우엔 자식 클래스의 DisplayMethod가 호출되고, 인자가 있을 경우에는 부모 클래스의 DisplayMethod가 호출된다.


반대로 오버라이딩은 뭘까? 오버라이딩은 메소드의 이름이 서로 같고, 인자가 같고 반환형이 같을 경우에 상속받은 메소드를 덮어쓰는 것을 말한다. "부모 클래스의 기존 메소드는 무시해버리고 자식 클래스의 메소드의 기능을 사용하겠다"란 말과 같다. 예제를 보자.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
package home.work.test;
 
public class ParentClass {
 
    public void DisplayMethod()
 
    {
 
        System.out.println("ParentClass의 DisplayMethod() 호출");
 
    }
 
}
 
Colored by Color Scripter

cs


1
2
3
4
5
6
7
8
9
10
11
12
package home.work.test;
 
public class ChildClass extends ParentClass {
    public void DisplayMethod()
 
    {    
 
        System.out.println("ChildClass의 DisplayMethod() 호출");
 
    }
}
 
Colored by Color Scripter
cs


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package home.work.test;
 
public class InheritanceExample {
 
    public static void main(String[] args)
 
    {
 
        ChildClass child=new ChildClass();
 
 
 
        child.DisplayMethod();
 
    }
 
    
}
 
Colored by Color Scripter
cs



결과 : 



이번에도 역시 객체가 생성되고 그 객체의 DisplayMethod를 호출하는 예제이다. 그런데 부모 클래스와 자식 클래스 사이에 동일한 메소드가 존재하고 있고 반환형도, 인자도 똑같다. 여기서 오바라이딩이 이루워지며 부모 클래스의 메소드를 무시하고 자기 클래스의 메소드를 호출한다.


이상으로 자바 상속에 대해 마친다.


'Dev > JAVA ' 카테고리의 다른 글

JAVA 추상 클래스  (0) 2018.01.15
JAVA 인터페이스(Interface)  (0) 2018.01.15
[JAVA] jsp / java를 이용한 DB연동  (0) 2017.12.04
[JAVA] 다른클래스 호출및선언 setting,getting  (0) 2017.12.01
[JAVA] switch, while-break, 응용문  (0) 2017.12.01
    'Dev/JAVA ' 카테고리의 다른 글
    • JAVA 추상 클래스
    • JAVA 인터페이스(Interface)
    • [JAVA] jsp / java를 이용한 DB연동
    • [JAVA] 다른클래스 호출및선언 setting,getting
    김루트
    김루트
    방문해주셔서 감사합니다:)

    티스토리툴바