자바 클래스를 만들 때, 클래스 간의 관계를 판단해보자.
- is a 관계
- has a 관계
🚗 예1) 자동차 클래스 - 엔진 클래스, 바퀴 클래스 ...
📱 예2) 휴대폰 클래스 - 아이폰 클래스, 안드로이드폰 클래스 ...
- '물려받는다'는 의미
- B클래스가 A클래스를 상속받으면, B클래스는 A클래스가 가지고 있는 구성원(멤버변수, 메서드) 사용할 수 있음
- ⚡ 자바에서는 모든 클래스가 다른 클래스를 상속받는데, 그 최초의 부모클래스는
Object
클래스이다 ⚡
문법:
class B
extends
A
{ ... }
고객 정보를 관리하는 'Customer' 클래스가 있을 때, 이 클래스의 구성요소를 모두 포함하면서 새로운 속성과 기능을 가진 'VIPCustomer' 클래스를 만들어보자.
<Customer.java>
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
}
<VIPCustomer.java>
public class VIPCustomer extends Customer {
// 자식클래스인 VIPCustomer 클래스만의 멤버변수
double saleRatio;
}
<CustomerTest.java>
public class CustomerTest {
public static void main(String[] args) {
VIPCustomer vc1 = new VIPCustomer();
// VIPCustomer 클래스는 customerName 멤버변수가 없지만,
// Customer 클래스로부터 상속받았기 때문에 사용 가능
vc1.customerName = "홍길동";
System.out.println(vc1.customerName); // 홍길동
}
}
부모클래스인 Customer 클래스에 아래와 같이 생성자를 구현했을 때,
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
// 생성자를 직접 구현 ( => 디폴트 생성자 안만들어짐)
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "Silver";
}
}
VIPCustomer.java에서는 오류가 발생한다.
VIPCustomer 클래스의 생성자를 명시하지 않았기 때문에, 컴파일시에 디폴트생성자와 그 안에 super()가 자동 생성된다.
super()가 부모클래스의 디폴트생성자를 호출해야 하는데, Customer클래스에는 디폴트생성자가 없어 오류가 발생하는 것이다.
아래와 같이 VIPCustomer 클래스의 생성자와 super()를 명시해준다.
public class VIPCustomer extends Customer {
double saleRatio;
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName); // 부모클래스의 생성자 호출
super.customerGrade = "VIP"; // 부모클래스의 멤버변수 참조
saleRatio = 0.1;
}
}
- 부모클래스의 메서드를 자식클래스에서 재정의
- 메서드의 반환형, 이름, 매개변수 개수/자료형이 모두 같아야 함
(그렇지 않으면 다른 메서드로 인식됨)
<Customer.java>
public class Customer {
protected int customerID;
protected String customerName;
protected String customerGrade;
public Customer(int customerID, String customerName) {
this.customerID = customerID;
this.customerName = customerName;
customerGrade = "Silver";
}
// 가격을 반환하는 메서드
public double calcPrice(double price) {
return price;
}
// VIP손님은 정가를 반환하지 않을 거라서 재정의 필요
}
<VIPCustomer.java>
public class VIPCustomer extends Customer {
double saleRatio;
public VIPCustomer(int customerID, String customerName) {
super(customerID, customerName);
super.customerGrade = "VIP";
saleRatio = 0.1;
}
// 메소드 오버라이딩
@Override
public double calcPrice(double price) {
return price * (1-saleRatio);
}
// VIPCustomer 클래스에 맞게 재정의해서 사용
}
- 하나의 코드가 여러 자료형으로 구현되어 실행되는 것을 뜻함
- 필요에 따라 상속받은 모든 클래스를 하나의 상위 클래스로 처리하거나, 다형성에 의해 각 자식클래스의 구현을 실행할 수 있음
Customer vc = new VIPCustomer();
public class CustomerTest {
public static void main(String[] args) {
Customer c = new Customer(10, "김철수");
VIPCustomer v = new VIPCustomer(11, "홍길동");
// 묵시적 형변환
Customer vc = new VIPCustomer(12, "알파카");
System.out.println(v.saleRatio); // 0.1
// System.out.println(vc.saleRatio);
// vc는 Customer 클래스를 참조하는 변수이므로, saleRatio 변수에 접근 불가
}
}
변수
와 메서드
가 사용하는 메모리는 다르다.스택 메모리
에 생성됨메서드 영역
에 생성됨public class CustomerTest {
public static void main(String[] args) {
Customer c = new Customer(10, "김철수");
VIPCustomer v = new VIPCustomer(11, "홍길동");
Customer vc = new VIPCustomer(12, "알파카");
System.out.println(c.calcPrice(1000)); // 1000.0
System.out.println(v.calcPrice(1000)); // 900.0
// 가상메서드
System.out.println(vc.calcPrice(1000)); // 900.0
}
}