고래씌
[JAVA] 9. 상속 & 오버라이딩 본문
1. 상속
1) 상속을 쓰는 이유?
☞ 매 클래스마다 중복된 코드들을 일일이 기술해두게 되면 수정, 추가, 삭제시 매번 일일이 찾아가서 수정을 해야하는 번거로움이 생긴다.
ex) 필드명 수정, 새로운 필드가 추가시
☞ 상속이라는 개념을 적용시켜서 매 클래스마다 "중복된" 필드, 메소드들을 단 한번 또 하나의 클래스에 정의해둔뒤, 해당 클래스를 상속받아서 부모클래스의 필드와 메소드를 가져다 쓰는 방식으로 코드의 중복을 피해야한다.
super(); => 자기보다 상위의 존재를 말함. 즉, 부모클래스의 생성자 호출을 의미!
=> 부모클래스의 주소값을 보관하고 있음.
=> super.으로 부모에 접근이 가능
☞ super(brand, pCode, pName, price) 로 작성하여도 되고,
super.setBrrand(brand);
super.setpCode(pCode);
super.setpName(pName);
super.setPrice(price); 으로 작성하여도 된다
=> super는 보이지 않지만 생성된 Product의 주소값을 보관하고 있음!
2) 상속의 장점
▶ 보다 적은 양의 코드로 새로운 클래스들을 작성 가능
▶ 중복된 코드를 공통적으로 관리하기 때문에 새로운 코드를 추가하거나 수정할 때 용이함
=> 프로그램의 생산성 증대 및 유지보수에 크게 기여한다.
3) 상속의 특징
▶ 클래스간의 상속은 다중상속이 불가능함(단일 상속만 가능)
▶ 부모의 private 멤버는 상속은 되지만 직접 접근 불가. 자식 생성자 안에서 부모의 private 필드에 직접 접근하여 대입 불가능하다! super() 이용하여 부모 생성자쪽으로 넘겨 생성하거나 setter, getter 메소드를 이용하여 접근
▶ 명시되어있지 않지만 모든클래스는 Object클래스의 후손
=> Object클래스에 있는 메소드를 모든 클래스에서 사용이 가능함.
=> Object클래스에 있는 메소드가 마음에 안들면 오버라이딩을 통해 재정의 가능
우리 눈에 보이진 않지만 우리는 계속 public class Product extends Object 를 사용하고 있었다!
2. 오버라이딩
: 부모클래스에 이미 존재하는 메소드를 재정의(override)하는 것
☞ 실행하고자 하는 메소드가 자식클래스에 없다면, 자동으로 부모클래스에 있는 메소드가 실행됨.
단, 자식클래스에서 재정의된(오버라이딩된) 메소드가 있을 경우 자식클래스에 있는 메소드가 실행에서 ★우선권을 가진다.
<오버라이딩>
- 상속받고 있는 부모클래스의 메소드를 자식 클래스에서 재정의(재작성)하는 것
- 부모가 제공하고 있는 메소드를 자식이 일부 고쳐서 사용하겠다는 의미.(실행 우선권은 자식메소드에게 있다)
1) ★오버라이딩 성립조건
- 부모메소드의 메소드명과 동일해야함
- 매개변수 자료형, 개수, 순서가 정확하게 일치해야함
- 반환형이 일치해야함
- 부모메소드의 접근제한자보다 같거나 공유범위가 더 커야한다.
- private 메소드, final 메소드 오버라이딩 불가
2) @Override 어노테이션
- 생략가능(명시를 안해도 부모메소드와 형태가 같으면 오버라이딩이 된 것)
- 그럼에도 불구하고 어노테이션을 붙이는 이유?
→ 잘못 기술했을 경우(성립조건과 다르게)오류를 알려주기 때문에 다시한번 검토할 수 있게 유도한다.
→ 혹시라도 부모메소드가 나중에 수정이 되었을 경우 오류를 알려주기 때문에 검토할 수 있게 유도한다.
→ 이 메소드가 오버라이딩된 메소드라는걸 알리고자 하는 목적이 큼.
3) 주의 사항
- 메소드의 리턴타입은 오버로딩 조건과 관계 없음. 여기서 <- 오버라이딩과 오버로딩의 차이점!
▶ 출력문 안에 참조형변수(레퍼런스 변수)를 제시해서 출력하고자 할 때, 내부적으로 JVM이 자동으로 toString()메소드를 호출한다.
▶ 부모클래스인 Object클래스에 있는 toString()
해당 참조형의 풀클래스명 + @ + 해당객체의 주소값
▶ 자식클래스인 Book클래스에서 toString()메소드를 재정의시
해당 객체의 모든 필드값을 하나의 문자열로 합쳐서 돌려줄 수 있다.
▶ 모든 클래스는 Object클래스의 후손이다. 즉 항상 최상위클래스는 Object
=> 즉, Object에 있는 모든 메소드들을 다 가져다 쓸 수 있음. 마음에 들지 않으면 재정의가 가능함.
▶ 메소드 오버라이딩 전 :
com.kh.chap03_override.model.vo.Book@16진수 주소값
▶ 메소드 오버라이딩 후 :
책 제목 : 수학의 정석, 책 저자 : 김길동, 15000
[Tv클래스 information() 메소드 주석]
☞ 부모클래스 Product 에 있는 informaion 메소드가 호출되어 출력된 것을 확인
[Product 클래스 - 부모클래스]
package com.kh.chap01_beforeVsAfter.after.model.vo;
public class Product {
// 세 클래스 모두 공통적으로 기술되어있던 요소들만 추출해서 정의해둔 클래스
private String brand;
private String pCode;
private String pName;
private int price;
public Product() {
}
public Product(String brand, String pCode, String pName, int price) {
super();
this.brand = brand;
this.pCode = pCode;
this.pName = pName;
this.price = price;
}
// 세 클래스 모두 공통적으로 기술되어있던 메소드
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getpCode() {
return pCode;
}
public void setpCode(String pCode) {
this.pCode = pCode;
}
public String getpName() {
return pName;
}
public void setpName(String pName) {
this.pName = pName;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String information() {
return "brand : " + brand + " pCode : " + pCode + " pName : " + pName + " price : " + price;
}
}
[Desktop - 자식클래스]
package com.kh.chap01_beforeVsAfter.after.model.vo;
// 자식 부모
// 후손 조상
// 하위 상위
public class Desktop extends Product{
private boolean allInOne;
public Desktop() {
// super(); // 자기보다 상위의 존재를 말함. 즉 부모클래스의 생성자 호출을 의미
// super. 으로 부모에 접근이 가능
}
public Desktop(String brand, String pCode, String pName, int price, boolean allInOne) {
// brand, pCode, pName, price를 부모클래스의 Product에 있는 필드에 초기화
// Product(String brand, String pCode, String pName, int price) 생성자 호출
// super(brand, pCode, pName, price);
// 아래에 이런 방법으로도 초기화가 가능하다!
super.setBrand(brand);
super.setpCode(pCode);
super.setpName(pName);
super.setPrice(price);
this.allInOne = allInOne;
}
public boolean isAllInOne() {
return allInOne;
}
public void setAllInOne(boolean allInOne) {
this.allInOne = allInOne;
}
// 오버라이딩 : 부모클래스에 이미 존재하는 메소드를 재정의(override)하는 것
public String information() {
return super.information() + " allInOne : " + allInOne;
}
}
[SmartPhone - 자식클래스]
package com.kh.chap01_beforeVsAfter.after.model.vo;
public class SmartPhone extends Product{
private String mobileAgency;
public SmartPhone() {
}
public SmartPhone(String brand, String pCode, String pName, int price, String mobileAgency) {
super(brand, pCode, pName, price);
this.mobileAgency = mobileAgency;
}
public String getMobileAgency() {
return mobileAgency;
}
public void setMobileAgency(String mobileAgency) {
this.mobileAgency = mobileAgency;
}
public String information() {
return super.information() + " moblieAgency : " + mobileAgency;
}
}
[Tv - 자식클래스]
package com.kh.chap01_beforeVsAfter.after.model.vo;
public class Tv extends Product{
private int inch;
public Tv() {
}
public Tv(String brand, String pCode, String pName, int price, int inch) {
super(brand,pCode, pName, price);
this.inch = inch;
}
public int getInch() {
return inch;
}
public void setInch(int inch) {
this.inch = inch;
}
// public String information() {
// return super.information() + " inch : " + inch;
// }
}
[Run 클래스]
package com.kh.chap01_beforeVsAfter.run;
import com.kh.chap01_beforeVsAfter.after.model.vo.*;
public class Run {
public static void main(String[] args) {
Desktop d = new Desktop("삼성", "d-01", "삼성데스크탑", 1_500_000, true);
SmartPhone sm = new SmartPhone("삼성", "s-01", "z-플립5", 1_500_000, "kt");
Tv t = new Tv("엘지", "t-01", "얇은 티비", 3_500_000, 60);
/*
* 실행하고자 하는 메소드가 자식클래스에 없다면, 자동으로 부모클래스에 있는 메소드가 실행됨.
* 단, 자식클래스에서 재정의된(오버라이딩된) 메소드가 있을 경우 자식클래스에 있는 메소드가
* 실행에서 우선권을 가진다.
*/
System.out.println(d.information());
System.out.println(sm.information());
System.out.println(t.information()); // Tv 클래스는 information 메소드를 주석하고
// 출력하면 부모클래스에 있는 information 메소드를 출력함
}
}
'JAVA > JAVA 기초' 카테고리의 다른 글
[JAVA] 상속 실습 문제 (0) | 2023.10.16 |
---|---|
[JAVA] 사원 프로그램 객체 실습 (0) | 2023.10.13 |
[JAVA] 8. 객체 배열 & 실습문제 (0) | 2023.10.13 |
[JAVA] 7-4. 오버로딩 & 클래스 실습문제 (0) | 2023.10.13 |
[JAVA] 7-3. 메소드(Method) (0) | 2023.10.12 |