[JAVA] 객체 지향 핵심 – 다형성과 다형성을 사용하는 이유, 상속은 언제 사용할까?

– 다형성

자바에서 다형성(Polymorphism)은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 같은 인터페이스나 상위 클래스 타입을 통해 여러 다른 하위 클래스 객체를 동일하게 다룰 수 있는 기능을 의미합니다. 다형성을 통해 코드의 유연성과 재사용성을 높일 수 있습니다.

– 다형성의 주요 개념

  1. 상위 클래스 참조 변수로 하위 클래스 객체를 참조: 상위 클래스나 인터페이스 타입의 변수로 여러 하위 클래스 객체를 참조할 수 있습니다.
  2. 동적 바인딩(Dynamic Binding): 메서드 호출이 컴파일 시점이 아닌 런타임 시점에 실제 객체의 타입에 따라 적절한 메서드가 호출되는 방식입니다.
  3. 메서드 재정의(Overriding): 상위 클래스의 메서드를 하위 클래스에서 재정의하여 각기 다른 동작을 수행할 수 있습니다.
  • 하나의 코드가 여러 자료형으로 구현되어 실행되는 것
  • 같은 코드에서 여러 다른 실행 결과가 나옴
  • 정보은닉, 상속과 더불어 객체지향 프로그래밍의 가장 큰 특징 중 하나임
  • 다형성을 잘 활용하면 유연하고 확장성 있고, 유지보수가 편리한 프로그램을 만들수 있음
public class Customer {

    protected int customerId;
    protected String customerName;
    protected String customerGrade;

    int bonusPoint;
    double bonusRatio;



//    public Customer(){
//        customerGrade = "SILVER";
//        bonusRatio = 0.01;
//        System.out.println("Customer() Call");
//    }

    public Customer(int customerId, String customerName){
        this.customerId = customerId;
        this.customerName = customerName;

        customerGrade = "SILVER";
        bonusRatio = 0.01;
        System.out.println("Customer(int, String) Call");
    }
    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 + "입니다.";
    }
}


public class GoldCustomer extends Customer{
    protected int agentID;
    double salesRatio;

    public GoldCustomer(int customerId, String customerName) {

        super(customerId, customerName);
        customerGrade = "Gold";
        salesRatio = 0.1;
        bonusRatio = 0.02;
    }
    @Override
    public int calcPrice(int price) {
        bonusPoint += price * bonusRatio;
        return price - (int)(price * salesRatio);
    }
}

public class VIPCustomer extends Customer {

    protected int agentID;
    double salesRatio;

    public VIPCustomer(int customerId, String customerName, int agentID){

        super(customerId, customerName);
        customerGrade = "VIP";
        salesRatio = 0.1;
        bonusRatio = 0.05;
        this.agentID = agentID;

        System.out.println("VIPCustomer()");
    }

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

    public int getAgentID(){
        return agentID;
    }

    @Override
    public String showCustomerInfo() {
        return super.showCustomerInfo() + "상담원 아이디는 " + agentID;
    }
}

public class CustomerTest {
    public static void main(String[] args) {

        ArrayList<Customer> customerList = new ArrayList<Customer>();

        Customer customerLee = new Customer(10010, "이순신");
        Customer customerShin = new Customer(10020, "신사임당");
        Customer customerHong = new GoldCustomer(10030, "홍길동");
        Customer customerYul = new GoldCustomer(10040, "이율곡");
        Customer customerKim = new VIPCustomer(10050, "김유신", 12345);

        customerList.add(customerLee);
        customerList.add(customerShin);
        customerList.add(customerHong);
        customerList.add(customerYul);
        customerList.add(customerKim);

        System.out.println("====== 고객 정보 출력 =======");

        for( Customer customer : customerList){
            System.out.println(customer.showCustomerInfo());
        }

        System.out.println("====== 할인율과 보너스 포인트 계산 =======");

        int price = 10000;
        for( Customer customer : customerList){
            int cost = customer.calcPrice(price);
            System.out.println(customer.getCustomerName() +" 님이 " +  + cost + "원 지불하셨습니다.");
            System.out.println(customer.getCustomerName() +" 님의 현재 보너스 포인트는 " + customer.bonusPoint + "점입니다.");
        }

    }
}

– 상속

자바에서 상속(Inheritance)은 객체 지향 프로그래밍의 핵심 개념 중 하나로, 새로운 클래스가 기존 클래스의 특성과 행동을 물려받아 재사용하고 확장할 수 있게 하는 기능입니다. 상속을 통해 코드의 재사용성을 높이고, 클래스 간의 계층 구조를 형성할 수 있습니다.

– 상속의 기본 개념

  1. 상위 클래스(부모 클래스, 슈퍼클래스): 다른 클래스가 물려받을 수 있는 기존 클래스입니다.
  2. 하위 클래스(자식 클래스, 서브클래스): 상위 클래스를 상속받아 그 특성과 행동을 물려받는 새로운 클래스입니다.
  3. extends 키워드: 자바에서 클래스 상속을 선언할 때 사용되는 키워드입니다.

– 상속은 언제 사용할까?

– IS-A 관계(is a relationship : inherutance)

  • 일반적인(general) 개념과 구체적인(apecific) 개념과의 관계
  • 상위 클래스 : 하위 클래스보다 일반적인 개념 (예:Employee)
  • 하위 클래스 : 상위 클래스보다 구체적인 개념들이 더해짐 (예:Engineer, Manager…)
  • 상속은 클래스간의 결합도가 높은 설계
  • 상위 클래스의 수정이 많은 하위 클래스에 영향을 미칠 수 있음
  • 계층구조가 복잡하거나 hierarchy가 높으면 좋지 않음

– HAS-A 관계(compostion)

  • 클래스가 다른 클래스를 포함하는 관계 (변수로 선언)
  • 코드 재사용의 가장 일반적인 방법
  • Student가 subject를 포함하는
  • Library를 구현할 때 ArrayList 생성하여 사용
  • 상속하지 않음

Leave a Comment