08-1. 상속이란?
클래스 상속
- 새로운 클래스를 정의 할 때 이미 구현된 클래스를 상속(inheritance) 받아서 속성이나 기능을 확장하여 클래스를 구현함
- 이미 구현된 클래스보다 더 구체적인 기능을 가진 클래스를 구현해야 할 때 기존 클래스를 상속함
상속하는 클래스 : 상위 클래스, parent class, base class, super class 상속받는 클래스 : 하위 클래스, child class, derived class, subclass |
- 상속의 문법
class B extends A { } B클래스가 A클래스를 상속받는다 |
extends 키워드 뒤에는 단 하나의 클래스만 올 수 있음 자바는 단일 상속(single inheritance)만을 지원함 |
상속을 구현 하는 경우
- 상위 클래스는 하위 클래스 보다 더 일반적인 개념과 기능을 가짐
- 하위 클래스는 상위 클래스 보다 더 구체적인 개념과 기능을 가짐
- 하위 클래스가 상위 클래스의 속성과 기능을 확장 (extends)한다는 의미
상속을 활용한 멤버십 클래스 구현하기
멤버십 시나리오
회사에서 고객 정보를 활용한 맞춤 서비스를 하기 위해 일반고객(Customer)과 이보다 충성도가 높은 우수고객(VIPCustomer)에 따른 서비스를 제공하고자 함 물품을 구매 할 때 적용되는 할인율과 적립되는 보너스 포인트의 비율이 다름 여러 멤버십에 대한 각각 다양한 서비스를 제공할 수 있음 멤버십에 대한 구현을 클래스 상속을 활용하여 구현해보기 |
Customer 클래스 구현
- 고객의 속성 : 고객 아이디, 고개 이름, 고객 등급, 보너스 포인트 적립비율
- 일반 고객의 경우 물품 구매시 1%의 보너스 포인트 적립
package ingeritance;
public class Customer { //멤버 변수 protected int customerID; //고객아이디 protected String customerName; //고객이름 protected String customerGrade; //고객등급 int bonusPoint; //보너스포인트 double bonusRatio; //적립비율 //디폴트 생성자 public Customer() { customerGrade = "SILVER"; //기본등급 bonusRatio = 0.01; //보너스 포인트 기본 적립 비율 } //보너스 포인트 적립, 지불 가격 계산 메서드 public int calcPrice(int price) { bonusPoint += price * bonusRatio; //보너스 포인트 계산 return price; //얼마짜리를 샀다는 것을 반환 } //protected 예약어로 선언한 변수를 위해 get set 메서드 추가 public int getCustomerID() { return customerID; } public void setCustomerID(int customerID) { this.customerID = customerID; } public String getCustomerName() { return customerName; } public void setCustomerName(String customerName) { this.customerName = customerName; } public String getCustomerGrade() { return customerGrade; } public void setCustomerGrade(String customerGrade) { this.customerGrade = customerGrade; } //고객 정보를 반환하는 메서드 public String showCustomerInfo() { return customerName + " 님의 등급은" + customerGrade + "이며, 보너스 포인트는" + bonusPoint + "입니다."; } } |
VIPCustomer 클래스 구현
package ingeritance;
public class VIPCustomer extends Customer { //VIPCustomer 클래스는 Customer 클래스를 상속받는다 private int agentID; //VIP 고객 상담원 아이디 double saleRatio; //할인율 public VIPCustomer() { customerGrade = "VIP"; //상위 클래스에서 private 변수이므로 오류 발생 ㅡ> protected 예약어로 바꿔준다 bonusRatio = 0.05; saleRatio = 0.1; } public int getagentID() { return agentID; } } |
TEST 클래스 구현
package ingeritance;
public class Customertest1 { public static void main(String[] args) { Customer customerLee = new Customer(); customerLee.setCustomerID(10010); //protected 변수이므로 set()메서드 호출 customerLee.setCustomerName("이순신"); //protected 변수이므로 set()메서드 호출 customerLee.bonusPoint = 1000; System.out.println(customerLee.showCustomerInfo()); VIPCustomer customerKim = new VIPCustomer(); customerKim.setCustomerID(10020); customerKim.setCustomerName("김유신"); customerKim.bonusPoint = 10000; System.out.println(customerKim.showCustomerInfo()); } } |
출력
이순신 님의 등급은SILVER이며, 보너스 포인트는1000입니다.
김유신 님의 등급은VIP이며, 보너스 포인트는10000입니다. |
protected 접근 제어자
- 상위 클래스에 선언된 private 멤버 변수는 하위 클래스에서 접근 할 수 없음
- 외부 클래스는 접근 할 수 없지만, 하위 클래스는 접근 할 수 있도록 protected 접근 제어자를 사용
08-2. 상속에서 클래스 생성과 형 변환
하위 클래스가 생성 되는 과정
- 하위 클래스를 생성하면 상위 클래스가 먼저 생성 됨
- new VIPCustomer()를 호출하면 Customer()가 먼저 호출 됨
- 클래스가 상속 받은 경우 하위 클래스의 생성자에서는 반드시 상위 클래스의 생성자를 호출 함
상속에서 인스턴스 메모리의 상태
- 항상 상위 클래스의 인스턴스가 먼저 생성되고, 하위 클래스의 인스턴스가 생성 됨
형 변환(업캐스팅)
- 상위 클래스로 변수를 선언하고 하위 클래스의 생성자로 인스턴스를 생성 Customer customerLee = new VIPCustomer();
- 상위 클래스 타입의 변수에 하위 클래스 변수가 대입
- 하위 클래스는 상위 클래스의 타입을 내포하고 있으므로 상위 클래스로의 묵시적 형 변환이 가능함
- 상속 관계에서 모든 하위 클래스는 상위 클래스로 형 변환(업캐스팅)이 됨 (그 역은 성립하지 않음)
08-3. 메서드 오버라이딩 overring
하위 클래스에서 메서드 재정의 하기
- 오버라이딩(overriding) : 상위 클래스에 정의된 메서드의 구현 내용이 하위 클래스에서 구현할 내용과 맞지 않는 경우 하위 클래스에서 동일한 이름의 메서드를 재정의 할 수 있음
- VIPCustomer 클래스의 calcPrice()는 할인율이 적용되지 않음
- 재정의 하여 구현해야 함
@overriding 애노테이션 (annotation)
- 애노테이션은 원래 주석이라는 의미
- 컴파일러에게 특별한 정보를 제공해주는 역할
- @overriding 애노테이션은 '이 메서드는 재정의된 메서드입니다' 라고 컴파일러에게 명확히 알려주는 역할
- 코드에서 [오른쪽 마우스 버튼 클릭 ㅡ> Source ㅡ> Override/Implement Methods…]
![]() |
형 변환과 오버라이딩 메서드 호출
Customer vc = new VIPCustomer();
vc 변수의 타입은 Customer지만 인스턴스의 타입은 VIPCustomer 임
자바에서는 항상 인스턴스의 메서드가 호출 됨 (가상메서드의 원리)
자바의 모든 메서드는 가상 메서드(virtual method) 임
메서드는 어떻게 호출되고 실행 되는가?
- 메서드(함수)의 이름은 주소값을 나타냄
- 메서드는 명령어의 set(집합)이고 프로그램이 로드되면 메서드 영역(코드 영역)에 명령어 set이 위치
- 해당 메서드가 호출 되면 명령어 set이 있는 주소를 찾아 명령어가 실행됨
- 이때 메서드에서 사용하는 변수들은 스펙 메모리에 위치 하게 됨
- 따라서 다른 인스턴스라도 같은 메서드의 코드는 같으므로 같은 메서드가 호출됨
- 인스턴스가 생성되면 변수는 힙 메모리에 따로 생성되지만, 메서드 명령어 set은 처음 한번만 로드 됨
![]() |
가상 메서드의 원리
- 가상 메서드 테이블 (virtual method table)에서 해당 메서드에 대한 address를 가지고 있음
- 재정의 된 경우는 재정의 된 메서드의 주소를 가리킴
![]() |
![]() |
변수는 인스턴스가 생성될 때마다 새로 생성되지만
메서드는 실행해야 할 명령 집합이기 때문에 인스턴스가 달라도 같은 로직을 수행한다.
즉, 같은 객체의 인스턴스를 여러 개 생성한다고 해서 메서드도 여러 개 생성되지 않는다.
상위클래스(Customer)에서 선언한 calcPrice() 메서드가 있고 이를 하위클래스(VIPCustomer)에서
재정의한 상태에서 하위 클래스 인스턴스(vc)가 상위 클래스로 형변환이 되었다.
이때 vc.calcPrice()가 호출되면,
vc 변수를 선언할 때 사용한 자료형(Customer)의 메서드가 호출되는 것이 아니라
생성된 인스턴스(VIPCustomer)의 메서드가 호출된다.
이를 가상 메서드 라고 하고,
자바의 모든 메서드는 가상 메서드이다.
08-4. 다형성
다형성(polymorphism) 이란?
- 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
- 같은 코드에서 여러 다른 실행 결과가 나옴
- 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나임
- 다형성을 잘 활용하면 유연하고 확장성 있고, 유지보수가 편리한 프로그램을 만들 수 있음
다형성을 사용하는 이유?
- 상위 클래서에서는 공통적인 부분을 제공하고 하위 클래스에서는 각 클래스에 맞는 기능 구현
- 여러 클래스를 하나의 타입(상위 클래스)으로 핸들링 할 수 있음
08-5. 다형성 활용하기
상속은 언제 사용 할까?
IS-A 관계 (is a relationship : inheritance)
- 일반적인(general) 개념과 구체적인(specific) 개념과의 관계
- 상위 클래스 : 하위 클래스보다 일반적인 개념 (예 : Employee)
- 하위 클래스 : 상위 클래스보다 구체적인 개념들이 더 해짐 (예 : Engineer, Manager...)
- 상속은 클래스 간의 결합도가 높은 설계
- 상위 클래스의 수정이 많은 하위 클래스에 영향을 미칠 수 있음
- 계층구조가 복잡하거나 hierarchy가 높으면 좋지 않음
HAS-A 관계 (composition)
- 클래스가 다른 클래스를 포함하는 관계 (변수로 선언)
- 코드 재사용의 가장 일반적인 방법
- Student가 Subject를 포함하는
- Library를 구현할 때 ArrayList 생성하여 사용
- 상속하지 않음
08-6. 다운 캐스팅과 instanceof
다운 캐스팅(downcasting)
- 업캐스팅된 클래스를 다시 원래의 타입으로 형 변환
- 하위 클래스로의 형 변환은 명시적으로 해야 함
Customer vc = new VIPCustomer(); //묵시적 VIPCustomer vCustomer = (VIPCustomer)vc; //명시적 |
instanceof를 이용하여 인스턴스의 형 체크
- 원래 인스턴스의 형이 맞는지 여부를 체크하는 키워드 맞으면 true 아니면 false를 반환 함
'Programming Language > JAVA' 카테고리의 다른 글
[Do it 자바 프로그래밍 입문] 10.인터페이스 (0) | 2023.05.25 |
---|---|
[Do it 자바 프로그래밍 입문] 09.추상 클래스 (0) | 2023.05.24 |
아리송한 개념들 짜집기 모음 (0) | 2023.05.22 |
[Do it 자바 프로그래밍 입문] 객체지향 입문 복습 문제 풀이 (0) | 2023.05.22 |
[Do it 자바 프로그래밍 입문] 07.배열과 ArrayList (0) | 2023.05.15 |