230227 체크포인트 (상속, 캡슐화 예제) - 다듬기 전

허크·2023년 2월 27일
0
/* 예제 개요
* 슈퍼카를 타는 건물주 메간 vs 투싼타는 프로그래머 허크의 하루
* 필요한 객체
* 허크 객체, 메간 객체, 슈퍼카 객체, 투싼 객체
*/
package inheritance.checkpoint.car;

public class Car {

	private String name; 
    private int fuelPercent; // 데이터 캡슐화
    
    public Car(String name, int fuelPercent) {
    	this.name = name;
        this.fuelPercent = feulPercent;
    }
	
    public String getName() { // name만 조회가능한 생성자
    	return name;
    }
    
    public int getFuelPercent() {
    	return fuelPercent;
    }
    
    private void on() { // public -> private로 수정
    	System.out.println(name + "에 시동을 겁니다.");
    }
    
    private void go() {
    	System.out.println("부릉부릉");
    }
    
    private void off() {
    	System.out.println("시동을 끕니다.");
    }
    
    public void operate() {
    	if (FuelPercent() <= 0) { // 동일 클래스 이므로 수정)
        	System.out.println("연료가 부족하여 시동을 걸 수 없습니다.);
        }
        else{
        	car.on();
            car.go();
            car.off();
    }
}
package inheritance.checkpoint.Person;

import inheritance.checkpoint.car.Car;

public class Person {

	private String name;
    private Car car
    
    public Person(String name, Car car) {
    	this.name = name;
        this.car = car;
    }
    
    public String getName() { // name만 조회가능한 생성자
    	return name;
    }
    
    public Car getCar() {
    	return car;
    }
    
    pubilc void sleep() {
    	System.out.printf("%s이(가) 잠을잡니다.\n", name);
    	System.out.println("쿨쿨쿨...zzZ");
    }
    
    pubilc void eat() {
    	System.out.printf("%s이(가) 밥을 먹습니다.\n", name);
    	System.out.println("여유롭게 냠냠냠");
    }
    
    pubilc void introduce() {
    	System.out.printf("안녕하세요, 저는 %s입니다. \n", name);
    }

	pubilc void drive() {
    	car.operate(); // Person 클래스에서는 동작을 알 수 없으며 Car클래스 내에서 계산한 값만 호출받게 된다.
    }
}
package inheritance.checkpoint

import inheritance.checkpoint.car.Car;
import inheritance.checkpoint.person.Person;

public class DayOfMegan {
	public static void main(String[] args) {
    	System.out.println("🌈건물주 메간님의 하루🌈");
        
        Car lamborghini = new Caar("람보르기니 무르시엘라고", fulePercent:100);
        
        Person Megan = new Person("메간", lamborghini);
        
        Megan.introduce();
        Megan.eat();
        Megan.drive();
        Megan.sleep;        
    }
}
package inheritance.checkpoint.person;

public class Programmer extends Person {
	private String company;
    private boolean tooMuchWork;
    
    public Programmer(String name, Car car, String company, boolean tooMuchWork);
    	super(name, car); // 상위클래스 호출 및 초기화
    	this.company = company;
        this.tooMuchWork = tooMuchWork;
        
    public void work() {
    	System.out.println("근무를 시작합니다.");
        System.out.println("타닥...타닥...타다닥..탁!!!");
        System.out.println("이게 왜 안되지...?");
    	System.out.println("타닥...타닥...타다닥..탁!!!");
        System.out.println("이게 왜 되지...?");
        System.out.println();
    }
    
    pubilc void commute() {
    	System.out.println("%s를 타고 %s로 출근합니다.\n", super.getCar().getName(), company); 
        // 차 이름을 가져오기위해 상위클래스인 인스턴스에 접근
        // super+getter를 통해 private된 name에 접근가능
        super.drive();
        System.out.println("%s에 도착했습니다.\n", company);
        System.out.println();
    }
    
    // 오버라이딩
    public void eat() {
    	if (tooMuchWork) System.outprintln("허겁지겁 후루룩");
        else super.eat();
        System.out.println();
    }
    
    public void sleep() {
    	if (tooMuchWork) System.outprintln("잠을 잘 수 없습니다....");
        else super.sleep();
        System.out.println();
    }
	
    public void introduce() {
    	super.introduce();
        System.out.printf(
        	"#s에서 일하고 있으며, #s", 
            company,
            tooMuchWork ? "오늘은 야근을합니다...\n" : "오늘은 정시에 퇴근합니다.\n");
    }
}
	// 자바는 상속계층도를 보고 가장 가까운 곳의 메서드를 호출

오버라이딩은 상위 클래스를 쓰고싶은데 미묘하게 다를때
super로 상위클래스의 멤버에 접근할 수 있다(private제외)

package inheritance.checkpoint.person.Programmer;

import inheritance.checkpoint.car.Car;
import inheritance.checkpoint.person.Programmer;

public class DayofHurk {
	public static void main(String[] args) {
    
    	System.out.println("🌈프로그래머 허크의 하루🌈");
        
        Car spark = new Car("스파크", "20");
        
        Programmer Hurk = new Programmer("김득렬", spark, "코드스테이츠", true);
        
        Hurk.introduce();
        Hurk.commute();
        Hurk.work();
        Hurk.eat();
        Hurk.sleep();
    }
}

객체지향 프로그래밍은 수정해야될 양을 사람이 관리할 수 있는 합리적인 수준으로 낮추는 것.

  • 캡슐화의 위반

Car 클래스의 on, go, off 메서드를 수정해야 할 경우
-> 완전히 다른 메서드를 정의할 경우
-> Person에 있는 drive도 바꿔야함
-> Car의 내부동작을 그대로 실현하고 있기 때문
-> Car의 정보를 너무나 공개하고있다
-> 캡슐화를 위반했다 라고 함

-> Car의 내부동작을 감추면 됨
-> 캡슐화

-> Person drive내부 내용을 Car의 새로운 operate에 삽입
-> operate 하나만 public으로 열어둠
-> Car의 동작들은 public에서 private로 수정
-> drive는 car.operate();만 입력

  • go,on,off는 애초에 person 클래스에서 동작해야할 것이 아닌 Car 클래스에서 동작하는 것.

  • 외부에서는 자동차에 대한 코드는 모두 Car 클래스에 모임
    -> 자동차의 동작에 대한 수정을 다른 클래스에 구애받지 않고 수정가능

  • 만약 수십개의 Person같은 클래스가 있었다면 캡슐화를 하지 않았다면 어마어마한 비효율적인 수정이 필요했을것

  • 변경과 확장에 유연한 설계로 캡슐화가 연결되는 이유임

  • 캡슐화를 적용하지 않은 상황을 다시 만들어보고 다시 캡슐화 해보기

profile
codestates seb 44th // 다크모드로 보는걸 추천드립니다

0개의 댓글