1. 상속
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; } } | cs |
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); } } | cs |
위 사진처럼 "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(); } } | 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 | 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(); } } | 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); } } | 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); } } | cs |
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(); } } | 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); } } | 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() 호출"); } } | 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!"); } } | 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() 호출"); } } |
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() 호출"); } } | 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(); } } | 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 |