AVA 3일차 - 상속과 다형성 20210117

들어가며.

B클래스가 A클래스를 상속받으면
B클래스는 A클래스의 멤버 변수와 메서드를 사용할 수 있습니다.

  • 부모 클래스(parent class)/ 상위클래스
  • 자식 클래스(child class) / 하위클래스
class B extends A{

}

상속을 사용하여 고객 관리 프로그램 구현하기

현재 상황

  • 고객
    • 고객 아이디
    • 고객 이름
    • 고객 등급
    • 보너스 포인트
    • 보너스포인트 적립 비율
  • 기본 등급은 SILVER
  • 보너스 포인트 비율은 0.01

갑자기?

해당 기능을 완성 한뒤 배달업이 성행하여 영업부에서 연락이 왔다.

  • VIP 등급 신설
  • 음식 구매시 10% 할인
  • 보너스 포인트를 5% 적립
  • 담당 상담 직원 배정

이럴 경우 간단하게 Customer에 VIP에 필요한 변수와 메소드를 다 생성해도 되지만
하지만 상속을 이용하면 추가된 내용만 구현

public class VIPCustomer extends Customer {
    private int agentID;
    double saleRatio;

    public VIPCustomer( ) {
        customerGrade = "VIP";
        bonusRatio = 0.05;
        saleRatio = 0.01;
    }

    public int getAgentID( ) {
        return agentID;
    }
    
    @Override
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price * saleRatio);
    }

}

하위 클래스가 생성되는 과정

  • 하위클래스에서는 상위클래스 변수를 선언하지 않아도 사용이 가능
  • 이는 우리가 굳이 선언하지 않아도 상위 클래스의 변수를 저장하고 있는 메모리가 존재하고 있다는 뜻
  • 하위 클래스를 생성할때 상위클래스 같이 생성한다.
public class CustomerTest2 {
    public static void main(String[] args) {
        VIPCustomer customerKim = new VIPCustomer();

    }
}

결과
Customer( ) 생성자 호출
VIPCustomer( ) 생성자 호출

메모리 에서는

힙메모리생성자
customerIDCustomer() 생성자
customerName
customerGrade
bonusPoint
bonusRatio
agentIDVIPCustomer() 생성자
salesRatio

SUPER 엄마!!!!

  • VIPCustomer 객체를 생성할때 자동으로 Customer 상위 클래스도 생성
  • 이는 super()
  • 하위 클래스 객체의 디폴트 생성자에 자동으로 추가된다.
public VIPCustomer( ) {
    super( );
    customerGrade = "VIP";
    bonusRatio = 0.05;
    saleRatio = 0.1;    

하지만 상위 클래스의 생성자를 아래와 같이 변경하면

public Customer(int customerID, String customerName)

 public Customer(int customerID, String customerName){
        this.customerId = customerID;
        this.customerName = customerName;
        customerGrade = "SILVER";
        bonusRatio = 0.01;
    }

하위 클래스의 생성자에도 명시적으로 작성해야 한다.

public VIPCustomer(int customerID, String customerName, int agentID ) {
super(customerID, customerName);

    public VIPCustomer(int customerID, String customerName, int agentID ) {
        super(customerID, customerName);
        customerGrade = "VIP";
        bonusRatio = 0.05;
        saleRatio = 0.01;
        this.agentID = agentID;
        System.out.println("VIPCustomer( ) 생성자 호출");
    }

상위 클래스로 묵시적 클래스 형변환

VIPCustomer은 VIPCustomer 형이면서 동시에 Customer 형임

Customer vc = new VIPCustomer();
  • vc의 경우 Customer로 형변환 되었기 때문에 VIPCustomer의 변수나 메소드를 사용할 수 없다.

    customer.getAgentId 메소드가 보이지 않음

메서드 오버라이딩(method overriding)

  • 상위클래스에서 정의한 메서드가 하위 클래스에서 구현할 내용이 맞지 않을 경우
  • 하위 클래스에서이 이 메서드를 재 정의할 수 있다.
  • 반환형, 메서드 이름, 매개변수 개수, 매개변수 자료형이 다 같아야 합니다.
 @Override
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price * saleRatio);
    }

묵시적 클래스 형 변환과 메서드 재정의

Customer vc = new VIPCustomer("10030", "나몰라", 2000);
vc.calcPrice(10000);

묵시적 형변환에 의해 VIPCustomer가 Customer형으로 변환
상위 클래스, 하위 클래스 모두 calcPrice가 존재하면 하위클래스의 calcPrice가 작동

  • 호출되는 메소드는 인스턴스에 따라 결정 / 선언한 클래스를 따르지 않음
  • 가상 메서드(virtual method) : 인스턴스의 메서드가 호출되는 기술

결과 :
Customer( ) 생성자 호출 //할인율 없음
VIPCustomer( ) 생성자 호출 //할인율 있음
나몰라님이 지불해야 하는 금액은 9900입니다.//할인율이 적용됨

가상 메서드

  • 클래스를 생성하여 인스턴스가 만들어지면 힙에 위치
  • 메서드는 메소드 영역(method area)에 위치해있다.
  • 메서드는 메모리상에 여러 개 생성되지 않음
  • 변수는 인스턴스가 생성될 때마다 새로 생성

가상 메서드의 원리

  • 프로그램에서 메서드를 호출한다는 것은 메서드의 명령집합이 있는 메모리 위치를 참조하여 실행
  • 가상메서드의 경우 가상 메서드 테이블이 만들어짐
  • 가상메서드 테이블
    • 메서드 - 메서드 주소가 짝을 이루고 있음
메소드메소드주소
calcPrice0x11FF33AA

모든 자바의 메서드는 가상 메서드이다.

가상메서드

public class TestA {
    int num;

    void aaa( ) {
        System.out.println("aaa( ) 출력");
    }

    public static void main(String[] args) {
        TestA a1 = new TestA();
        a1.aaa();
        TestA a2 = new TestA();
        a2.aaa();
    }
}
  • 스택 메모리

    • 변수 :
  • 힙 메모리

    • a1의 객체, a2의 객체
  • 메소드 영역
    - aaa();

  • 메소드 영역

    • 모든 class level 정보가 들어있다.
      • 클래스 이름, 직속 부모 클래스 이름(super), 메소드, 변수, 정적 변수
    • JVM마다 단 하나의 Method Area가 존재하고 Method Area는 공유 자원이다.
  • 힙(heap)

    • 모든 객체의 정보를 저장
    • JVM마다 단 하나의 Heap Area가 존재
    • Heap Area는 공유된 리소스이다.

Annotation 이란?

  • @ 기호와 사용하며 '@애노테이션 이름'으로 표현
  • 컴파일러에게 특정한 정보를 제공해 주는 역할
  • 어노테이션과 메소드의 선언부가 다르면 컴파일 오류 발생
  • 프로그래머의 실수를 줄여준다.
애노테이션설명
@Override재정의된 메소드라는 정보 제공
@FunctionalInterface함수영 인터페이스라는 정보 제공
@Deprecated이후 버전에서 사용되지 않을 수 있는 변수, 메소드에 사용
@SuppressWarnings특정 경고가 나타나지 않도록함

좋은 웹페이지 즐겨찾기