728x90
상속
매 클래스마다 중복된 필드, 메소드들을 단 한 번 또는 하나의 클래스(부모클래스)로 정의해둔 후 해당클래스의 내용을 가져다 쓰는 개념. 기존의 클래스를 이용해서 새로운 클래스를 만든다.
>> 상속의 특징
- 클래스 간의 다중상속 불가능(단일 상속만 가능)
- 명시되어 있찌는 않지만 모든 클래스는 object 클래스의 후손이다.
(모든 클래스란? 내가 만든 클래스, 자바에서 이미 제공하고 있는 클래스)
>> 상속의 장점
- 중복된 코드를 공통적으로 관리할 수 있음
=> 새로운 코드를 작성하하거나 수정할 때 용이
=> 보다 적은 양의 코드로 새로운 클래스를 만들 수 있음
- 프로그램의 생산성과 가독성을 높이고, 유지보수에 크게 기여함.
728x90
오버라이딩
- 상속받고 있는 부모클래스의 메소드를 자식클래스에서 재정의(재작성)하는 것
- 부모클래스가 제공하고 있는 메소드를 자식이 일부 고쳐서 사용하겠다는 의미
- 자식클래스의 오버라이드 된 메소드가 우선권을 가져서 호출된다.
- 성립조건
* 부모메소드의 메소드명과 동일해야 한다.
* 매개변수의 자료형, 개수, 순서가 동일해야 한다. 매개변수명과는 무관
* 반환형이 동일해야 한다.
* 접근 제어자를 조상클래스의 메소드보다 좋은 범위로 변경할 수 없다.
* 예외는 조상 클래스의 메소드보다 많이 선언할 수 없다.
- @Override
어노테이션 => 생략 가능. 명시를 하지 않아도 부모메소드의 형태가 같으면 오버라이딩 된 것으로 판단.
>> 예제
[ Product.java ]
public class Product {
// 공통되는 필드 : brand, pCode, pName, price
// [필드부]
private String brand;
private String pCode;
private String pName;
private int price;
// [생성자부]
public Product() {
}
public Product(String brand, String pCode, String pName, int price) {
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 + "\npCode : " + pCode + "\npName : " + pName +
"\nprice : " + price ; }
}
[ Desktop.java ]
//자식클래스 extends 부모클래스이름
public class Desktop extends Product {
// [필드부]
// brand, pCode, pName, price,
private boolean allInOne;
// [생성자부]
public Desktop() {
}
// brand, pCode, pName, price : 부모클래스인 Product에 있는 필드에 초기화가 된다.
public Desktop(String brand, String pCode, String pName, int price, boolean allInOne) {
// 1. 부모클래스의 필드들의 접근제한자를 private에서 protected로 변경
// 2. 부모클래스의 setter를 이용해서 PRoduct의 필드를 초기화 시켜주는 방법
// 3. 부모틀래스의 생성자를 호출하여 Product의 필드를 초기화 시켜주는 방법 => 주로 이 방법을 많이 사용
// 부모클래스에 있는 녀석들을 가져다 쓰기 위해서는 어떻게 해야 할까?
// super.로 부모에 접근이 가능
// 매개변수가 있는 부모클래스의 생성자 호출
super(brand, pCode, pName, price);
this.allInOne = allInOne;
}
// [메소드부]
// 오버라이딩이라는 개념이 적용가능
// brand, pCode, pName,price에 대한 setter/getter는 작성하지 않아도 호출이 가능 => 상속받았으니까
// allInOne에 대한 setter/getter 작성
public boolean isAllInOne() {
return allInOne;
}
public void setAllInOne(boolean allInOne) {
this.allInOne = allInOne;
}
public String information() {
return super.information() + "\nallInOne : "+ allInOne;
}
}
[ SmartPhone.java ]
//자식클래스이름 extends 부모클래스이름
public class SmartPhone extends Product { // extends
// [필드부]
public String mobileAgency;
// + brand, pCode, pName, price => Product클래스에게 상속받음
// [생성자부]
// 생성자는 상속받을 수 없다.
public SmartPhone() {
}
// 초기화를 모두 진행할 생성자
public SmartPhone(String brand,String pCode, String pName, int price, String mobileAgency) {
/*
super : 해당 부모의 주소를 담고 있다. (즉, super. 부모에 접근가능)
단, 접근하고자하는 그 어떤 것이 private일 경우 외부에서는 접근이 불가능하다(자식클래스도 접근불가)
super.brand = brand; => 불가능. 접근제한자가 private이기 때문
필드를 찾을 수 없음
해결방법 1. 부모클래스의 필드를 자식까지는 접근 가능하도록 설정(private => protected)
=> 캡슐화 원칙X (적잡한 방법은 아님)
해결방법 2. 부모클래스에 있는 public 접근제한자인 setter메소드를 호출한다
super.setBrand(brand);
super.setpCode(pCo de);
super.setpName(pName);
super.setPrice(price);
this.mobileAgency = mobileAgency;
해결방법 3. 부모 생성자 호출
super(brand, pCode, pName, price);
*/
super(brand, pCode, pName, price);
this.mobileAgency = mobileAgency;
}
// [메소드부]
// mobileAgency에 대한 getter/setter
public String getMobileAgency() {
return mobileAgency;
}
public void setMobileAgency(String mobileAgency) {
this.mobileAgency = mobileAgency;
}
}
[ TV.java ]
public class TV extends Product {
// [필드부]
// brand, pCode, pName, price, inch
private int inch;
// [생성자부]
// 기본생성자
public TV() {
}
// 모든 필드에 대해 매개변수가 있는 생성자
public TV(String brand, String pCode, String pName, int price, int inch) {
// 부모에 있는 필드나 메소드에 접근하고자 할때는?
// super.brand = // 해당 필드가 private 이므로 접근 불가
// 해결방법1. 부모의 private을 protected로 바꾼다.
// 해결방법2. 부모의 setter 메소드를 호출해서 초기화한다. super.set필드이름();
// 해결방법3. 부모의 모든 매개변수가 있는 생성자를 호출해서 초기화한다. super(매개변수들);
//2번 방법 이용
super.setBrand(brand);
super.setpCode(pCode);
super.setpName(pName);
super.setPrice(price);
this.inch = inch;
}
// [메소드부]
public int getInch() {
return inch;
}
public void setInch(int inch) {
this.inch = inch;
}
public String information() {
return super.information() + "\ninch : " + inch;
}
}
[ Run.java }
public class afterRun {
public static void main(String[] args) {
SmartPhone s = new SmartPhone("애플","app13","아이폰14", 1000000,"SKT");
System.out.println(s.information());
System.out.println();
Desktop d = new Desktop("애플","d01","앱플데스트톱",5000000,true);
System.out.println(d.information());
System.out.println();
TV t = new TV("엘지","tv01","엘지티비",8000000,70);
System.out.println(t.information());
}
728x90
'Programming > JAVA' 카테고리의 다른 글
[JAVA] 다형성(2) / 추상클래스 / 관련 예제 (0) | 2023.12.27 |
---|---|
[JAVA] 다형성 / 형변환 / 관련 예제 (1) | 2023.12.27 |
[JAVA] 객체 배열 (0) | 2023.12.27 |
[JAVA] 필드(Field) / 메소드(Method) / 관련 예제 (1) | 2023.12.22 |
[JAVA] 객체지향 프로그래밍 / setter, getter / 캡슐화 encapsulation (0) | 2023.12.22 |