package javajungsuk7_10;

public class Ch07_22 {
    
    public static void main(String[] args) {
        // 7-22 캡슐화

        // 캡슐화와 접근제어자 
        // 접근제어자를 사용하는 이유
        System.out.println("접근 제어자로 직접 접근을 막고 메서드를 통한 간접접근을 허용하는 것이 캡슐화다.");
        System.out.println("1. 데이터를 보호하기 위해서 / 2. 외부에는 불필요한, 내부적으로 사용되는 부분을 감추기 위해서 접근제어자를 쓴다.");

        Time t = new Time();
        // t.hour = 100; 접근 제어자 private을 사용하지 않으면 0~23사이의 값이 아니더라도 값을 가질 수 있지만 이것은 원하는 것이 아니다.
        t.setHour(21);
        System.out.println(t.getHour());
        t.setHour(100); // 100은 유효한 값이 아니기때문에 21만 출력이 된다.
        System.out.println(t.getHour());
    }
}

class Time {
    private int hour; // 0~23사이의 값을 가져야 하기때문에 private을 붙인다.
    // private int minute; // 0~59
    // private int second; // 0~59

    // 메서드를 통해서 iv로 접근하게 한다.
    public void setHour(int hour) {
        if(0 > hour || hour > 23) {
            return;
        } // if문으로 값을 보호
        else {
            this.hour = hour;
        }
    }

    public int getHour() {
        return hour;
    }
}

package javajungsuk7_10;

public class Ch07_23 {
    
    public static void main(String[] args) {
        // 7-23 다형성

        // 다형성의 사전적인 의미로는 여러가지 형태를 가질수 있는 능력이다.
        // 다형성 : 조상 타입 참조 변수로 자손 타입 객체를 다루는 것이라고 하는 것이 정확하다.

        // 다형성의 특징
        System.out.println("다형성은 조상, 자손관계라면 타입이 불일치해도 된다. 보통은 일치하지만 일치하지 않아도 된다.");
        System.out.println("자손 타입의 참조변수로 조상 타입의 객체를 다루는 것은 불가능하다. / 에러"); // 자손타입의 멤버개수가 더 많기 때문에 맞지않는다.

        // 참조변수가 조상타입일 때와 자손타입일 때의 차이?
        System.out.println("사용가능한 멤버의 개수가 달라진다.");

        // 타입이 불일치
        Tv t = new SmartTv(); // Tv리모콘으로 SmartTv를 다루는 것이라고 보면 된다. == 조상타입 참조변수 t로 자손타입 SmartTv객체를 다루는 것이다.
        t.channel = 7;
        System.out.println(t.channel);

        // 에러 : 자손타입의 참조변수로 자손 타입의 객체를?
        // SmartTv st = new Tv(); // 없는 것을 호출했기 때문에 에러가 난다. / 리모콘 버튼이 7개인데 가지고 있는 기능은 5개뿐이다.
    }
}

// 부모 클래스
class Tv {
    boolean power;
    int channel;

    void power() { power = !power; }
    void channelUp() { ++channel; }
    void channelDown() { --channel; }
}

// 자식 클래스
class SmartTv extends Tv {
    String text; // 캡션(자막)을 보여주기 위한 문자열
    void caption() {}
}

package javajungsuk7_10;

public class Ch07_24a25 {
    
    public static void main(String[] args) {
        // 7-24 ~ 7-25 참조변수의 형변환(1) / 참조변수의 형변환(2)

        // 참조변수의 형변환 : 사용할 수 있는 멤버의 개수를 조절하는 것이다.
        // 기본형의 형변환은 int로 형변환을 한다고 하면  3.6 >> 3으로 형변환

        // 참조변수 형변환 특징
        System.out.println("중요 포인트 : 객체를 가리키는 게 무슨 객체인지 중요하다.(참조변수들이 가리키는 실제 객체 중요) / 실제 객체의 멤버개수를 알고 그 개수를 넘지않게 해야 한다.");
        System.out.println("조상, 자손 관계의 참조변수는 서로 형변환이 가능하다.");
        System.out.println("자손타입 >> 조상타입으로 형변환을 할 때, ()을 생략가능 / 조상타입 >> 자손타입으로 형변환을 할 때는 생략불가하다.");
        System.out.println("생략가능과 불가능은 생각하지말고 그냥 붙이자.");

        FireEngine f = new FireEngine();

        // 감소는 안전, 증가는 안전하지 않다.
        Car c = (Car)f; // 형변환 : f타입에서 c타입으로 형변환 / 자손타입에서 조상타입으로 형변환한 것이다. / 멤버개수 5 >> 4
        FireEngine f2 = (FireEngine)c; // FireEngine타입을 하나 더 만들어서 조상타입에서 자손타입으로 형변환을 한 것이다. / 멤버개수 4 >> 5
        f2.color = "";
        
        // 에러
        // Ambulance a = (Ambulance)f; 자손끼리는 형변환이 불가능하여 에러가 난다.
        // Car c = new Car(); 멤버개수가 4인 Car 객체를 가리키도록하고 f를 c로 형변환하고 water()를 호출하면, water()가 없는 Car객체를 가리키기 때문에 에러가 난다.
        // c.water(); 참조변수 c타입에서는 멤버개수가 4개뿐이고 water()가 없기때문에 호출하면 에러가 난다.
    }
}

class Car { // 멤버 4개
    String color;
    int door;

    // 운전하는 기능
    void drive() {
        System.out.println("brrrr~");
    }

    // 멈추는 기능
    void stop() {
        System.out.println("Stop");
    }
} // class의 끝

class FireEngine extends Car{ // 멤버 5개
    void water() {
        System.out.println("water!!!");
    }
} // class의 끝

class Ambulance extends Car { // 멤버 5개
    void a() {
        System.out.println(" ");
    }
} // class의 끝