- 상속
: B클래스가 A클래스를 상속받으면 B클래스는 A클래스의 멤버 변수와 메서드를 사용할 수 있다.
A클래스 (상위 클래스)
^ = A클래스가 B클래스에게 상속한다.
^ = B클래스가 A클래스를 상속받는다
B클래스 (하위 클래스)
class B extends A {
}
class Mammal {
...
}
class Human extends Mammal {
...
}
- 상속을 사용하여 고객 관리 프로그램 구현하기

.PNG)
-> VIP 클래스 8행 오류 발생 이유 : 상위클래스에서 customerGrade가 private 변수이기 때문에 외부 클래스에서는 이 변수를 사용할 수 없다. 해결방법은 protected 예약어 사용
%20private%20%EB%B3%80%EC%88%98%EB%A5%BC%20protected%20%EB%B3%80%EC%88%98%EB%A1%9C%20%EB%B3%80%ED%99%98%20(VIPCustomer%20%ED%81%B4%EB%9E%98%EC%8A%A4%20%EC%98%A4%EB%A5%98%20%ED%95%B4%EA%B2%B0).PNG)
%20protected%EB%A1%9C%20%EC%84%A0%EC%96%B8%ED%95%9C%20%EB%B3%80%EC%88%98%EB%93%A4%EC%9D%84%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0%20%EC%9C%84%ED%95%B4%20get(),%20set()%20%EB%A9%94%EC%84%9C%EB%93%9C%20%EC%B6%94%EA%B0%80%20(VIPCustomer%20%ED%81%B4%EB%9E%98%EC%8A%A4%20%EC%98%A4%EB%A5%98%20%ED%95%B4%EA%B2%B0).PNG)
-> protected 변수로 선언하고 외부에서 사용할 수 있도록 get(), set() 메서드 추가

- 하위 클래스가 생성되는 과정
%20Customer%20%ED%81%B4%EB%9E%98%EC%8A%A4%EC%97%90%20%EC%B6%9C%EB%A0%A5%EB%AC%B8%20%EC%B6%94%EA%B0%80.PNG)
-> Customer() 생성자에 출력문을 추가함. Customer 인스턴스가 생성되면 이 호출문이 출력될 것이다.
%20VIPCustomer%20%ED%81%B4%EB%9E%98%EC%8A%A4%EC%97%90%20%EC%B6%9C%EB%A0%A5%EB%AC%B8%20%EC%B6%94%EA%B0%80.PNG)
-> VIPCustomer() 생성자에도 출력문 추가

-> 출력 화면을 보면 상위 클래스의 Customer() 생성자가 먼저 호출되고 그다음에 VIPCustomer()가 호출되는 것을 알 수 있다. 즉, 상위 클래스를 상속받은 하위 클래스가 생성될 때는 반드시 상위 클래스의 생성자가 먼저 호출된다. 그리고 상위 클래스 생성자가 호출될 때 상위 클래스의 멤버 변수가 메모리에 생성된다.
- super 예약어
: 하위 클래스에서 상위 클래스로 접근할 때 사용함. 하위 클래스는 상위 클래스의 주소, 즉 참조 값을 알고 있고 이 참조 값을 가지고 있는 예약어가 super다.
- super 예약어로 매개변수가 있는 생성자 호출하기

-> 기존 Customer 클래스에 새로운 생성자를 추가하고 기존 디폴트 생성자를 삭제.

-> 호출될 디폴트 생성자 Customer()가 위에서 삭제됐기 때문에 다시 명시적으로 상위 클래스 생성자를 호출함.
- 메서드 오버라이딩
: 상위 클래스에 정의한 메서드가 하위 클래스에서 구현할 내용과 맞지 않을 경우에 하위 클래스에서 이 메서드를 재정의할 수 있는데 이를 메서드 오버라이딩(method overriding)이라고 한다. *오버라이딩을 할 때에는 반환형, 메서드 이름, 매개변수 개수, 매개변수 자료형이 반드시 같아야 한다.
- VIP 고객 클래스의 제품 가격 계산 (calcPrice()) 메서드 재정의하기
%20%EB%A9%94%EC%84%9C%EB%93%9C%20%EC%9E%AC%EC%A0%95%EC%9D%98%ED%95%98%EA%B8%B0(overriding).PNG)
-> 재정의한 메서드 / @Override 애노테이션은 '이 메서드는 재정의된 메서드입니다.' 라고 컴파일러에 명확히 알려주는 역할이다.%20%ED%85%8C%EC%8A%A4%ED%8A%B8%ED%95%98%EA%B8%B0.PNG)
-> 두 고객을 생성해서 지불하는 가격을 출력한 테스트
- 묵시적 클래스 형 변환과 메서드 재정의

-> 멤버 변수와 메서드는 선언한 클래스형에 따라 호출되는데 위를 보면 재정의된 메서드가 호출된 것을 알 수 있다. 이는 상속에서 상위 클래스와 하위 클래스에 같은 이름의 메서드가 존재할 때 호출되는 메서드는 인스턴스에 따라 결정되기 때문이다. 즉 선언한 클래스형이 아닌 생성된 인스턴스의 메서드를 호출하는 것이다. 이렇게 인스턴스의 메서드가 호출되는 기술을 '가상 메서드(virtual method)' 라고 한다.
- 가상 메서드
.PNG)
-> 같은 객체의 인스턴스를 여러 개 생성한다고 해서 메서드도 여러 개 생성되지 않는다. 메서드의 메모리는 변수가 사용하는 메모리와 다르다. 메서드는 실행해야 할 명령 집합이기 때문에 인스턴스가 달라도 같은 로직을 수행한다.
- 클래스형에 기반하여 지불 금액 계산하기

-> 마지막 13행에서 VIPCustomer로 생성하고 Customer형으로 변환한 vc는 원래 Customer형 메서드가 호출되는 것이 맞지만, 가상 메서드 방식에 의해 VIPCustomer 인스턴스의 메서드가 호출되어 할인 가격 9,000원이 출력된다.
=> 정리) 상위 클래스에서 선언한 calcPrice() 메서드가 있고 이를 하위 클래스에서 재정의한 상태에서 하위 클래스 인스턴스(vc)가 상위 클래스로 형 변환이 되었다. 이때 vc.calcPrice()가 호출되면, vc변수를 선언할 때 사용한 자료형(Customer)의 메서드가 호출되는 것이 아니라 생성된 인스턴스(VIPCustomer)의 메서드가 호출된다. 이를 가상 메서드라고 하며 자바의 모든 메서드는 가상 메서드이다.
- 다형성
: 하나의 코드가 여러 자료형으로 구현되어 실행되는 것

-> 테스트를 하기 위해 AnimalTest1 클래스에 moveAnimal() 메서드를 만들었다. 이 메서드는 어떤 인스턴스가 매개변수로 넘어와도 모두 Animal형으로 변환한다. 예를 들어 매개변수가 전달되는 부분에 Human 인스턴스가 전달되었다면 Animal형으로 변환되므로 animal.move() 메서드를 호출할 수 있다. 가상 메서드의 원리에 따라 animal.move() 메서드가 호출하는 메서드는 Animal의 move가 아닌 매개변수로 넘어온 실제 인스턴스의 메서드이다. animal.move() 코드는 변함이 없지만 어떤 매개변수가 넘어왔느냐에 따라 출력문이 달라지는데 이것이 바로 다형성이다.
- 다형성을 활용해 VIP 고객 클래스 완성하기
%20Customer%20%ED%81%B4%EB%9E%98%EC%8A%A4.PNG)
-> 기존 Customer 클래스 수정한 내용. initCustomer() 메서드는 클래스의 멤버 변수를 초기화 하는데, Customer 클래스를 생성하는 두 생성자에서 공통으로 사용하는 코드이므로 메서드로 분리하여 호출함
%20VIPCustomer%20%ED%81%B4%EB%9E%98%EC%8A%A4.PNG)
-> VIP 고객 클래스에서 calcPrice() 메서드와 showCustomerInfo() 메서드를 재정의 했다.
%20CustomerTest%20%ED%81%B4%EB%9E%98%EC%8A%A4.PNG)
- 새로운 고객 등급 추가하고, 배열을 활용한 고객 관리 프로그램 구현하기
.PNG)

.PNG)
- 상속 활용
: 모든 등급에서 공통으로 사용하는 코드 부분은 상위 클래스에 구현하고, 각 등급별 고객의 내용은 각각의 하위 클래스에 구현한다. 따라서 프로그램이 확장성 있고 유지보수하기 좋다.
- 상속 활용 관계
: IS-A 관계, 일반클래스를 점차 구체화하는 상황에서 상속 사용
: HAS-A 관계, 한 클래스가 다른 클래스를 소유한 관계에서는 상속을 사용하지 않는게 좋다.
- 자바는 다중 상속을 지원하지 않기 때문에 extends 예약어 뒤에 오는 클래스는 반드시 한 개여야만 한다.
- 다운캐스팅(downcasting)
: 상위 클래스로 형 변환되었던 하위 클래스를 다시 원래 자료형으로 형 변환하는 것을 말한다. 다운캐스팅을 하기 전에 상위 클래스로 형 변환된 인스턴스의 원래 자료형을 확인해야 변환할 때 오류를 막을 수 있다. 이때 사용하는 예약어가 instanceof 이다.
Animal hAnimal = new Human();
if(hAnimal instanceof Human) { //hAnimal 인스턴스 자료형이 Human형이라면
Human human = (Human)hAnimal; //인스턴스 hAnimal을 Human형으로 다운 캐스팅
}
.PNG)
.PNG)
.PNG)