JavaStudy

TIL JAVA #3-3

린예쑰 2023. 12. 1. 20:55

 

상속

μ˜€λ²„λΌμ΄λ”© 


<객체지ν–₯의 꽃 상속!>

 

μžλ°”μ—λŠ” μƒμ†μ΄λΌλŠ” κ°œλ…μ΄ μ‘΄μž¬ν•˜λŠ”λ° μžμ‹ ν΄λž˜μŠ€κ°€ λΆ€λͺ¨ν΄λž˜μŠ€λ₯Ό 상속 받을 수 μžˆλ‹€.(ν•„λ“œμ™€ λ©”μ„œλ“œ 같은 것듀)

# 상속을 톡해 μ½”λ“œ 쀑볡 제거, μž¬μ‚¬μš©μ„± 증가 이둜 인해 생산성과 μœ μ§€λ³΄μˆ˜μ— μœ λ¦¬ν•΄μ§„λ‹€.

 

상속

-> extends ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•΄ μ •μ˜ν•  수 μžˆλ‹€.

- ν•΄λ‹Ή ν‚€μ›Œλ“œμ˜ μ˜λ―ΈλŒ€λ‘œ 상속을 'ν™•μž₯' 의 κ°œλ…μœΌλ‘œ μ΄ν•΄ν•˜λ©΄ μ’‹λ‹€.

- μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀λ₯Ό λ¬Όλ €λ°›μ•„ μƒˆλ‘­κ²Œ ν•„λ“œ, λ©”μ„œλ“œλ₯Ό μ •μ˜ν•  수 μžˆλ‹€. μžμ‹ 클래슀의 멀버 κ°œμˆ˜λŠ” 늘 λΆ€λͺ¨μ˜ 것과 κ°™κ±°λ‚˜ λ§Žλ‹€.

(μžμ‹ ν΄λž˜μŠ€κ°€ 더 큰 범주라고 μƒκ°ν•˜λ©΄ νŽΈν•¨.)

 

예제λ₯Ό 톡해 μ‚΄νŽ΄λ³΄λ©΄ 훨씬 이해가 λΉ λ₯΄λ‹€.

 

#Car -> λΆ€λͺ¨ 클래슀

public class Car {

    String company; // μžλ™μ°¨ νšŒμ‚¬
    private String model; // μžλ™μ°¨ λͺ¨λΈ
    private String color; // μžλ™μ°¨ 색상
    private double price; // μžλ™μ°¨ 가격

    double speed;  // μžλ™μ°¨ 속도 , km/h
    char gear = 'P'; // κΈ°μ–΄μ˜ μƒνƒœ, P,R,N,D
    boolean lights; // μžλ™μ°¨ μ‘°λͺ…μ˜ μƒνƒœ

    public String getModel() {
        return model;
    }

    public void setModel(String model) {
        this.model = model;
    }

    public double gasPedal(double kmh, char type) {
        changeGear(type);
        speed = kmh;
        return speed;
    }

    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public char changeGear(char type) {
        gear = type;
        return gear;
    }

    public boolean onOffLights() {
        lights = !lights;
        return lights;
    }

    public void horn() {
        System.out.println("λΉ΅λΉ΅");
    }

}

 

#SportsCar -> μžμ‹ 클래슀

public class SportsCar extends Car{
    String engine;
    public void booster() {
        System.out.println("엔진 " + engine + " λΆ€μ•™~\n");
    }
}

 

#Main

public class Main {
    public static void main(String[] args) {
        // λΆ€λͺ¨ 클래슀 κ°μ²΄μ—μ„œ μžμ‹ 클래슀 멀버 μ‚¬μš©
        Car car = new Car();
        // car.engine = "Orion"; // 였λ₯˜  ->μžμ‹ν΄λž˜μŠ€μ—μ„œ μ •μ˜λœ λΆ€λΆ„.
        // car.booster(); // 였λ₯˜

        // μžμ‹ 클래슀 객체 생성
        SportsCar sportsCar = new SportsCar();
        sportsCar.engine = "Orion"; //μ—¬κΈ°μ—μ„œ μ‚¬μš©ν•΄μ•Ό λœλ‹€.
        sportsCar.booster();

        // μžμ‹ 클래슀 κ°μ²΄μ—μ„œ λΆ€λͺ¨ 클래슀 멀버 μ‚¬μš©
        sportsCar.company = "GENESIS";
        sportsCar.setModel("GV80");
        System.out.println("sportsCar.company = " + sportsCar.company);
        System.out.println("sportsCar.getModel() = " + sportsCar.getModel());
        System.out.println();

        sportsCar.horn();
        System.out.println(sportsCar.changeGear('D'));
    }
}

 

μ½”λ“œμ—μ„œ λ³Ό 수 μžˆλ“―, μžμ‹ ν΄λž˜μŠ€λŠ” λΆ€λͺ¨ 클래슀λ₯Ό 상속 λ°›μ•˜κΈ° λ•Œλ¬Έμ— ν•΄λ‹Ή ν΄λž˜μŠ€μ—μ„œ λ”°λ‘œ μ •μ˜ν•˜μ§€ μ•Šμ•„λ„ λΆ€λͺ¨ 클래슀의 멀버λ₯Ό 자유자재둜 μ‚¬μš©μ΄ κ°€λŠ₯ν•˜λ‹€.

 

μ°Έκ³ ) 9번째 쀄, ν΄λž˜μŠ€λŠ” 섀계도일 뿐 μΈμŠ€ν„΄μŠ€ν™”λ₯Ό ν•΄μ„œ 객체λ₯Ό λ§Œλ“€μ–΄μ•Όν•¨! 


#ν΄λž˜μŠ€κ°„μ˜ 관계 

- 상속관계: is 

 ex) μŠ€ν¬μΈ μΉ΄λŠ” μžλ™μ°¨μ΄λ‹€. μΌ€μ΄ν¬λŠ” λ””μ €νŠΈμ΄λ‹€.

- 포함관계: has

 ex) μžλ™μ°¨λŠ” 타이어λ₯Ό κ°–κ³  μžˆλ‹€. μ„ ν’κΈ°λŠ” λ‚ κ°œλ₯Ό κ°–κ³  μžˆλ‹€.

 

-> Car ν΄λž˜μŠ€μ— ν¬ν•¨λ˜λŠ” 세가지 클래슀

 

# Car 클래슀 (포함관계)

public class Car {

    static final String company = "GENESIS"; // μžλ™μ°¨ νšŒμ‚¬
    String model; // μžλ™μ°¨ λͺ¨λΈ
    String color; // μžλ™μ°¨ 색상
    double price; // μžλ™μ°¨ 가격

    double speed;  // μžλ™μ°¨ 속도 , km/h
    char gear = 'P'; // κΈ°μ–΄μ˜ μƒνƒœ, P,R,N,D
    boolean lights; // μžλ™μ°¨ μ‘°λͺ…μ˜ μƒνƒœ

    Tire[] tire;
    Door[] door;
    Handle handle;

    public Car(String model, String color, double price) {
        this.model = model;
        this.color = color;
        this.price = price;
    }

    public void setTire(Tire ... tire) {
        this.tire = tire;
    }

    public void setDoor(Door ... door) {
        this.door = door;
    }

    public void setHandle(Handle handle) {
        this.handle = handle;
    }

    public double gasPedal(double kmh, char type) {
        changeGear(type);
        speed = kmh;
        return speed;
    }

    public double brakePedal() {
        speed = 0;
        return speed;
    }

    public char changeGear(char type) {
        gear = type;
        return gear;
    }

    public boolean onOffLights() {
        lights = !lights;
        return lights;
    }

    public void horn() {
        System.out.println("λΉ΅λΉ΅");
    }
}

 

ν¬ν•¨λ˜λŠ” ν΄λž˜μŠ€λ“€μ΄ ν•„λ“œ, μƒμ„±μžμ— μ •μ˜λœ 것을 λ³Ό 수 μžˆλ‹€.

 

# Main 클래슀 (포함관계)

public class Main {
    public static void main(String[] args) {
        // μžλ™μ°¨ 객체 생성
        Car car = new Car("GV80", "Black", 50000000);

        // μžλ™μ°¨ λΆ€ν’ˆ : 타이어, μ°¨λ¬Έ, ν•Έλ“€ μ„ μ–Έ
        Tire[] tires = new Tire[]{
                new Tire("KIA", 150000), new Tire("금호", 150000),
                new Tire("Samsung", 150000), new Tire("LG", 150000)
        };
        Door[] doors = new Door[]{
                new Door("LG", "FL"), new Door("KIA", "FR"),
                new Door("Samsung", "BL"), new Door("LG", "BR")
        };
        Handle handle = new Handle("Samsung", "S");


        // μžλ™μ°¨ 객체에 λΆ€ν’ˆ 등둝
        car.setTire(tires);
        car.setDoor(doors);
        car.setHandle(handle);

        // λ“±λ‘λœ λΆ€ν’ˆ ν™•μΈν•˜κΈ°
        for (Tire tire : car.tire) {
            System.out.println("tire.company = " + tire.company);
        }
        System.out.println();

        for (Door door : car.door) {
            System.out.println("door.company = " + door.company);
            System.out.println("door.location = " + door.location);
            System.out.println();
        }
        System.out.println();

        // μžλ™μ°¨ ν•Έλ“€ μΈμŠ€ν„΄μŠ€ μ°Έμ‘°ν˜• λ³€μˆ˜μ— μ €μž₯
        Handle carHandle = car.handle;
        System.out.println("carHandle.company = " + carHandle.company);
        System.out.println("carHandle.type = " + carHandle.type + "\n");

        // μžλ™μ°¨ ν•Έλ“€ μ‘°μž‘ν•΄λ³΄κΈ°
        carHandle.turnHandle("Right");
        carHandle.turnHandle("Left");
    }
}

 

μƒμ„±μž 뢀뢄이 κΈ΄κ°€λ―Όκ°€ν–ˆλŠ”λ° 포함관계λ₯Ό κ³΅λΆ€ν•˜λ©΄μ„œ μžμ—°μŠ€λŸ½κ²Œ 이해가 λ˜μ—ˆλ‹€.

 Main λ©”μ„œλ“œμ— μ •μ˜λœ 데이터λ₯Ό λ°›μ•„μ™€μ„œ ν•΄λ‹Ή 클래슀 ν•„λ“œμ— μ €μž₯ν•œλ‹€. 이것을 각 클래슀의 μƒμ„±μžλ₯Ό 톡해 ν•  수 μžˆλ‹€!

 

#닀쀑상속

- μžλ°”μ—μ„œλŠ” 닀쀑상속을 μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€. μ‰½κ²Œ 말해 λΆ€λͺ¨κ°€ μ—¬λŸ¬ μžμ‹μ„ κ°–λŠ” 건 κ°€λŠ₯ν•˜λ‚˜ μžμ‹μ΄ μ—¬λŸ¬ λΆ€λͺ¨λ₯Ό κ°€μ§ˆ 수 μ—†μŒ.

- 닀쀑상속을 μ§€μ›ν•˜κ²Œ 되면 ν΄λž˜μŠ€κ°„μ˜ 관계가 λ³΅μž‘ν•΄μ§€κ³  λ§Œμ•½ μžμ‹ ν΄λž˜μŠ€κ°€ μ—¬λŸ¬κ°œμ˜ λΆ€λͺ¨ν΄λž˜μŠ€λ₯Ό 상속 λ°›μ•˜λŠ”λ°

  각기 λ‹€λ₯Έ λΆ€λͺ¨ν΄λž˜μŠ€κ°€ 같은 μ΄λ¦„μ˜ 멀버 λ³€μˆ˜λ₯Ό κ°–κ³  μžˆλ‹€λ©΄? 이것을 ꡬ뢄할 방법이 μ—†λ‹€.

 

# final 클래슀, λ©”μ„œλ“œ

- 기본적으둜 상속은 μžμ‹ ν΄λž˜μŠ€κ°€ λΆ€λͺ¨ 클래슀λ₯Ό μž¬μ •μ˜ν•˜μ—¬ μ‚¬μš©ν•  수 있게 ν•˜λŠ” 것이 λͺ©μ μ΄λ‹€. 그런데 변경이 λΆˆκ°€λŠ₯ν•œ 클래슀, λ©”μ„œλ“œλ₯Ό μƒμ†λ°›λŠ”κ²Œ 무슨 μ˜λ―Έκ°€ μžˆμ„κΉŒ? κ·Έλ ‡κΈ° λ•Œλ¬Έμ— final ν‚€μ›Œλ“œκ°€ 뢙은 ν΄λž˜μŠ€λŠ” 더 이상 상속할 수 μ—†λŠ” ν΄λž˜μŠ€κ°€ λœλ‹€.

 

#Object

- 말 κ·ΈλŒ€λ‘œ "객체"λ₯Ό μ˜λ―Έν•˜λŠ” 단어이며 보톡 Object 클래슀λ₯Ό μ˜λ―Έν•œλ‹€.

** Object ν΄λž˜μŠ€λŠ” Javaλ‚΄μ˜ λͺ¨νŠΌ ν΄λž˜μŠ€λ“€μ˜ μ΅œμƒμœ„ λΆ€λͺ¨ ν΄λž˜μŠ€μ΄λ‹€!


 

μ˜€λ²„λΌμ΄λ”© / super

#μ˜€λ²„λΌμ΄λ”©

- λΆ€λͺ¨λ‘œλΆ€ν„° 상속받은 λ©”μ„œλ“œμ˜ λ‚΄μš©μ„ μž¬μ •μ˜ν•˜λŠ” 것을 μ˜€λ²„λΌμ΄λ”© 이라고 ν•œλ‹€.

 

μ• λ„ˆν…Œμ΄μ…˜ @override λ₯Ό μ‚¬μš©ν•œλ‹€.

 

@Override
public String breakPedal(){
	speed =100;		//μ›λž˜ λΆ€λͺ¨ν΄λž˜μŠ€μ—μ„œλŠ” ν•΄λ‹Ή λ©”μ„œλ“œ 호좜 μ‹œ μŠ€ν”Όλ“œ 0으둜 λ§Œλ“€μ—ˆμŒ
    				//μžμ‹ ν΄λž˜μŠ€μ—μ„œ μž¬μ •μ˜
    s.o.println("λΈŒλ ˆμ΄ν¬λž€ μ—†λ‹€!");
    return speed; //100을 returnν•˜κ²Œ 됨
}

- 이렇듯 λΆ€λͺ¨ 클래슀의 λ©”μ„œλ“œλ₯Ό μžμ‹ ν΄λž˜μŠ€κ°€ μž¬μ •μ˜ν•΄μ„œ μ‚¬μš©ν•  수 있음

 

#super, super()

:this, this() μΈμŠ€ν„΄μŠ€, μƒμ„±μž 이것과 λΉ„μŠ·ν•œ λͺ¨μŠ΅μ΄λ‹€.

super: μžμ‹ν΄λž˜μŠ€μ—μ„œ λΆ€λͺ¨ν΄λž˜μŠ€μ— μ ‘κ·Όν•  수 있게 ν•΄μ£ΌλŠ” λΆ€λͺ¨μžμ‹ μ„ κ°€λ¦¬ν‚€λŠ” ν‚€μ›Œλ“œμ΄λ‹€.

 

#λ‹€ν˜•μ„±

: 객체지ν–₯&μƒμ†μ—μ„œ μ€‘μš”ν•œ νŠΉμ§•μ΄λ‹€.

-> λ‹€μ–‘ν•œ ν˜•νƒœλ₯Ό κ°€μ§ˆ 수 μžˆλ‹€.

객체λ₯Ό 생성할 λ•Œ 

Mammal mammal = new Whale(); ν•΄λ‹Ή 선언이 κ°€λŠ₯ν•˜λ‹€. -> κ³ λž˜μ—μ„œ 포유λ₯˜ 즉 λΆ€λͺ¨ν΄λž˜μŠ€λ‘œ μžλ™μœΌλ‘œ ν˜•λ³€ν™˜μ΄ κ°€λŠ₯ν•˜λ‹€.

-> μ΄λŸ°μ‹μœΌλ‘œ μžλ™ν˜•λ³€ν™˜ν•˜λŠ” 방법이 있고

또, μ°Έμ‘°λ³€μˆ˜ νƒ€μž…λ³€ν™˜μ„ ν™œμš©ν•΄μ„œ λ‹€ν˜•μ„±μ„ κ΅¬ν˜„ν•  수 μžˆλ‹€!

 

- instance of

: λ‹€ν˜•μ„± κΈ°λŠ₯으둜 클래슀의 μ›λž˜ 클래슀λͺ…을 ν™•μΈν•˜λŠ” 것이 ν•„μš”ν•˜λ‹€. ν•΄λ‹Ή λͺ…λ Ήμ–΄λ₯Ό 톡해 확인 κ°€λŠ₯ν•˜λ‹€.

κ²°κ³ΌλŠ” boolean νƒ€μž…μœΌλ‘œ 좜λ ₯λœλ‹€.

 

#μΆ”μƒν΄λž˜μŠ€ -> abstract ν‚€μ›Œλ“œ !

λΆ€λͺ¨ν΄λž˜μŠ€ abstract 클래슀 & λ©”μ„œλ“œ

μžμ‹ν΄λž˜μŠ€ λΆ€λͺ¨ν΄λž˜μŠ€λ₯Ό extends, μΆ”μƒλ©”μ„œλ“œλ₯Ό λ°˜λ“œμ‹œ @override ν•΄μ„œ μ‚¬μš©ν•΄μ•Όν•¨!

 

λ§Œμ•½ 클래슀 A, B, C 에 λ©”μ„œλ“œκ°€ 각각 3κ°œμ”© μžˆλ‹€. 그런데 μ½”λ“œλ₯Ό λ³΄λ‹ˆ 2κ°œλŠ” μ™„μ „νžˆ λ˜‘κ°™κ³  ν•œ λ©”μ„œλ“œλ§Œ λ‚΄μš©μ΄ λ‹€λ₯΄λ‹€.

κ·Έλ ‡λ‹€λ©΄, 이럴 λ•Œ λΆ€λͺ¨ 클래슀λ₯Ό 생성해 μ™„μ „νžˆ λ˜‘κ°™μ€ λ©”μ„œλ“œ λ‘κ°œλŠ” 일반 λ©”μ„œλ“œλ‘œ μ •μ˜ν•˜κ³  λ‹€λ₯Έ λ‚˜λ¨Έμ§€ ν•œ λ©”μ„œλ“œλ§Œ μΆ”μƒλ©”μ„œλ“œλ‘œ μž‘μ„±ν•΄ μžμ‹ 클래슀 A, B, C κ°€ 그것을 @override ν•˜μ—¬ ν•΄λ‹Ή λΆ€λΆ„λ§Œ 각각 λ‹€λ₯΄κ²Œ μž‘μ„±ν•΄μ£Όλ©΄ 될 것이닀.

 

-> μ½”λ“œλ‘œ ν™•μΈν•˜κΈ°

- Car (λΆ€λͺ¨)

public abstract Car{
	String company;
    String color;
    double speed;
    
    public double gasPedal(){
    	speed = kmh;
        return speed;
    }
    
    public double breakPedal(){
    	speed = 0;
        return speed;
    } 
    
    public abstract void horn();//μΆ”μƒλ©”μ„œλ“œλŠ” μ€‘κ΄„ν˜Έμ—†μ΄ μ΄λ ‡κ²Œ μž‘μ„±ν•˜λ©΄ λœλ‹€.
    
}

 

- AudiCar (μžμ‹) .. νŽΈμ˜μƒ μžμ‹ν΄λž˜μŠ€λŠ” ν•˜λ‚˜λ§Œ μž‘μ„±ν•˜μ˜€λ‹€.

public AudiCar extends Car { //λΆ€λͺ¨ν΄λž˜μŠ€ 상속받고
	
    @Override //μ˜€λ²„λΌμ΄λ”©ν•΄μ„œ
    public void horn(){
    	System.out.println("λΉ΅λΉ΅!"); //μΆ”μƒλ©”μ„œλ“œλ₯Ό μ™„μ„±μ‹œμΌœμ£Όλ©΄ λœλ‹€.
    }
    //λ‹€λ₯Έ ν•„λ“œλ‚˜ λ©”μ„œλ“œλŠ” λ‹Ήμ—°νžˆ 상속받은 μƒνƒœ!
}

 

μ—¬κΈ°κΉŒμ§€ 상속! 일단 끝!


#interface 

 

- 두 객체λ₯Ό μ—°κ²°ν•΄μ£ΌλŠ” 맀개체 역할을 ν•œλ‹€.

- 상속관계가 μ—†λŠ” μ„œλ‘œ λ‹€λ₯Έ ν΄λž˜μŠ€λ“€μ΄ μ„œλ‘œ λ™μΌν•œ λ©”μ„œλ“œλ₯Ό κ΅¬ν˜„ν•΄μ•Όν•  λ•Œ μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ‚¬μš©ν•˜λ©΄ λœλ‹€.

- implements ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ μΈμŠ€ν„΄μŠ€λ₯Ό κ΅¬ν˜„ν•  수 μžˆλ‹€.

 

^ λͺ¨λ“  λ©€λ²„λ³€μˆ˜λŠ” public static final 이어야 함.

^ λͺ¨λ“  λ©”μ„œλ“œλŠ” public abstract 이어야 함.

 

++μΈν„°νŽ˜μ΄μŠ€λŠ” μΆ”μƒν΄λž˜μŠ€μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ 직!μ ‘! μΈμŠ€ν„΄μŠ€λ₯Ό 생성할 수 μ—†κΈ° λ•Œλ¬Έμ— ν΄λž˜μŠ€μ— κ΅¬ν˜„λ˜μ–΄ μƒμ„±λœλ‹€.

 

+ μΈν„°νŽ˜μ΄μŠ€κ°„μ˜ 상속이 κ°€λŠ₯ν•˜κ³  μ΄λ•ŒλŠ” extends μ‚¬μš©.

+ μΈν„°νŽ˜μ΄μŠ€λŠ” ν΄λž˜μŠ€μ™€ 달리 닀쀑상속이 κ°€λŠ₯ν•˜λ‹€.

 

예제λ₯Ό μ‚΄νŽ΄λ³΄μž!

public class Main extends D implements C { //Main은 D클래슀 상속받고
										  //C μΈν„°νŽ˜μ΄μŠ€ implements도 함. 
	//a(), b() -> μΈν„°νŽ˜μ΄μŠ€μ˜ μΆ”μƒλ©”μ„œλ“œ μ˜€λ²„λΌμ΄λ”©.
    @Override
    public void a() {
        System.out.println("A");
    }

    @Override
    public void b() {
        System.out.println("B");
    }

	
    @Override
    void d() {
        super.d();
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.a();
        main.b();
        main.d();
    }
}

interface A {
    void a(); //μΆ”μƒλ©”μ„œλ“œ
}

interface B {
    void b(); //μΆ”μƒλ©”μ„œλ“œ public abstract λŠ” μƒλž΅λ¨
}

interface C extends A, B { //μΈν„°νŽ˜μ΄μŠ€κ°„ 닀쀑상속!
}

class D {
    void d() {
        System.out.println("D");
    }
}

 

'JavaStudy' μΉ΄ν…Œκ³ λ¦¬μ˜ λ‹€λ₯Έ κΈ€

TIL Java 3-*  (2) 2023.12.04
TIL JAVA #3-2  (3) 2023.12.01
TIL JAVA #3-1  (0) 2023.11.30
TIL JAVA #2-4  (1) 2023.10.20
TIL JAVA #2-3  (0) 2023.10.19