09009
[Java] 상속 본문
상속
• 부모가 자식에게 물려주는 행위
• 자식(하위, 파생) 클래스가 부모(상위) 클래스의 멤버를 물려받는 것, 자식이 부모를 선택해 물려받는다.
• 기존의 클래스를 재사용하여 새로운 클래스를 작성하는것
• 상속 대상: 부모의 필드와 메소드
상속을 하는 이유?
• 부모 클래스를 재사용하여 자식 클래스 빨리 개발 가능
• 적은 양의 코드로 새로운 클래스 작성
• 코드를 공통적으로 관리할 수 있어 코드의 추가 및 변경 쉬움
• 반복된 코드 중복 줄임
• 유지 보수 편리성 제공
• 객체 다형성 구현 가능
상속을 구현하는 방법 - extends 키워드
• 자식 클래스가 상속할 부모 클래스를 지정하는 키워드
class 자식클래스 extends 부모클래스
• 새로 작성하려는 클래스 이름 : Child (자식클래스)
• 자식이 상속받고자 하는 기존 클래스의 이름 : Parent (부모클래스)
class Child extends Parent {
}
• Java는 단일 상속, 부모 클래스 나열 불가
상속의 특성
• Java에서 제공되어지는 모든 클래스들은 Object라고 하는 최상위 클래스로부터 상속되어진다.
• 사용자정의 클래스들도 Object 클래스라는 최상위클래스를 상속받아야 한다.
• child 클래스가 parent 클래스를 상속받았다고 가정해보자. child는 자손 클래스이고 parent는 조상 클래스이다.
자손 클래스는 조상 클래스의 모든 멤버를 상속받기 때문에 만일 parent 클래스에 age라는 정수형 변수를 멤버변수로 추가하였을 때, 자손 클래스 child는 자동적으로 age라는 멤버변수가 추가된다.
• 하지만, child 클래스에 새로운 변수나 메서드가 추가되어도 부모인 parent 클래스는 아무런 영향도 받지 않는다.
• 조상 클래스가 변경되면 자손 클래스는 자동적으로 영향을 받으나 자손 클래스가 변경되는 것은 조상 클래스에 아무런 영향을 주지 않는다.
!!! 상속 대상 제한 !!!
• 부모 클래스의 private 접근제한자를 갖는 필드와 메소드는 제외된다.
→ 클래스는 상속을 받더라도 private 메서드는 접근할 수 없지만 getter and setter 메소드를 사용하면 상속을 받았을 때 간접적으로 접근이 가능하다.
• 부모 클래스가 다른 패키지에 있을 경우, default 접근제어자를 갖는 필드와 메소드도 제외된다.
• 생성자와 초기화 블럭은 상속에서 제외된다.
✍ 입력
package ch07;
class A1 {
int a1 = 1;
public void m1() {
System.out.println("부모 메서드입니다");
}
}
class A2 extends A1 { // A2가 A1을 상속 --> A2클래스에 없는 a1 변수, m1() 메서드를 A2의 것처럼 사용
int a2 = 2;
void m2() {
System.out.println("자식 메서드입니다");
}
}
public class Inher1 {
public static void main(String[] args) {
A2 a2 = new A2();
System.out.println("a1 = " + a2.a1);
System.out.println("a2 = " + a2.a2);
a2.m1(); a2.m2();
}
}
A2 클래스에서 a1 변수와 m1() 메서드를 선언하지 않았지만 A1 클래스를 상속받았기 때문에 A2 클래스의 부모 클래스는 A1 클래스가 되는 것이고 A1 클래스에 있는 a1 변수와 m1() 메서드를 A2 클래스는 마치 본인의 것처럼 사용할 수 있다.
💻 출력 결과
a1 = 1
a2 = 2
부모 메서드입니다
자식 메서드입니다
✍ 입력
package ch07;
// B3을 이용하여 객체 b3을 생성하고 사용 가능한 변수와 메서드를 출력
class B1 {
int k1 = 77;
void m1() {
System.out.println("난 b1 메서드");
}
}
class B2 extends B1 {
int k2 = 88;
void m2() {
System.out.println("난 b2 메서드");
}
}
class B3 extends B2 {
int k3 = 99;
void m3() {
System.out.println("난 b3 메서드");
}
}
public class Inher2 {
public static void main(String[] args) {
B3 b3 = new B3();
System.out.println("k1 = " + b3.k1);
System.out.println("k2 = " + b3.k2);
System.out.println("k3 = " + b3.k3);
b3.m1(); b3.m2(); b3.m3();
}
}
💻 출력 결과
k1 = 77
k2 = 88
k3 = 99
난 b1 메서드
난 b2 메서드
난 b3 메서드
위에서와 마찬가지로 B3 클래스에서 k1, k2 변수와 m1() 메서드, m2() 메서드를 따로 선언하지 않았지만 B3 클래스는 B2를 상속받고, B3 클래스의 부모 클래스인 B2는 B1을 상속받았기 때문에 B3 클래스는 B1 클래스에 있는 k1 변수와 m1() 메서드, B2 클래스에 있는 k2 변수와 m2() 메서드를 B3 클래스는 마치 본인의 것처럼 사용할 수 있다.
✍ 입력
package ch07;
class C1 {
String s1 = "부모 멤버변수";
C1() {
System.out.println("난 부모 생성자");
}
void m1() {
System.out.println("부모 메서드");
}
}
class C2 extends C1 {
// 생성자는 부모부터 생성된 후에 자식이 생성된다. 상속은 아님.
String s2 = "자식 멤버변수";
C2() {
System.out.println("난 자식 생성자");
}
void m2() {
System.out.println("자식 메서드");
}
}
public class Inher3 {
public static void main(String[] args) {
C2 c = new C2();
System.out.println("s1 = " + c.s1);
System.out.println("s2 = " + c.s2);
c.m1(); c.m2();
}
}
💻 출력 결과
난 부모 생성자
난 자식 생성자
s1 = 부모 멤버변수
s2 = 자식 멤버변수
부모 메서드
자식 메서드
위의 출력 결과를 확인해보면 C2 클래스는 C1 클래스를 상속받았기 때문에 C1 클래스에 있는 s1 변수와 m1() 메서드를 사용할 수 있다는 사실을 확인할 수 있다.
그런데 생성자 출력결과(C2 c = new C2();)를 보면 분명히 C2 클래스의 객체만 생성했을 뿐인데 C1 클래스의 생성자까지 같이 출력된다는 것을 알 수 있다.
→ 생성자는 자식 생성자를 호출하게 되면, 자동으로 부모의 생성자가 먼저 호출이 된다.
(생성자는 반환형이 없다)
예제
- D3의 d 객체 생성 후에 각각 가능한 변수와 메서드를 실행할 것.
- 각각 생성자와 m1,m2,m3 메서드를 만들 것
D1 할아버지 생성자 int k1 = 7 m1() 난 할아버지
D2 아버지 생성자 int k2 = 77 m2() 난 아버지
D3 자식 생성자 int k3 = 777 m3() 난 자식
✍ 입력
package ch07;
class D1 {
int k1 = 7;
D1() {
System.out.println("난 할아버지 생성자");
}
void m1() {
System.out.println("할아버지 메서드");
}
}
class D2 extends D1 {
int k2 = 77;
D2() {
System.out.println("난 아버지 생성자");
}
void m2() {
System.out.println("아버지 메서드");
}
}
class D3 extends D2 {
int k3 = 777;
D3() {
System.out.println("난 자식 생성자");
}
void m3() {
System.out.println("자식 메서드");
}
}
public class Inher4 {
public static void main(String[] args) {
D3 d = new D3();
System.out.println("k1 = " + d.k1);
System.out.println("k2 = " + d.k2);
System.out.println("k3 = " + d.k3);
d.m1(); d.m2(); d.m3();
}
}
💻 출력 결과
난 할아버지 생성자
난 아버지 생성자
난 자식 생성자
k1 = 7
k2 = 77
k3 = 777
할아버지 메서드
아버지 메서드
자식 메서드
D3 클래스는 D2 클래스를 상속받았기 때문에 D2 클래스에 있는 k2 변수와 m2() 메서드를 사용할 수 있다는 사실을 확인할 수 있다.
D3 클래스는 D2를 상속받고, D3 클래스의 부모 클래스인 D2는 D1을 상속받았기 때문에 D3 클래스는 D1 클래스에 있는 k1 변수와 m1() 메서드, D2 클래스에 있는 k2 변수와 m2() 메서드를 D3 클래스는 마치 본인의 것처럼 사용할 수 있다.
Getter and Setter
(eclipse 단축키 : alt + shift + s + r)
(intellij 단축키 : alt + insert)
✍ Person.java
클래스는 상속을 받더라도 private 메서드는 접근할 수 없지만 getter and setter 메소드를 사용하면 상속을 받았을 때 간접적으로 접근이 가능하다.
package ch07;
public class Person {
private String name;
private int age;
public Person() {
}
// private -> generate getter and setter
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
void print() {
System.out.println("========================");
System.out.println("이름 : " + name);
System.out.println("나이 : " + age);
}
}
✍ Teacher.java
package ch07;
public class Teacher extends Person {
private String subject;
public Teacher(String name, int age, String subject) {
setName(name); setAge(age); this.subject = subject;
}
void printTh() {
print();
System.out.println("과목 : " + subject);
}
}
✍ Student.java
package ch07;
public class Student extends Person {
private String sno;
public Student(String name, int age, String sno) {
setName(name); setAge(age); this.sno = sno;
}
void printSt() {
print();
System.out.println("학번 : " + sno);
}
}
✍ Manager.java
package ch07;
public class Manager extends Person{
private String part;
public Manager(String name, int age, String part) {
setName(name); setAge(age); this.part = part;
}
void printMg() {
print();
System.out.println("담당 : " + part);
}
}
✍ PersonEx.java
package ch07;
// 상속 사용 이유: 코드 중복을 방지하기 위함.
//상속을 받아도 private 메소드는 접근할 수 없지만 getter and setter 메소드를 사용하면 상속을 받았을 때 간접적으로 접근이 가능하다.
public class PersonEx {
public static void main(String[] args) {
Student st1 = new Student("로제", 26, "5678");
Student st2 = new Student("제니", 25, "5679");
Teacher th1 = new Teacher("하니", 32, "JAVA");
Teacher th2 = new Teacher("보검", 33, "스프링");
Manager mg1 = new Manager("은우", 18, "화장실 청소");
Manager mg2 = new Manager("효리", 38, "노래");
st1.printSt(); st2.printSt();
th1.printTh(); th2.printTh();
mg1.printMg(); mg2.printMg();
}
}
💻 출력 결과
=================
이름 : 로제
나이 : 26
학번 : 5678
=================
이름 : 제니
나이 : 25
학번 : 5679
=================
이름 : 하니
나이 : 32
과목 : JAVA
=================
이름 : 보검
나이 : 33
과목 : 스프링
=================
이름 : 은우
나이 : 18
담당 : 화장실 청소
=================
이름 : 효리
나이 : 38
담당 : 노래
예제
- Car(print) kind, inwon / 출력: print() 차종류, 승차인원:
- 상속 : Ambulance(printAm 환자를 싣고 달린다. "구급차", 5), Bus(printBus 승객 40명 이상을 태울 수 있다. "버스", 40), FireEngine(printFe 불을 끄는 차량입니다. "불자동차", 10) java 파일 만들기
- CarEx .java 객체 3개를 생성하고 출력
✍ Car.java
package ch07;
// Car(print) kind, inwon / 출력: print() 차종류: 승차인원:
//상속 : Ambulance(printAm 환자를 싣고 달린다.), Bus(printBus 승객 40명 이상을 태울 수 있다.), FireEngine(printFe 불을 끄는 차량입니다.)
// CarEx 3개를 생성하고 출력
public class Car {
private String kind;
private int inwon;
public void setKind(String kind) {
this.kind = kind;
}
public void setInwon(int inwon) {
this.inwon = inwon;
}
void print() {
System.out.println("===============");
System.out.println("종류: " + kind);
System.out.println("승차인원: " + inwon);
}
}
✍ Ambulance.java
package ch07;
public class Ambulance extends Car {
public Ambulance(String kind, int inwon) {
setKind(kind); setInwon(inwon);
}
void printAm() {
print();
System.out.println("환자를 싣고 달린다.");
}
}
class Bus extends Car {
public Bus(String kind, int inwon) {
setKind(kind); setInwon(inwon);
}
void printBus() {
print();
System.out.println("승객 40명 이상을 태울 수 있다.");
}
}
class FireEngine extends Car {
public FireEngine(String kind, int inwon) {
setKind(kind); setInwon(inwon);
}
void printFe() {
print();
System.out.println("불을 끄는 차량입니다.");
}
}
✍ CarEx.java
package ch07;
public class CarEx {
public static void main(String[] args) {
Ambulance am = new Ambulance("구급차", 5);
Bus b = new Bus("버스", 40);
FireEngine f = new FireEngine("불자동차", 10);
am.printAm();
b.printBus();
f.printFe();
}
}
💻 출력 결과
===============
종류 : 구급차
승차인원 : 5
환자를 싣고 달린다.
===============
종류 : 버스
승차인원 : 40
승객 40명 이상을 태울 수 있다.
===============
종류 : 불자동차
승차인원 : 10
불을 끄는 차량입니다.
Object 클래스 - 모든 클래스의 최고 조상
• 상속계층도의 최상위에는 Object 클래스가 위치한다.
• 다른 클래스로부터 상속 받지 않는 모든 클래스들은 자동적으로 Object 클래스로부터 상속받게 된다.
→ Java에서 모든 클래스들은 Object 클래스의 멤버들을 상속받으므로 Object 클래스에 정의된 멤버들을 그대로 사용 가능 (toString(), equals()와 같은 메서드를 따로 정의하지 않고도 사용할 수 있었던 이유)
오버라이딩
• 조상클래스로부터 상속받은 메서드의 내용을 변경하는 것
• 자손클래스 자신에 맞게 매서드의 내용을 변경하는 것
오버라이딩의 조건
• 선언부(이름, 매개변수, 반환타입)가 같아야 한다.
• 조상 클래스를 오버라이딩하는 자손 클래스의 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경할 수 없다.
- 조상 클래스에 있는 메서드의 접근 제어자가 protected라면, 이를 오버라이딩하는 자손 클래스에 정의된 메서드의 접근 제어자는 범위가 같거나 넓은 protected이거나 public이어야 한다.
• 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
Super
• 하위(자손) 클래스에서 상위(조상) 클래스로부터 상속받은 멤버를 참조하는데 사용되는 참조 변수
• 하위 클래스에 의해 가려진 상위 클래스의 멤버 변수나 메소드에 접근할 때 사용한다.
• this()와 마찬가지로 super() 역시 생성자
• super()는 조상 클래스의 생성자 호출 시 사용
✍ 입력
class Parent {
int x = 10;
}
class Child extends Parent {
int x = 20;
void disp() {
System.out.println("x = " + x);
System.out.println("this.x = " + this.x);
System.out.println("super.x = " + super.x);
}
}
public class SuperTest{
public static void main(String[] args) {
Child c = new Child();
c.disp();
}
}
위의 소스코드를 보면 같은 이름을 가진 멤버변수 x가 조상 클래스 Parent와 자손 클래스 Child에도 있는 것을 확인할 수 있다.
💻 출력
x = 20
this.x = 20
super.x = 10
하위 클래스에 의해 가려진 상위 클래스의 멤버 변수나 메소드에 접근할 때
→ super.객체변수
→ super.메서드이름(매개변수)
상위 클래스의 생성자를 호출할 때
→ super(매개변수)
!!! super문장은 반드시 첫 번째 라인에 와야 한다 !!!
✍ Super1.java
package ch07;
class E1 {
E1() {
System.out.println("기본 생성자");
}
E1(int k) {
System.out.println("매개변수가 1개인 생성자 : " + k);
}
void m1() {
System.out.println("m1 메서드입니다");
}
}
class E2 extends E1 {
E2(int k) {
System.out.println("안녕하세요");
}
void m2() {
System.out.println("반가워요");
}
}
public class Super1 {
public static void main(String[] args) {
E2 e = new E2(7);
e.m1(); e.m2();
}
}
💻 출력 결과
기본 생성자
안녕하세요
m1 메서드입니다
반가워요
!!! 주의할 점!!!
• 기본 생성자는 생성자가 하나도 없으면 컴파일할 때 자동으로 만들어 준다. 다른 생성자가 하나라도 있으면 기본 생성자는 만들어지지 않는다.
• 위의 소스코드에서 E1 클래스의 기본생성자가 없고 매개변수를 받는 생성자 (E1(int k)) 만 있을 때와 동시에 E2 클래스의 매개변수 k가 있는 E2 생성자에 super(k);가 명시되어 있지 않으면 에러가 발생한다.
아래 스크린샷에 있는 소스코드를 보면 그 사실을 확인할 수 있다.
-----------------------------------------------------------------------------------------------------------------------------------------
에러 해결 방법
1) E2 클래스에 super(k);를 작성 (E1 클래스에 기본생성자는 없고 매개변수를 받는 생성자만 있을 경우)
💻 출력 결과
매개변수가 1개인 생성자 : 7
안녕하세요
m1 메서드입니다
반가워요
2) E1 클래스에 기본 생성자 만들기 (E2 클래스에 super(k);를 작성하지 않아도 에러가 발생하지 않는다.)
!!! 생성자는 자식 생성자를 호출하면 반드시 부모부터 호출된 후에 자식이 호출된다는 것을 잊지말자 !!!
그러므로 출력 결과에 "기본 생성자입니다"가 먼저 출력되는 것이다.
💻 출력 결과
기본 생성자입니다
안녕하세요
m1 메서드입니다
반가워요
수정한 코드
✍ Super1.java
package ch07;
class E1 {
E1() {
System.out.println("기본 생성자");
}
E1(int k) {
System.out.println("매개변수가 1개인 생성자 : " + k);
}
void m1() {
System.out.println("m1 메서드입니다");
}
}
class E2 extends E1 {
E2 (int k) {
super(k);
System.out.println("안녕하세요");
}
void m2() {
System.out.println("반가워요");
}
}
public class Super1{
public static void main(String[] args) {
E2 e = new E2(7);
e.m1(); e.m2();
}
}
💻 출력 결과
매개변수가 1개인 생성자 : 7
안녕하세요
m1 메서드입니다
반가워요
다른 예제 소스코드
위의 소스코드를 그대로 컴파일하면 에러가 발생한다. Point3D 클래스의 생성자에서 조상 클래스의 생성자인 Point()를
찾을 수 없기 때문이다.
Point3D 클래스의 생성자의 첫 줄이 생성자를 호출하는 문장이 아니므로 컴파일러는 자동적으로 super();를 point3D 클래스의 생성자의 첫 줄에 넣어준다. (super()도 생성자이므로 자식의 생성자가 호출될 시, 부모의 생성자부터 먼저 호출되어야 하기 때문에)
그래서 Point3D 클래스의 인스턴스를 생성하면, 생성자 Point3D(int x, int y, int z)가 호출되어 첫 문장인 super();를 수행한다.
super() = Point 클래스 [Point3D 클래스의 조상]의 기본 생성자인 Point()
그러나, Point 클래스에서 기본 생성자 Point()가 정의되어 있지 않았기 때문에 에러가 발생한다.
위 에러를 수정하기 위해서는 Point 클래스에 기본 생성자 Point()를 추가하던지 아니면 생성자 Point3D(int x, int y, int z)의 첫 줄에서 Point(int x, int y)를 호출하도록 변경해야 한다.
!! 클래스에 다른 생성자가 정의되어 있으면 컴파일러는 기본 생성자를 자동적으로 추가하지 않는다 !!
에러 해결 방법
수정한 코드
1) Point 클래스에 기본 생성자 Point()를 추가
2) 생성자 Point3D(int x, int y, int z)의 첫 줄에서 Point(int x, int y)를 호출
✍ Super2.java
package ch07;
class F1 {
int x = 7;
void disp() {
System.out.println("부모 메서드입니다");
}
}
class F2 extends F1 {
int x = 8;
void disp() {
System.out.println("자식 메서드입니다");
}
void print() {
System.out.println("x = " + x);
disp();
}
}
public class Super2 {
public static void main(String[] args) {
F2 f = new F2();
f.print();
}
}
💻 출력 결과
x = 8
자식 메서드입니다
위의 출력 결과를 확인해보면 F2 클래스는 F1 클래스를 상속받았지만 변수 x를 출력할 때는 부모의 변수인 x와 같이 출력되는 것이 아닌 F2 클래스 자신이 가지고 있는 변수만 출력된다는 사실을 알 수 있다.
부모의 변수까지 같이 출력하려면 어떻게 해야 할까?
수정한 코드
✍ Super2.java
package ch07;
class F1 {
int x = 7;
void disp() {
System.out.println("부모 메서드입니다");
}
}
class F2 extends F1 {
int x = 8;
void disp() {
System.out.println("자식 메서드입니다");
}
void print() { // 이름이 중복되면 가까운 이름 사용, super를 붙이면 부모의 것 사용 (자식과 부모를 구별하기 위함)
System.out.println("x = " + super.x);
super.disp();
System.out.println("x = " + x);
disp();
}
}
public class Super2 {
public static void main(String[] args) {
F2 f = new F2();
f.print();
}
}
💻 출력 결과
x = 7
부모 메서드입니다
x = 8
자식 메서드입니다
위의 출력 결과를 확인해보면 super.객체변수 , super.메서드이름(매개변수)을 작성할 시 자식 클래스가 상속받은 부모 클래스의 변수와 메서드의 결과까지 같이 출력되는 것을 알 수 있다.
예제
클래스 G1
- class G1 생성 -> G1(String name) 생성자 만들기 -> name 님이 생성되었습니다.
disp() 오늘은 금요일입니다
age = 47
클래스 G2
- G1 상속받는다
- age = 22
- G2(String name) 생성자 만들기 -> xxx님 반갑습니다
disp() 코딩하기 좋은 날입니다
print()
부모 나이, 자식 나이
부모 disp(), 자식 disp()
Super3Ex.java 파일 만들기
G2 g 객체를 생성하고 print() 실행
✍ 입력
package ch07;
class G1 {
int age = 47;
G1(String name) {
System.out.println(name + "님이 생성되었습니다.");
}
void disp() {
System.out.println("오늘은 금요일입니다");
}
}
class G2 extends G1 {
int age = 22;
G2(String name) {
super(name); // super(매개변수,...) 없으면 부모 기본생성자가 호출된다. 근데 부모의 기본생성자가 명시되어 있지 않아서 오류가 발생한 것임
// 오류발생을 막으려면 부모의 기본생성자를 직접 작성하거나 자식 클래스에서 super를 작성해야함.
System.out.println(name + "님, 반갑습니다.");
}
void disp() {
System.out.println("코딩하기 좋은 날입니다.");
}
void print() {
super.disp();
disp();
System.out.println("부모님의 나이 : " + super.age);
System.out.println("자식의 나이 : " + age);
}
}
public class Super3Ex {
public static void main(String[] args) {
G2 g = new G2("홀란드");
g.print();
}
}
위의 소스코드에서 super(매개변수,...) (위의 소스코드에선 G2 클래스의 G2 생성자에 선언된 super(name);)가 없다고 가정하면 부모의 기본생성자가 호출된다.
그런데 부모 클래스 G1에 매개변수를 받는 생성자는 있고, 기본생성자가 명시되어 있지 않은 채 자식 클래스 G2 생성자에서 super(매개변수,...) 를 작성하지 않으면 에러가 발생한다.
즉, 에러 발생을 막으려면 부모의 기본생성자를 직접 작성하거나 자식 클래스에서 super를 작성해야한다.
-----------------------------------------------------------------------------------------------------------------------------------------
에러 해결 방법
1) 부모 클래스 기본 생성자 작성
2) 자식 클래스 생성자에서 super(매개변수) 작성 (부모 클래스 G1에서 기본 생성자가 없고 매개변수를 받는 생성자만 있을 때)
소스코드를 다시 한 번 정리해보면 아래와 같은 결과가 나온다.
✍ 입력
package ch07;
class G1 {
int age = 47;
G1(String name) {
System.out.println(name + "님이 생성되었습니다.");
}
void disp() {
System.out.println("오늘은 금요일입니다");
}
}
class G2 extends G1 {
int age = 22;
G2(String name) {
super(name); // super(매개변수,...) 없으면 부모 기본생성자가 호출된다. 근데 부모의 기본생성자가 명시되어 있지 않아서 오류가 발생한 것임
// 오류발생을 막으려면 부모의 기본생성자를 직접 작성하거나 자식 클래스에서 super를 작성해야함.
System.out.println(name + "님, 반갑습니다.");
}
void disp() {
System.out.println("코딩하기 좋은 날입니다.");
}
void print() {
super.disp();
disp();
System.out.println("부모님의 나이 : " + super.age);
System.out.println("자식의 나이 : " + age);
}
}
public class Super3Ex {
public static void main(String[] args) {
G2 g = new G2("홀란드");
g.print();
}
}
💻 출력 결과
홀란드님이 생성되었습니다.
홀란드님, 반갑습니다.
오늘은 금요일입니다
코딩하기 좋은 날입니다.
부모님의 나이 : 47
자식의 나이 : 22
그리고 부모 클래스의 변수와 메서드의 결과까지 같이 출력하려면 super.객체변수 , super.메서드이름(매개변수)를 작성하면 된다.
This와 Super 예제
✍ 입력
package ch07;
class H1 {
int x;
H1(int x) { // 8
this.x = x; // 9
System.out.println("부모 매개변수 1개"); // 10
}
H1(int x, int y) { // 6
this(x); // 7
System.out.println("부모 매개변수 2개"); // 11
}
void print() {
System.out.println("x = " + x);
}
}
class H2 extends H1 {
// 처음에 작성할때 빨간줄이 나오는건 부모의 기본생성자가 없기 때문
H2(int x, int y) { // 4
super(x, y); // 5
System.out.println("자식 매개변수 2개"); // 12
}
H2(int x, int y, int z) { // 2
this(x,y); // 3
System.out.println("자식 매개변수 3개"); // 13
}
}
public class Super4Ex {
public static void main(String[] args) {
H2 h = new H2(34, 66, 55); // 1
h.print(); // 14
}
}
💻 출력 결과
부모 매개변수 1개
부모 매개변수 2개
자식 매개변수 2개
자식 매개변수 3개
x = 34
실습 예제
class Computer {
String owner;
public Computer(String name) {
owner = name;
}
public void calculate() {
System.out.println("요청 내용을 계산합니다.");
}
}
class NotebookComp extends Computer {
int battery;
public NotebookComp(String name, int initChag) {
super(name); battery = initChag;
}
public void charging() {
battery += 5;
}
public void movingCal() {
if (battery < 1) {
System.out.println("충전이 필요합니다");
return;
}
System.out.println("이동하면서 ");
calculate(); // 부모한테 물려받은 메서드 호출
battery -= 1;
}
}
class TableNotebook extends NotebookComp {
String regstPenModel;
public TableNotebook(String name, int initChag, String pen) {
super(name, initChag);
regstPenModel = pen;
}
public void write(String penInfo) {
if (battery < 1) {
System.out.println("충전이 필요합니다.");
return;
}
if (regstPenModel.compareTo(penInfo) != 0) {
System.out.println("등록된 펜이 아닙니다.");
return;
}
System.out.println("필기 내용을 처리합니다,");
battery -= 1;
}
}
public class Inheritance {
public static void main(String[] args) {
NotebookComp nc = new NotebookComp("이수종", 5);
TableNotebook tn = new TableNotebook("정수영", 5, "ISE-241");
nc.movingCal();
tn.write("ISE-241");
}
}
다음 내용 참고
[Java] 클래스 간의 관계
이전 내용 참고 [Java] 상속 상속 • 부모가 자식에게 물려주는 행위 • 자식(하위, 파생) 클래스가 부모(상위) 클래스의 멤버를 물려받는 것, 자식이 부모를 선택해 물려받는다. • 기존의 클래스
haaland09009.tistory.com
'Back-End > JAVA' 카테고리의 다른 글
[Java] collection (0) | 2023.03.11 |
---|---|
[Java] Object 클래스, equals(), toString() (2) | 2023.03.11 |
[Java] 클래스 간의 관계 - 포함관계 (0) | 2023.03.11 |
[Java] 다형성, 오버라이딩 (1) (0) | 2023.03.10 |
[Java] 메서드 (0) | 2023.03.10 |