[Java] OOP(캡슐화, 상속, 추상화, 다형성)

김예원·2022년 12월 20일
0

자바 기초 이론

목록 보기
7/7

객체지향

“실제 세계는 사물(유형의 객체)로 이루어져 있으며 발생하는 모든 사건들은 사물(객체)간의 상호작용이다.” 라는 것이 객체 지향의 기본 개념이다.

프로그래밍에서는 상속, 캡슐화, 추상화 개념을 중심으로 가상세계에서 객체(무형의 객체)를 다룰 수 있는 객체지향언어가 만들어졌다.

객체지향 프로그래밍을 위한 객체지향개념은 캡슐화, 상속, 추상화, 다형성 4가지로 나뉜다.

객체지향 프로그래밍(Object Oriended Programming)

캡슐화

어떤 데이터와 그 데이터를 활용한 메서드를 한 클래스 안에 넣어놓는 것을 캡슐화라고 한다.

클래스가 캡슐인 셈이다.

외부에서 클래스 내부의 멤버변수나 메서드 등에 접근할 필요가 없을 때, 접근제어자를 활용해서 클래스 내부에 선언된 데이터를 보호할 수 있다.

노출하고 싶은 데이터는 해당 범위의 접근제어자로 설정하고,

노출시키지 않는 데이터는 외부에서 데이터를 함부로 변경하지 못하게 접근을 제한해서 데이터가 유효한 값을 유지하도록 하는것이 캡슐화에 해당한다.

class Car {
    private String brand;    // private 제어자로 외부에서 직접 접근할 수 없는 데이터
    private int price;
    
    public void setCar(String brand, int price) {       // set 메서드를 통해 변수를 저장한다
        this.brand = brand;
        this.price = price;
    }

    public String analysis() {    // 자동차 브랜드와 가격별 멘트
        if (this.brand.equals("벤츠") || this.brand.equals("아우디") || this.brand.equals("bmw") && this.price > 5000) {
            return this.price + "만원의 " + this.brand + " 탑클래스 차를 타시는군요!";
        }
        else return this.price + "만원의 " + this.brand + "를 타시는군요, " + "당신의 차도 멋져요.";
    }
}

public class JavaChapter {

    public static void main(String[] args) {
//        캡슐화
        Car car = new Car();
        car.setCar("벤츠",100000000);
        System.out.println(car.analysis());
    }
}
실행결과

100000000만원의 벤츠 탑클래스 차를 타시는군요!

상속

상속이란, 기존의 코드를 확장하여 새로운 클래스를 작성하는 것이다.

코드의 재사용성을 높이고 코드의 중복을 제거하여 프로그램의 생산성과 유지보수에 크게 기여한다.

일반적으로 사용되는 큰 개념으로 구성된 부모클래스를 기반으로 구체적인 내용으로 이 클래스를 확장하여 새로운 클래스를 생성하는 것을 말한다.

상속은 재사용의 목적보다는 확장에 의미가 있다.

class Car {
    String brand;       // 자동차 브랜드
    int price;      // 자동차 가격

    public Car(String brand, int price) {   // Car 생성자
        this.brand = brand;
        this.price = price;
    }

    public String comment() {      // 자동차 브랜드와 가격별 멘트
        if (this.brand.equals("벤츠") || this.brand.equals("아우디") || this.brand.equals("bmw") && this.price > 5000) {
            return this.price + "만원의 " + this.brand + " 탑클래스 차를 타시는군요!";
        }
        else return this.price + "만원의 " + this.brand + "를 타시는군요, " + "당신의 차도 멋져요.";
    }
}

public class JavaChapter {

    static class Age extends Car {      // Age클래스가 Car클래스를 상속 - Age클래스는 자식클래스, Car클래스는 부모클래스
        int age;    // Age의 인스턴스 변수

        public Age(String type, int price, int age) {    // 생성자 오버로딩
            super(type, price);
            this.age = age;
        }
        @Override
        public String comment() {   // 부모클래스 메서드 오버라이딩
            return super.comment() + " 부러워요. 전 "+ this.age + "살에 차를 살거에요.";
        }
    }

    static class FuelEfficiency extends Car {
        int fuelEfficiency;     // FuelEfficiency의 인스턴스 변수

        public FuelEfficiency(String type, int price, int fuelEfficiency) {     // 생성자 오버로딩
            super(type, price);
            this.fuelEfficiency = fuelEfficiency;
        }
        @Override
        public String comment() {   // 부모클래스 메서드 오버라이딩
            if (this.fuelEfficiency >= 15) return super.comment() + " 연비가 " + this.fuelEfficiency + "km로 아주 좋군요.";
            else return super.comment() + " 연비는 " + this.fuelEfficiency + "km로 아쉽네요.";
        }
    }

    public static void main(String[] args) {


//        상속
        Age age = new Age("bmw", 9000, 29);
        System.out.println(age.comment());

        FuelEfficiency fe = new FuelEfficiency("중고차", 2000, 13);
        System.out.println(fe.comment());

    }
}
실행결과

9000만원의 bmw 탑클래스 차를 타시는군요! 부러워요. 전 29살에 차를 살거에요.
2000만원의 중고차를 타시는군요, 당신의 차도 멋져요. 연비는 13km로 아쉽네요.

추상화

추상화는 상속과 비슷하지만 반대되는 개념이라고 볼 수 있다.

클래스의 공통점을 찾아서 공통의 클래스를 만드는 작업을 추상화라고 한다.

class Marine {  // 보병
    int x, y;
    void move(int x, int y) {}  // 지정된 위치로 이동
    void stop() {}  // 정지
    void stimPack() {}
}

class Tank {    // 탱크
    int x, y;
    void move(int x, int y) {}
    void stop() {}
    void changeMode() {}
}

class Dropship {    // 수송선
    int x, y;
    void move(int x, int y) {}
    void stop() {}
    void load() {}
    void unload() {}
}

abstract class Unit {   // 공통 부분을 추상화
    int x, y;
    abstract void move(int x, int y);
    void stop() {}
}

class Marine extends Unit {
    void move(int x, int y) {}  // 추상메서드만 상속 (재구현)
    void stimPack() {}
}

class Tank extends Unit {
    void move(int x, int y) {}
    void changeMode() {}
}

class Dropship extends Unit{
    void move(int x, int y) {}
    void load() {}
    void unload() {}
}

다형성

객체지향 개념에서 다형성은 '여러가지 형태를 가질 수 있는 능력'을 의미하고

자바에서 다형성은 부모클래스 타입의 참조변수로 자식클래스의 인스턴스를 참조할 수 있다는 것의 의미가 기본이다.

  1. 부모타입의 참조변수로 자식클래스의 인스턴스를 참조할 수 있다.
    참조변수와 인스턴스의 타입이 일치하지 않고
    부모타입의 참조변수로 자식클래스의 인스턴스를 참조할 경우 참조변수로 사용가능한 멤버는 부모클래스의 멤버뿐이다.
  1. 부모타입 <-> 자식타입 간의 형변환이 가능하다.
    참조하고 있는 인스턴스에서 사용할 수 있는 멤버의 범위를 조전하기 위해 사용한다.

    자식타입을 부모타입으로 형변환 할 때 (업캐스팅)     : 형변환 생략 가능
    부모타입을 자식타입으로 형변환 할 때 (다운캐스팅)    : 형변환 생략 불가능
  2. 형변환 검사

     참조변수 instanceof 클래스명(타입)

    가 true이면 참조변수의 타입을 해당 클래스의 타입으로 변환할 수 있다는 뜻이고 false이면 타입변환이 불가하다는 뜻이다.

  1. 참조변수의 타입에 따른 호출 값의 차이
    부모클래스와 자식클래스가 같은 이름의 멤버변수를 갖고 있을 때 멤버의 사용 범위가 달라지기 때문에 아래와 같이 멤버변수의 호출 값이 달라진다.

     class Car {
         int speed = 20;
     }
    
     class myCar extends Car {
         int speed = 50;
     }
    
     public class JavaChapter {
     public static void main(String[] args) {
         Car c = new myCar();
         myCar m = new myCar();
    
         System.out.println(c.speed);
         System.out.println(m.speed);
    
         }
     }
    실행결과
    
    20
    50
  2. 메서드의 매개변수에도 다형성을 적용할 수 있다.
    자식클래스가 부모클래스를 상속받았다면 메서드의 매개변수에 부모타입의 참조변수를 통해 자식클래스의 인스턴스를 사용하는 것이 가능하다.

  1. 부모타입의 참조변수 배열에 자식클래스의 객체를 배열로 묶어서 다룰 수 있다.

다형성이 가장 중요하다.

스프링에서 의존성 주입, ioc 컨테이너 등 모두 다형성을 활용한 것이다.


객체지향 프로그래밍에 대해 공부하는데 꽤 오래 시간을 쏟았다.

아직 온전히 이해하지 못했고 내용도 아직 다 채워지진 않았지만 여러번 되새기면서 더 적절한 예제도 많이 만들어봐야할 듯 하다.🫠💪🏻

profile
기억력이 짧은 나를 위한 기록 🍀

0개의 댓글