1. 상속(Inherit)
: 매 클래스마다 중복된 필드와 메소드를 하나의 클래스(부모 클래스)로 모아서 정의한 후 상속을 받아
자식 클래스가 자신의 필드와 메소드처럼 사용하는 개념
(1) 목적
: 클래스를 재사용하기 위해, 연관된 클래스들에 대해 공통적인 규약을 정의하기 위해
(2) 특징
① 클래스 간에 다중 상속은 불가하고, 단일 상속만 가능하다.
ⓐ 단일 상속: Java에서는 하나의 부모클래스에게만 상속받을 수 있다.(여러 부모클래스에게 상속받을 수 없다.)
② 모든 클래스는 Object 클래스의 후손이다.
ⓐ 모든 클래스에는 이미 만들어진 클래스와 새로 만들 클래스들이 모두 포함되어 있다.
ⓑ Object 클래스에 있는 메소드들을 사용할 수 있다.
ⓒ Object 클래스에서 상속 받은 메소드를 오버라이딩(Overriding)으로 재정의하여 사용할 수 있다.
- 실행하고자 하는 메소드가 자식 클래스에 존재하지 않으면 자동으로 해당 클래스의 부모 클래스에 있는
메소드로 호출된다.
- 단, 자식 클래스에 오버라이딩한 메소드가 있으면 그 메소드가 호출된다. → 오버라이딩한 메소드가 우선권을
가진다.
(3) 표현법
접근제한자 class 클래스명 extends 클래스명 {}
public class Apple extends Fruit {}
// 자식클래스 extends 부모클래스
(4) super()와 super.
① super()
: 부모 객체의 생성자를 호출하는 메소드(자식 생성자에 부모 생성자가 포함된다.)
ⓐ 자식 클래스의 생성자 안에 부모 생성자를 호출하는 'super()'가 "첫 번째 줄"에 와야 한다.(부모 생성자가 제일
먼저 실행되어야 하기 때문이다.)
ⓑ 매개변수가 있는 부모 생성자를 호출할 땐 'super(매개변수)'로 작성하면 된다.
② super.
: 자식 클래스에서 정의할 때에 부모 객체를 가리키는 참조변수
ⓐ 자식 클래스 내에서 부모 클래스의 필드나 메소드를 호출할 때 사용한다.
부모 클래스 Product
// 필드
public class Product { // 부모 클래스를 조상 클래스 또는 super 클래스라고도 부른다.
private String brand;
private String name; // 자손 클래스 간의 공통된 변수들을 부모 클래스로 한번에 정의
private int price;
// 생성자
public Product() { // 기본 생성자
}
public Product(String brand, String name, int price) {
super(); // 이 super();는 생략 가능.
this.brand = brand;
this.name = name;
this.price = price;
}
// 메소드
// 각 매개변수들 setter/getter 메소드 생성
중간 과정 생략;
public String information() {
return brand + " " + name + " " + price;
}
}
자식 클래스 Phone
// 필드
public class Phone extends Product {
private String Agency; // 공통된 변수를 제외한 자식 클래스의 고유한 변수
// 생성자
public Phone() { // 기본 생성자
}
public Phone(String brand, String name, int price, String agency) {
super(brand, name, price, agency); // 부모 생성자를 호출하여 super()로 한번에 초기화
this.agency = agency; // 같은 클래스 내에 있는 메소드 호출(this.)
}
// 메소드
// 매개변수 agency setter/getter 메소드 생성
중간 과정 생략;
@Override
public String information() {
return super.information() + " " + agnecy;
// 자식 클래스에서 정의할 때 부모 객체를 가리키는 참조변수 super.를 사용하여
// 부모 메소드 information()을 자식 클래스로 호출
}
}
(5) 장점
① 적은 양의 코드로 새로운 클래스를 작성할 수 있다.
② 부모 클래스에서 코드를 공통으로 관리하므로 코드를 추가하고 변경하는 데에 용이하다.
③ 중복된 코드를 제거하기 때문에 프로그램의 생산성과 유지보수에 좋다.
2. 오버라이딩(Overriding)
(1) 의미
: 자식 클래스가 상속 받은 부모 클래스를 재정의하는 것(부모 클래스가 상속하는 메소드를 다르게 고쳐서
사용하겠다는 뜻으로, 이때는 오버라이딩한 자식 클래스의 메소드가 우선권을 가진다.)
(2) 특징
① 오버라이딩한 메소드 윗줄에 반드시 Annotation, '@Override'를 표시해야 한다.
② 접근제어자를 부모 클래스와 같거나 부모 클래스보다 넓은 범위로 변경할 수 있다.
③ 부모 메소드의 예외 처리 클래스 처리 범위보다 좁은 범위로 예외 처리 클래스를 수정할 수 있다.
(3) 성립 조건
① 부모 클래스의 메소드명과 자식 클래스의 메소드명이 동일해야 한다.
② 서로 매개변수의 타입과 개수가 동일해야 한다.
③ 리턴(return) 타입도 동일해야 한다.
④ 단, private 메소드는 오버라이딩할 수 없다.
(4) 오버로딩(Overloading)과의 비교★★
구분 | 오버라이딩(Overriding) | 오버로딩(Overloading) |
위치 | 하위 클래스에서 메소드를 정의 | 같은 클래스 내에서 메소드를 정의 |
성립 조건 | 메소드명과 매개변수의 타입, 개수, 순서가 동일해야 하며, 리턴(return) 타입도 동일해야 함 | 메소드명이 동일해야 하고, 매개변수의 타입과 개수, 순서는 달라야 함 리턴(return) 타입은 상관 없음 |
접근 범위 | 자식 메소드의 접근 범위가 부모 메소드보다 같거나 넓어야 함 | 접근제어자와 상관 없음 |
예외 처리 | 자식 메소드의 예외 처리 클래스 처리 범위가 부모 메소드보다 좁아야 함 | 예외처리와 상관 없음 |
[오버라이딩(Overriding)]
공통 메소드가 String brand(), String name(), int price()라고 하면
public class Product { // 부모 클래스 Product
중간 과정 생략;
public String information() {
return brand + " " + name + " " + price;
}
}
public class Phone extends Product { // 부모 클래스 Product에게 상속받은 자식 클래스 Phone
중간 과정 생략;
// 부모 클래스의 메소드에 "자신만의 메소드를 추가"하고 싶다면 "오버라이딩"을 한다.
@Override // 어노테이션은 꼭 적어주기!
public String information() {
return super.information() + " " + Agency;
// 부모 메소드의 형태는 return 타입까지 똑같이 유지한다.
// 그리고 부모 메소드를 호출하는 'super.부모메소드명()'을 사용하여 해당 값을 그대로 옮기고
// 자신만의 메소드(Agency)를 추가하면 오버라이딩이 된 메소드가 된다.
// 이렇게 오버라이딩 된 자식 메소드는 부모 메소드보다 우선권을 가지므로
// 실행시키면 자식 메소드가 출력된다.
}
}
[오버로딩(Overloading)]
public class Product {
private String brand();
private String name();
private int price();
public Product(String brand) { // 자신 클래스명의 메소드
this.brand = brand; // 자기 클래스 내에서 메소드를 가져다 쓰므로 this.를 사용
}
public Product(String brand, String name) { // 매개변수의 개수가 다름
this.brand = brand;
this.name = name;
}
public Product(String name, String brand) { // 매개변수의 순서가 다름
this.name = name;
this.brand = brand;
}
public Product(String brand, String name, int price) { // 매개변수의 개수가 다름
this.brand = brand;
this.name = name;
this.price = price;
}
}
3. 예약어
(1) final 예약어
① final 클래스: 상속이 불가능한 클래스
public final class Name {}
② final 메소드: 상속 시 오버라이딩이 불가한 메소드
public final void method() {}
(2) 대상별로 사용할 수 있는 접근제어자, 예약어
대상 | 사용할 수 있는 접근제어자 / 예약어 |
클래스 | public, (default), final, abstract |
메소드 | 모든 접근제어자, final, abstract, static |
변수 | 모든 접근제어자, final, static |
지역변수 | final |