6/13

ONLYS2545·2023년 6월 13일
0

상속의 주 목적은 추상화 -> 공통의 부모


상속의 효과 중 재산을 물려받는 것은 부가적인 것, 주 목적은 추상화를 통해 타입을 일치시키기 위한 것임.
--> 체계적 개발 및 OOP 구현(다형성 확보)에 도움, 편의성↑
ex)xxx, xxx 차렷 -> X , 일동 차렷(O)


생성자 오버로딩을 통해 가격만 넣으면 출력이되도록 편하게 만들기



구성(composition) 실습해보기


package ex05.composit;

//생성자, 게터는 기본 생성 -> 세터는 필요할 때만
public class BurgerSet {
    private Burger burger;
    private Coke coke;
    private Potato potato;

    public BurgerSet() {
        this(new Burger(), new Coke(), new Potato());
        // 매개변수 자리에 new () -> 힙 주소 전달됨.
        // new Burger(); 라고만 적으면 가비지컬렉션 대상이지만, 위 방법 처럼하면 실제적으로 값이 전달되므로 가비지컬렉션 대상X
    }

    private BurgerSet(Burger burger, Coke coke, Potato potato) {
        this.burger = burger;
        this.coke = coke;
        this.potato = potato;
    }

    public Burger getBurger() {
        return burger;
    }

    public Coke getCoke() {
        return coke;
    }

    public Potato getPotato() {
        return potato;
    }

}

버거세트 가격 출력하기


package practice;

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

        BurgerSet bs2 = new BurgerSet();

        int setPrice = bs2.getPotato().getPrice() + bs2.getCoke().getPrice() + bs2.getPotato().getPrice();
        String setDesc = bs2.getPotato().getDesc() + ", " + bs2.getCoke().getDesc() + ", " + bs2.getBurger().getDesc();

        System.out.println("버거세트의 가격은" + setPrice + "입니다.");
        System.out.println("버거세트는의 구성은 " + setDesc + "입니다.");

    }

}

Solid

==> D는 DIP(의존성 역전 원칙), 추상적인 것에 의존하도록 하는 것
==> O는 OCP(개방폐쇄원칙), 새로운 파일 만드는 것은 ok, 기존 코드의 변경은 X
DIP를 지키면 자연스럽게 지켜짐

DIP

주체가 달라지면 코드를 다시 써야하는 상황이 발생하지 않도록
주체(구체적인 것)에 의존하지 않고, 추상적인 것에 의존하도록 코드를 만드는 것

ex)
왕.심문() , 왕비 심문() --> X
재판관.심문() --> O


String str ="";
Object obj = str

String 타입인 str을 최상위 클래스 Object타입의 obj 변수에 담을 수 있다.
이유는 상속과 관련이 있다. Object는 최상위 클래스이고, 자식 클래스인 str은
Object클래스를 상속했으므로, 부모 클래스 타입으로 선언될 수 있기 때문이다.
따라서 str은 묵시적 형변환이 되어 Object 타입으로 obj에 저장된다.

int b= 5;
Object obj = b;
와 같이 클래스 타입이 아닌 변수 b의 경우도 Object 타입의 변수에 담을 수 있다.
-->
자바에서 int 타입의 경우 Integer 타입의 객체로 자동 변환하여 처리하기 때문이다.


실습


package ex06;

/**
 * 1. 추상클래스는 new 할 수 없다.
 * 2. 추상클래스는 일반메서드와 추상메서드를 가질 수 있다.
 * 3. 추상클래스는 상태변수를 가질 수 있다.
 */
abstract class 동물 {

    String name;

    // 일반 메서드는 공통된 것을 규정
    // 추상 메서드는 하위 클래스에서 구현하는 것이 각각 달라져야 할 때 사용

    public void run() {
        System.out.println("달린다");
    }

    public abstract void speak();
}

class 사자 extends 동물 {

    @Override
    public void speak() {
        System.out.println("어흥");
    }

}

public class Abstract01 {
    public static void main(String[] args) {
        // new 동물();

    }
}
package ex06;

//싱글톤 패턴 - new해서 1개만 유지시키고 싶을 때, 더 이상 생성X(바론)

class 미니언 {

    public 미니언() {
        System.out.println("미니언이 생성되었습니다.");
    }

}


//싱글톤 패턴 만들기
//생성자에 Private 붙이기: 클래스 외부에서 해당 클래스의 인스턴스를 생성할 수 없게 만들고, 상속을 통한 새로운 인스턴스 생성을 방지
//private static 제어자를 활용하여 인스턴스를 생성하는 코드를 클래스 영역에 작성 
//이후 getInstance 메서드를 작성하여 instance값을 가져오기.



class 바론 {
    private static 바론 instance = new 바론();

    private 바론() {

    }

    public static 바론 getInstance() {
        return instance;
    }
}

public class Single01 {

    public static void main(String[] args) {

        미니언 m1 = new 미니언();
        미니언 m2 = new 미니언();
        미니언 m3 = new 미니언();

        System.out.println(m1.hashCode());
        System.out.println(m2.hashCode());
        System.out.println(m3.hashCode());

        바론 b1 = 바론.getInstance();
        바론 b2 = 바론.getInstance();

        System.out.println(b1.hashCode());
        System.out.println(b2.hashCode());

        if (b1 instanceof 바론) {
            System.out.println("같은 타입 입니다.");

        }

        if (b1 instanceof Object) {
            System.out.println("바론과 오브젝트는 같은 타입입니다.");
        }

    }

}
package ex06;

/**
 * 인터페이스는 new할 수 없다.
 * 인터페이스는 static 변수를 만들 수 있다.
 * 인터페이스는 추상메서드만 가진다.
 * 인터페이스는 두 가지 관점에서 사용 - 노출, 강제성
 */

interface Remote {
    int NUM = 10; // public static final 생략

    void run(); // public abstract 생략

}

public class Inter01 {
    public static void main(String[] args) {
        System.out.println(Remote.NUM);
    }

}

package ex06;

interface Remocon {
    void on();

    void off();
}

class 삼성 implements Remocon {
    @Override
    public void off() {
        System.out.println("티비 끄다");
    }

    @Override
    public void on() {
        System.out.println("티비 켜다");
    }
}

class 엘지 implements Remocon {
    @Override
    public void off() {
        System.out.println("티비 끄다");
    }

    @Override
    public void on() {
        System.out.println("티비 켜다");
    }
}

public class Inter02 {

    public static void main(String[] args) {
        Remocon s1 = new 삼성();
        s1.on();
        s1.off();

        Remocon s2 = new 엘지();
        s2.on();
        s2.off();
    }
}
package ex06;

// 구현체 : Car
interface CarAble {
    void 전진();

    void 후진();

    void 스탑();
}

// 인터페이스 보세요!!
class Car implements CarAble {
    private void a1() {
    }

    private void a2() {
    }

    private void a3() {
    }

    private void a4() {
    }

    private void a5() {
    }

    private void a6() {
    }

    private void a7() {
    }

    private void a8() {
    }

    // 앞으로 가게 하려면 a1, a3, a5, a6 를 순서대로 호출해
    // 뒤로 가게 하려면 a8, a7, a6, a5 순서대로 호출해
    // 멈추려면 a3, a7 호출하면 돼

    @Override
    public void 전진() {
        a1();
        a3();
        a5();
        a6();
        System.out.println("전진함");
    }

    @Override
    public void 후진() {
        a8();
        a7();
        a6();
        a5();
        System.out.println("후진함");
    }

    @Override
    public void 스탑() {
        a3();
        a7();
        System.out.println("멈춤");
    }
}

public class Inter03 {

    public static void start(CarAble c) {
        c.전진();
        c.스탑();
        c.후진();
    }

    public static void main(String[] args) {
        start(new Car());

    }
}

구성 vs 집합


전체가 부분에 영향을 미친다 -> 구성
전체가 부분에 영향을 미치지 않는다 - > 집합

profile
백엔드 교육과정 기록 velog입니다.

0개의 댓글