/* 예제 개요
* 슈퍼카를 타는 건물주 메간 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같은 클래스가 있었다면 캡슐화를 하지 않았다면 어마어마한 비효율적인 수정이 필요했을것
변경과 확장에 유연한 설계로 캡슐화가 연결되는 이유임
캡슐화를 적용하지 않은 상황을 다시 만들어보고 다시 캡슐화 해보기