728x90
상속 (extends)
- 이미 구현된 클래스보다 더 구체적인 기능을 구현할 때 사용
protected
접근제어자를 이용하여 하위 클래스에서도 상위 클래스의 멤버 변수에 접근이 가능하도록 한다.- 하위 클래스에서 상위 클래스를 상속받으면 하위 클래스 생성자에서 먼저 상위 클래스 생성자를 호출한다.
상속을 이용한 멤버십 시나리오 구현
| 📄 Customer.java
/**
* 일반 고객 클래스
*/
public class Customer {
// protected : 하위 클래스 접근가능
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;
}
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.java
/**
* VIP 고객 클래스
*/
public class VIPCustomer extends Customer{
private int agentID;
double salesRatio;
public VIPCustomer() {
customerGrade = "VIP"; //오류 발생
bonusRatio = 0.05;
salesRatio = 0.1;
}
public void setAgentID(int agentID) {
this.agentID = agentID;
}
public int getAgentID() {
return agentID;
}
}
| 📄 CustomerTest.java
public class CustomerTest {
public static void main(String[] args) throws Exception {
Customer customerLee = new Customer();
customerLee.setCustomerName("이순신");
customerLee.setCustomerId(10010);
customerLee.bonusPoint = 1000;
System.out.println(customerLee.showCustomerInfo());
VIPCustomer customerKim = new VIPCustomer();
customerKim.setCustomerName("김유신");
customerKim.setCustomerId(10020);
customerKim.bonusPoint = 10000;
System.out.println(customerKim.showCustomerInfo());
}
}
Super
- 상위 클래스에 기본 생성자가 있는 경우
상위 클래스의 생성자를 호출하는 명시적인 코드가 없으면super()
를 자동으로 넣어서 컴파일 해준다. - 상위 클래스에 기본 생성자가 없고 다른 생성자가 있는 경우
하위 클래스에서는 생성자에 super를 이용하여 명시적으로 상위 클래스의 생성자를 호출해야한다. private
멤버 변수의 경우에도 메모리 상에는 만들어지는데, 접근만 불가능하게 되는 것이다.
형 변환 (업캐스팅)
Customer customerLee = new VIPCustomer();
VIPCustomer
의 경우에도Customer
를 내포하고 있기 때문에 가능하다.VIPCustomer
인스턴스는Customer
타입의 인스턴스로 대입될 수 있다.
VIPCustomer vCustomer = new VIPCustomer();
addCustomer(vCustomer);
int addCustomer(Customer customer){ ... }
- 업캐스팅 진행 시, 인스턴스 자체는 하위 클래스의 인스턴스 일지 모르지만 (내부 메서드 및 변수는 모두 만들어진 상태) 그러나 상위 클래스로 형 변환을 해줬기때문에 하위 클래스의 메서드 및 변수는 사용이 불가능하다.
- ⭐️ 생성은 다 되지만 상위 클래스 형태로 형 변환된 경우에는 접근 자체는 상위 클래스의 메서드만 가능!
오버라이딩
Customer vc = new VIPCustomer();
- 이때 vc 변수의 타입은 Customer지만 인스턴스 타입은 VIPCustomer이다.
- 자바에서는 항상 인스턴스의 메서드가 호출된다. (가상메서드의 원리)
- 자바의 모든 메서드는 가상 메서드 !
<-> (C++의 경우에는virtual
키워드를 함께 사용해야함)
가상 메서드
- 가상 메서드 테이블에서 해당 메서드에 대한 address를 가지고 있다.
- 만약 오버라이딩된 메서드가 존재한다면 재정의 된 메서드에 대한 주소를 갖게 되고 재정의된 메서드를 가리킨다.
- 각 클래스마다 오버라이딩된 메서드에 대해 address가 매핑된다.
다형성
- 여러 클래스를 하나의 타입으로 핸들링할 수 있다.
- 상속과 메서드 재정의를 활용하여 확장성있는 프로그램을 만들 수 있다.
상속
- is-a 관계
- 상속을 통해 클래스간 결합도를 높임
- has-a 관계
- 상속하지 않으며 일반적인 코드 재사용의 방법
다운 캐스팅
- 업 캐스팅된 클래스를 다시 본래의 클래스로 돌아가게 한다.
- 업 캐스팅은 묵시적(implicit)하게 발생하지만 다운 캐스팅은 명시적으로 이뤄진다.
- *
Object
클래스는 최상위클래스이기 때문에 어떤 클래스든Object
클래스로 반환될 수 있다.
Customer vc = new VIPCustomer(); //묵시적
VIPCustomer vCustomer = (VIPCustomer)vc; //명시적
instanceof
를 이용하여 인스턴스의 타입을 체크한다.
추상 클래스(abstract class)
abstract class
<->concrete class
- 메서드의 구현부 없이 선언만 있는 추상 메서드를 포함한 클래스를 말한다.
abstract
예약어를 사용한다.- 상속을 위한 클래스
abstract
로 선언된 클래스는 인스턴스화(new
) 될 수 없다.- 모든 메서드가 구현된 상태여도
abstract
로 선언된 상태면 인스턴스화 불가
- 모든 메서드가 구현된 상태여도
- 추상 클래스 사용 이유
- 공통으로 사용할 클래스만 구현해놓고 하위 클래스들이 추상 메서드를 구현하도록 책임을 위임하기 위함
| 📄 Computer.java
public abstract class Computer {
public abstract void display(); // 추상 메서드
public abstract void typing();
void turnOn() {
System.out.println("전원을 켭니다.");
}
void turnOff() {
System.out.println("전원을 끕니다.");
}
}
| 📄 Desktop.java
public class Desktop extends Computer{
@Override
public void display() {
System.out.println("Desktop display");
}
@Override
public void typing() {
System.out.println("Desktop typing");
}
@Override
void turnOff() {
System.out.println("Desktop turnOff");
}
}
- 추상 클래스를 상속 받아, 메서드 구현
| 📄 NoteBook.java
public abstract class NoteBook extends Computer{
@Override
public void display() {
System.out.println("NoteBook display");
}
}
- 메서드를 일부만 구현할 경우에는 클래스를
abstract
로 선언한다.
템플릿 메서드 패턴
- 프레임워크에서 많이 사용되는 패턴
- 추상 메서드나 구현된 메서드를 활용하여 코드의 흐름을 정의한다.
final
로 선언하여 하위 클래스에서 재정의 할 수 없게끔 한다.- 클래스를
final
로 선언하면 상속을 못하게끔 할 수 있다.
- 미리 시나리오를 정의 해놓고 시나리오에 따라 프로그램의 흐름이 결정된다.
Hook Method
public void run() {} // 구현부는 있지만 구현이 되어있지 않은 상태
- 상위 클래스에서 구현부를 비워두고 하위 클래스에서 재정의해서 사용하는 메서드
인터페이스
- 모든 메서드가 추상 메서드로 선언 abstract
- 모든 변수는 상수로 선언 final
- 클래스나 프로그램이 제공하는 기능을 명시적으로 선언한다.
- 클라이언트와 서버간의 일종의 약속 (어떤 기능을 구현할 것 인지)
| 📄 Calc.java
public interface Calc {
double PI = 3.14;
int ERROR = -99999999;
int add(int num1, int num2);
int substract(int num1, int num2);
int times(int num1, int num2);
int divide(int num1, int num2);
}
| 📄 Calculator.java
public abstract class Calculator implements Calc{
@Override
public int add(int num1, int num2) {
return num1 + num2;
}
@Override
public int substract(int num1, int num2) {
return num1 - num2;
}
}
| 📄 CompleteCalc.java
public class CompleteCalc extends Calculator{
@Override
public int times(int num1, int num2) {
return num1 * num2;
}
@Override
public int divide(int num1, int num2) {
if( num2 == 0 )
return ERROR;
else
return num1 / num2;
}
}
| 📄 CalculatorTest.java
public class CalculatorTest {
public static void main(String[] args) {
Calc calc = new CompleteCalc();
int num1 = 10;
int num2 = 2;
System.out.println(num1 + "+" + num2 + "=" + calc.add(num1, num2));
System.out.println(num1 + "-" + num2 + "=" +calc.substract(num1, num2));
System.out.println(num1 + "*" + num2 + "=" +calc.times(num1, num2));
System.out.println(num1 + "/" + num2 + "=" +calc.divide(num1, num2));
}
}
- Calc calc = new CompleteCalc();
- CompleteCalc는 Calculator를 상속받았지만 Calculator가 Calc를 구현했으므로 Calc로 형 변환이 가능하다!
728x90
'🧑💻 Language > Java' 카테고리의 다른 글
[Java] 객체 지향과 디자인 패턴 (0) | 2022.05.09 |
---|---|
[Java] 자료 구조 (0) | 2022.05.03 |
[Java] 객체 지향 프로그래밍(2) (0) | 2022.04.19 |
[Java] 객체 지향 프로그래밍 (1) (0) | 2022.04.07 |
[Java] Basic Java (2) (0) | 2022.04.04 |