- is-a 관계가 성립하는 객체간의 관계
- 슈퍼클래스(부모)의 모든 멤버를 서브클래스(자식)에게 물려받아 선언없이 사용하는 것
- 슈퍼클래스(Super Class) = 부모 클래스 = 상위클래스 = 조상클래스 서브클래스(Sub Class) = 자식 클래스 = 하위클래스 = 자손클래스
- private 접근제한자 지정된 멤버는 상속 대상에서 제외됨
- 생성자는 상속 대상에서 제외됨 => 생성자의 이름은 자신의 클래스 이어야만 함 상속받은 생성자는 부모의 클래스 이름이므로 규칙에 위배되기 때문
- 자바는 단일 상속만 지원함 => 두 개 이상의 슈퍼클래스(부모)를 지정할 수 없음
- 별도로 상속 대상을 지정하지 않을 경우(extends 생략할 경우) java.lang.Object 클래스를 자동으로 상속받음 ⇒ java.lang.Object 클래스를 자바의 최상위 클래스라고함
상속의 기본 문법
class 서브클래스명 extends 슈퍼클래스명 {}
} //Ex class 끝
// 슈퍼클래스에 해당하는 parent 클래스 정의
class Parent { // (=class Parent extends Objec)와 동일함
int num; // 슈퍼클래스의 멤버변수
public void parentPrn() {
System.out.println("슈퍼클래스의 parentPrn()");
}
}
// 슈퍼클래스인 parent 클래스를 상속받는 서브클래스 Child 정의
// => Child 클래스 선언부에 extends 키워드를 쓰고 슈퍼클래스인 Parent 명시
class Child extends Parent {
// Parent 클래스를 상속받게 되면 Child 클래스에서 선언하지 않은 멤버(=Parent의 멤버)도 사용 가능해짐
public void childPrn() {
System.out.println("서브클래스의 childPrn()");
}
public void showNum() {
// 슈퍼클래스의 멤버변수 num에 접근 가능
System.out.println("부모로부터 상속받은 멤버변수 num = " + num);
}
}
➡️ 부모클래스의 멤버변수
슈퍼클래스 parent로부터 상속받은 int형의 멤버변수
// 서브클래스 Child 인스턴스 생성
Child c = new Child();
c.childPrn(); // 서브클래스에서 직접 정의한 메서드
// Child 클래스는 자신의 클래스 내의 멤버뿐만 아니라
// 슈퍼클래스인 Parent 클래스의 멤버도 아무런 선언없이 사용 가능
c.num = 10; // 슈퍼클래스 Parent로부터 상속받은 멤버변수
c.parentPrn(); // 슈퍼클래스 Parent로부터 상속받은 메서드
c.showNum();
} // main() 메서드 끝
class 할아버지 {
String 집 = "고층 아파트";
String 티비 = "최신형 티비";
public void 그림그리기() {
System.out.println("그림을 잘 그린다!");
}
}
// 할아버지 클래스를 상속받는 아버지 클래스 정의
// 멤버변수 : 자동차("스포츠카")
// 메서드 : 노래하기 ("노래를 잘한다!" 출력)
class 아버지 extends 할아버지 {
String 자동차 = "스포츠카";
public void 노래하기() {
System.out.println("노래를 잘한다!");
}
}
// 아버지 클래스 상속받는 나 클래스 정의
// 멤버변수, 메서드 하나씩 정의
class 나 extends 아버지 {
String 폰 = "스마트폰";
public void 프로그래밍() {
System.out.println("프로그래밍을 잘한다!");
}
}
// 나 클래스 인스턴스 생성
나 나 = new 나();
// 나 클래스 자신의 멤버
System.out.println("내폰 : " + 나.폰);
나.프로그래밍();
// 아버지 클래스로부터 상속받은 멤버
System.out.println("내 자동차 : " + 나.자동차);
나.노래하기();
// 할아버지 클래스로부터 상속받은 아버지 클래스로부터 상속받은 멤버변수
System.out.println("내 집 : " + 나.집);
System.out.println("내 티비 : " + 나.티비);
나.그림그리기();
} // main() 메서드 끝
🌟private 접근제한자 지정된 멤버는 상속 대상에서 제외됨
Account 클래스를 상속받는 ItwillBank 클래스 정의
-Account의 기본 기능(계좌의 기본 기능)은 그대로 유지
=> 계좌번호(accountNo), 예금주명(ownerName), 현재잔고(balance) 멤버변수
=> 입금하기(deposit), 출금하기(withdraw), 정보보기(showAccountInfo) 메서드
- 멤버변수 추가 : 보험명(insureName, 문자열)
- 메서드 추가 : 보험계약(contract())
=> 파라미터 : 보험명, 리턴값 없음
=> 전달받은 보험명을 멤버변수에 저장 후 "XXX 보험 계약 완료!" 출력
} // Test 클래스 끝
class ItwillBank extends Account {
String insureName;
public void contract(String insureName) {
this.insureName = insureName; // this.insureName = itwillbank.insureName
System.out.println(insureName + "계약 완료!");
}
}
class Account { // =class Account extends Object
String accountNo;
String ownerName;
int balance;
public void showAccountInfo() {
System.out.println("계좌번호 : " + accountNo);
System.out.println("예금주명 : " + ownerName);
System.out.println("현재잔고 : " + balance);
}
// 입금기능
public void deposit(int amount) {
balance += amount;
System.out.println("입금하신 금액 : " + amount + "원");
showAccountInfo();
}
// 출금기능
public int withdraw(int amount) {
if(balance < amount) {
System.out.println("출금불가 : 잔액 부족");
System.out.println("출금할 금액 : " + amount + "원, 현재잔고 : " + balance + "원");
amount=0;
} else { // 현재잔고 >= 출금금액
balance -= amount;
System.out.println("출금할 금액 : " + amount + "원");
System.out.println("출금후 현재잔고 : " + balance + "원");
}
return amount;
}
}
// Account로부터 상속받은 기본 멤버 접근
ItwillBank ib = new ItwillBank();
ib.accountNo="111-1111-111";
ib.ownerName="땅콩";
ib.balance=10000;
ib.showAccountInfo();
ib.deposit(50000);
int money = ib.withdraw(40000);
System.out.println("출금된 금액 : "+ money + "원");
System.out.println("-------------------------------");
//ItwillBank의 고유기능(추가된 기능)
ib.contract("고양이 보험 ");
상속의 장점
- 코드 재사용성이 증가
- 코드의 유지보수성이 용이해짐
} // Ex2 class 끝
// 2차원 좌표(x,y)를 관리하는 Point2D 클래스
class Point2d {
int x = 10; // x좌표
int y = 20; // y좌표
// 2차원 좌표값을 출력하는 print2D() 메서드 정의
public void print2D() {
System.out.print("x좌표 : " + x + ", y좌표 : " + y);
}
}
// 3차원 좌표(x,y,z)를 관리하는 Point3D 클래스
// => x,y 좌표 관리 기능은 기본적으로 Point2D 클래스와 중복되므로 상속
class Point3D extends Point2d {
int z = 30; // z좌표
//3차원 좌표값을 출력하는 print3D() 메서드 정의
public void print3D() {
print2D();
System.out.println(", z좌표 : " + z);
}
}
Point3D p = new Point3D();
p.print3D();
} // main() 메서드 끝
⇒ 위 코드를 통해 코드의 재사용성을 확인 가능
코드의 유지보수성 확인!
public void print2D() {
// System.out.print("x좌표 : " + x + ", y좌표 : " + y);
// 슈퍼클래스의 메서드를 수정하면
// 서브클래스인 Print3D 클래스에서 수정 내용에 대한 적용을 받을 수 있음
System.out.print(x + ", " + y);
}
}
코드의 재사용성을 확인하는 예제
직원(Employee) 클래스
멤버변수
- 직원이름(name, 문자열)
- 연봉(salary, 정수)
메서드
- 직원 정보를 문자열로 결합하여 리턴하는 getEmployee() 메서드 정의
(파라미터 없음, 리턴값 없음)
ex) 홍길동, 4000
Employee 클래스를 상속받는 Manager 클래스 정의
- 이름, 연봉, 부서명(depart, 문자열) 멤버변수
- 이름, 연봉, 부서명을 문자열로 결합하여 리턴하는 getManager() 메서드
ex) 홍길동, 4000, 개발팀
/*
* 직원(Employee) 클래스
* 멤버변수
* - 직원이름(name, 문자열)
* - 연봉(salary, 정수)
* 메서드
* - 직원 정보를 문자열로 결합하여 리턴하는 getEmployee() 메서드 정의
* (파라미터 없음, 리턴값 있음)
* => 직원이름과 연봉을 문자열로 결합하여 리턴
* ex) 홍길동, 4000
*/
class Employee {
String name;
int salary;
public String getEmployee() {
return name + ", " + salary;
}
}
/*
* Employee 클래스를 상속받는 Manager 클래스 정의
* - 이름, 연봉, 부서명(depart, 문자열) 멤버변수
* - 이름, 연봉, 부서명을 문자열로 결합하여 리턴하는 getManager() 메서드
* ex) 홍길동, 4000, 개발팀
*/
class Manager extends Employee {
String depart; // 부서명
public Manager(String name, int salary, String depart) {
this.name = name;
this.salary = salary;
this.depart = depart;
}
public String getManager() {
// return name + ", " + salary + ", " + depart;
// 슈퍼클래스의 getEmployee() 메서드를 재사용하여
// 리턴값과 부서명을 결합 후 다시 리턴
return getEmployee() + ", " + depart;
}
}
public class Test2 {
public static void main(String[] args) {
Manager m = new Manager("홍길동", 4000, "개발팀");
System.out.println(m.getManager());
}
}
'JAVA' 카테고리의 다른 글
[JAVA] 상속에서의 생성자 (0) | 2023.09.18 |
---|---|
[JAVA] has-a 관계(포함) vs is-a 관계(상속) (0) | 2023.09.18 |
[JAVA] 싱글톤 디자인 패턴(Singleton Design pattern) (0) | 2023.09.13 |
[JAVA] static 키워드 (0) | 2023.09.13 |
[JAVA] import 키워드 (1) | 2023.09.13 |