K-Digital Training/내일배움캠프

자바 3주차

hoonssss 2023. 10. 20. 09:03
반응형
SMALL

Java -> 객체지향언어

객체란 세상에 존재하는 물체를 뜻하며 식별이 가능한 것을 의미

객체는 속성과 행위로 구성되어 있음

ex) 자동차는 회사, 모델, 색상, 가격, 속도 등의 속성

ex) 자동차는 가속, 브레이크, 기어변속, 조명, 경적 등의 행위

Java에서는 속성을 필드, 행위를 메서드로 정의

관계

사용 관계 : 사람 객체는 자동차 객체를 사용

포함 관계 : 자동차 객체는 타이어, 차문, 핸들객체를 포함

상속 관계 : 자동차, 기차 객체가 비슷한 부품을 사용할 때 자동차 객체와 기차 객체는 기계시스템 객체를 상속 받음

객체지향언어 특징

캡슐화, 상속, 다형성, 추상화

캡슐화

- 속성(필드)과 행위(메서드)를 하나로 묶어 객체로 만든 것, 내부 구현 내용은 외부에서 알 수 없게 숨기는 것

- 메서드를 통해 접근할 수 있음, 숨기는 이유는 보안때문(객체가 변화하지 않게 하기 위해)

- 캡슐화된 필드, 메서드를 노출할지 감출 지 결정하기 위해 접근제어자(public, private ...)를 사용

상속

- 객체지향은 부모 객체와 자식 객체가 존재

- 부모 객체는 필드와 메서드를 자식 객체에게 물려주어 자식 객체가 이를 사용할 수 있도록 만듬

상속을 하는 이유

1. 각각의 객체들을 상속관계로 묶음으로써 객체 간의 구조를 파악하기 쉬움

2. 부모 객체의 필드 메서드 수정 시 자식관계도 변경됨으로써 일관성을 유지하기 좋음

3. 부모 객체에서 상속받아 자식 객체가 사용함으로 코드의 중복이 줄어들며 코드의 재사용성이 증가

다형성

- 하나의 행위에 대해 다른 여러가지 형태로 재구성되는 것

추상화

- 객체에서 공통된 부분들을 모아 상위 개념으로 새롭게 선언하는 것

- 공통적이고 중요한 것들을 모아 객체를 모델링함

- ex) 가속, 브레이크, 속도와 같은 것들을 모아서 자동차라는 객체를 모델링함

package Week3;

public class Car {
    //필드영역
    //고유데이터영역
    String company;
    String model = "GV80";
    String color;
    double price;
    //상태데이터영역
    double speed;
    char gear;
    boolean lights = true;
    //객체 데이터 영역
    Tire tire = new Tire(); //인스턴스화
    Door door;
    Handle handle;

    //생성자 : 처음 객체가 생성될 떄(인스턴스) 어떤 값이 필수로 들어와야 하는지 정의
    //생성자 constructor -> 클래스의 이름과 동일하게 함
    public Car (){
        //아무것도 없는 상태 = 기본생성자
    }
    //메서드 영역
    //input kmh
    //output speed
    double gasPedal(double kmh, char type){
        changeGear(type); //gasPedal을 실행하면 changeGear도 변함
        speed = kmh;
        return speed;
    }

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

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

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

    void horn(){
        System.out.println("클락션");
    }//return(반환값)이 없다면 void

    // 가변길이 메서드
    void carSpeeds(double ... speeds){
        for(double v : speeds){
            System.out.println("v = " + v);
        }
    }
}
package Week3;

public class Main {
//    public static void main(String[] args) {
//        Car car1 = new Car(); //클래스 이름 = new 생성자();
//        Car car2 = new Car();
//        System.out.println(car1); //참조형변수처리, 객체
      public static void main(String[] args) {
          Car[] carArray = new Car[3];
          Car car1 = new Car();
          car1.changeGear('P'); //char이기 때문에 '
          carArray[0] = car1;

          Car car2 = new Car();
          car2.changeGear('N');
          carArray[1] = car2;

          Car car3 = new Car();
          car3.changeGear('D');
          carArray[2] = car3;

          for(Car car : carArray){
              System.out.println(car.gear);
          }
    }
}

필드는 데이터를 저장, 변경하는 역할을 담당

메서드를 생성할때 반환값(return)이 없으면 void를 사용 단 void사용 시 return사용 하여 원하는 지점에서 메서드를 종료할 수 있음.

매개변수(parameter)는 메서드를 호출할 때 전달할려는 값을 받기 위해 사용되는 변수

가변길이의 매개변수도 선언가능(Spread)

void carSpeeds(double ... speeds) {
    for (double v : speeds) {
        System.out.println("v = " + v);
    }
}

double ... speeds 이렇게 ...을 사용하면 아래처럼 매개값을 , 로 구분하여 개수 상관없이 전달 가능

carSpeeds(100, 80);

carSpeeds(110, 120, 150);

호출 시

car.carSpeeds(10,20)
//출력값 
//v = 10 
//v = 20
   double gasPedal(double kmh, char type){
        changeGear(type); //gasPedal을 실행하면 changeGear도 변함
        speed = kmh;
        return speed;
    }
...
    char changeGear(char type){
        gear = type;
        return gear;
    }

gasPedal실행시 kmh, type부분을 받으면서 changeGear부분 값도 값이 변함 -> gear가 type으로 변함

메서드 오버로딩

함수가 하나의 기능만을 구현하는것이 아니라 하나의 메서드 이름으로 여러 기능을 구현하도록 하는 것

메서드의 이름은 같고 매개변수의 개수 또는 타입 또는 순서가 달라야함

오버로딩은 매개변수의 차이로만 구현 가능

기본형 매개변수

매개변수의 타입이 기본형일 때는 값 자체가 복사되기 때문에 변수의 원본값이 변하지 않음

참조형 매개변수

매개변수의 타입이 참조형일 때는 원본 주소를 알기 때문에 값을 읽어보고, 변경하는 것도 가능

멤버 = 필드 + 메서드

인스턴스 멤버 = 인스턴스 필드 + 인스턴스 메서드

클래스 멤버 = 클래스 필드 + 클래스 메서드

필드와 메서드는 선언하는 방법에 따라서 인스턴스, 클래스 멤버로 구분가능

인스턴스 멤버는 객체 생성 후 사용가능, 클래스 멤버는 객체 생성 없이 사용가능

인스턴스멤버

객체의 인스턴스 필드는 각각의 인스턴스 마다 고유하게 값을 가지고 있음

인스턴스를 통해서만 메서드가 사용될 수 있도록 제한을 걸어둠

클래스멤버

Java의 클래스 로더에 의해 메서드 영역에 저장되고 사용

클래스 멤버는 메서드 영역의 클래스와 같은 위치에 고정적으로 위치하고 있는 멤버

필드와 메서드를 클래스 멤버로 만들기 위해서는 static키워드를 사용

즉 static메서드(클래스)는 인스턴스화 안시켜도 되니까 바로 사용 가능(void는 반환여부 return)

일반적으로 공용적인 데이터를 저장할때, 인스턴스 필드를 사용하지 않고 실행되는 메서드에 선언

클래스 메서드는 클래스 메서드만 호출 가능

인스턴스는 인스턴스, 클래스 둘다 호출 가능

지역변수(<->전역변수)

package Week3.sample;

public class Main {
    public static void main(String[] args) {
        Main main = new Main(); //기본생성자 public Main() {}
        System.out.println(main.getNumber()); //+=1 이지만 지역변수 이기 때문에 초기화 생성 반복 즉 2 값만 나옴
        System.out.println(main.getNumber());

        System.out.println(COMPANY); //클래스 메소드
    }

    //메서드
    public int getNumber(){
        //지역변수 : 해당 메서드가 실행될 때 마다 독립적인 값을 저장하고 관리
        //메서드 내부에서 정의될때 생성, 메서드가 종료되면 소멸
        int number = 1;
        number +=1;
        return number;
    }

    static final String COMPANY = "GENESIS";//final 및 상수는 전체를 대문자로 만듬
}

 

필드

생성자

메서드

public Car() {} // 생성자 선언
.
.
Car car = new Car(); //생성자 호출, 인스턴스화
 

모든 클래스는 반드시 생성자가 하나 이상 존재.

클래스에 생성자를 하나도 선언하지 않았다면 컴파일러는 기본 생성자를 바이트코드 파일에 자동으로 추가시켜줌 이러한 경우에는 기본 생성자 생략 가능.

단 하나라도 생성자가 선언되어있다면 컴파일러는 기본 생성자를 설정하지 않음

생성자, 매개변수 3개를 받아야 Car를 생성할 수 있는데 매개변수 modelName, nolorName, priceValue 값을 받지 않으면 에러

    //오버로딩 똑같은 메서드이름을 사용하면서 다른 기능을 사용
    public Car(String modelName) {
        model = modelName;
    }

    public Car(String modelName, String colorName) {
        model = modelName;
        color = colorName;
    }

    public Car(String modelName, String colorName, double priceValue) {
        model = modelName;
        color = colorName;
        price = priceValue;
    }
    -----------------------------------------------------------------
        // Car car1 = new Car(); // 오류 발생        
        // GV60 모델만 기본으로 선택      
        Car car2 = new Car("GV60"); //model 값 GV60
        System.out.println("car2.model = " + car2.model);
        System.out.println("car2.gear = " + car2.gear + "\n");

        // GV70 모델, 색상 Blue 만 기본으로 선택
        Car car3 = new Car("GV70", "Blue"); //model GV70, color Blue
        System.out.println("car3.model = " + car3.model);
        System.out.println("car3.color = " + car3.color);
        System.out.println("car3.gear = " + car3.gear + "\n");

        // GV80 모델, 색상 Black, 가격 50000000 으로 완전하게 고정된 경우
        Car car4 = new Car("GV80", "Black", 50000000); //model GV80, color Black, price 50000000 
        System.out.println("car4.model = " + car4.model);
        System.out.println("car4.color = " + car4.color);
        System.out.println("car4.price = " + car4.price);
        System.out.println("car4.gear = " + car4.gear + "\n");
    }

this

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

객체필드명 = 매개변수명 인데 두 이름이 같으면 구분을 위해서 this을 써줌(문법상 오류가 발생하지는 않지만 이름이 같을때는 쓰는게 조음)

Car returnInstance() {
    return this;
}//Car type을 return
Car car3 = new Car();
System.out.println(car3.returnInstance().model); // car3의 model
System.out.println(car3.returnInstance().color); // car3의 color
System.out.println(car3.returnInstance().price); // car3의 price

this() => 생성자를 표현

public Car(String model) { //model값만 받아오기 떄문
    this.model = model;
    this.color = "Blue";
    this.price = 50000000;
}

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

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

public Car(String model) {
    this(model, "Blue", 50000000);
}

public Car(String model, String color) {
    this(model, color, 100000000);
}

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

this() 키워드를 사용해서 다른 생성자를 호출할 때는 반드시 해당 생성자의 첫 줄에 작성

public Car(String model) {
    System.out.println("model = " + model);
    this(model, "Blue", 50000000);
}

위처럼 this()위에 다른코드 있을 시 오류 발생

제어자는 클래스, 변수, 메서드의 선언부에 사용되어 부가적인 의미를 부여

접근 제어자 : public, protected, default, private

그 외 제어자 : static, final, abstract

지정되어 있지 않는다면 기본값은 default

public : 접근 제한이 없음(접근 다 가능)

protected : 같은 패키지 내에서 다른 패키지의 자손클래스에서 접근 가능

default : 같은 패키지 내에서만 접근 가능

private : 같은 클래스 내에서만 접근 가능

public->->->private 갈수록 제한 사항 많아짐

클래스 : public, default 사용가능

메서드 & 멤버변수 : public, protected, default, private 사용가능

지역변수 : X

접근 제어자를 이용한 캡슐화(은닉화)

- 접근제어자는 클래스 내부에 선언된 데이터를 보호하기 위해 사용(은닉성)

Getter Setter(private 필드를 읽어오거나 저장하기 위해)

직접적인 값의 조회, 세팅을 방지하기 위해사용

private한 필드를 읽을 필요가 있을 때 Getter사용

메서드 이름은 get+필드명

private String model;
private String color;
private String price;
------------------------------------------------------------------------
public String getmodel(){
    return model;
}
public String getcolor(){
    return color;
}
public String getprice(){
    return price;
}

private한 필드를 저장/수정할 필요가 있을때 Setter사용

메서드의 이름은 set + 필드명

private String model;
private String color;
private String price;
------------------------------------------------------------------------
public String setmodel(String model){
    this.model = model;
}
public String setcolor(String color){
    this.color = color;
}
public double setprice(double price){
    this.price = price;
}

클래스간의 관계와 상속

클래스간의 상속은 extends키워드를 사용하여 정의

public class 자식클래스 extends 부모클래스 {

}
----------------------------------------------------------------------
public class Main extends 자식클래스{
       자식클래스 main = new 자식클래스();
       자식클래스.~~ //부모클래스 멤버까지 사용가능
}

상속은 확장의 개념

부모 클래스에 필드와 메서드가 추가되면 자식 클래스는 이를 상속받아서 사용 가능

자식 클래스에 필드와 메서드가 추가되어도 부모 클래스에는 영향이 없음(단반향)

따라서 자식클래스는 부모클래스와 필드,메서드(멤버)가 같거나 많다

클래스에 final 키워드를 지정하여 선언하면 최종적인 클래스가 됨으로 더 이상 상속할 수 없는 클래스

클래스간의 관계

상속관계 : is, ~는 ~이다. ex)스포츠카는 자동차다. 고래는 포유류다

포함관계 : has, ~는 ~를 가지고 있다. ex)자동차는 타이어, 핸들, 차문을 가지고 있다.

    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;
    }
------------------------------------------------------------------------------
        // 자동차 부품 : 타이어, 차문, 핸들 선언
        //has(포함)관계
        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) { //setTire를 통해 car.tire = 배열임
            System.out.println("tire.company = " + tire.company);
            System.out.println("tire.price = " + tire.price);
        }

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

        // 자동차 핸들 인스턴스 참조형 변수에 저장
        Handle carHandle = car.handle;
        System.out.println("carHandle.company = " + carHandle.company);
        System.out.println("carHandle.type = " + carHandle.type + "\n");

Java는 다중상속을 지원하지 않음

부모는 많은 자식에게 상속할 수 있지만 자식은 여러 부모에게 상속받을 수 없음

다중상속을 허용하면 클래스간의 관계가 복잡해짐

final 주의점

public final class Car {}

...

public class SportsCar extends Car{} // 오류가 발생

부모클래스에 final 지정 시 상속받을 수 없음

public class Car {
    public final void horn() {
        System.out.println("빵빵");
    }
}

...

public class SportsCar extends Car{
    public void horn() { // 오류가 발생합니다.
        super.horn();
    }

메서드에도 final 지정 시 최종적인 메서드가 됨으로 오버라이딩할 수 없는 메서드가 됨

Object 클래스는 Java내 모든 클래스들의 최상위 클래스이다

오버라이딩(오버로딩은 같은 메서드 이름에 다양한 기능을 구현한 것)

부모클래스로부터 상속받은 내용을 재정의 하는 것

- 선언부가 부모 클래스의 메서드와 일치해야 함

- 접근 제어자를 부모클래스의 메서드 보다 좁은 범위로 변경할 수 없음

- 예외는 부모클래스보다 많으면 안됨

    @Override
    public double brakePedal() {
        speed = 100;
        System.out.println("스포츠카에 브레이크란 없다");
        return speed;
    }
    //에노테이션(annotaion)
    @Override
    public void horn() {
        booster();
    }

Super, Super()

https://cl0clam.tistory.com/36

// 부모 클래스 Car
String model; // 자동차 모델
String color; // 자동차 색상
double price; // 자동차 가격
-----------------------------------------------------------------
// 자식 클래스 SportsCar
String model = "Ferrari"; // 자동차 모델
String color = "Red"; // 자동차 색상
double price = 300000000; // 자동차 가격
-----------------------------------------------------------------
sportsCar.setCarInfo("GV80", "Black", 50000000);
-----------------------------------------------------------------
public void setCarInfo(String model, String color, double price) { //메소드
    super.model = model; // model은 부모 필드에 set
    super.color = color; // color는 부모 필드에 set
    this.price = price; // price는 자식 필드에 set
}
-----------------------------------------------------------------
System.out.println(sportsCar.getModel()); // GV80 super호출
System.out.println(sportsCar.getColor()); // Black super호출
System.out.println(sportsCar.price()); //50000000 this 호출

선언형변환

class Mammal { //부모클래스
    // 포유류는 새끼를 낳고 모유수유를 한다.
    public void feeding() {
        System.out.println("모유수유를 합니다.");
    }
}
------------------------------------------------------------------------
class Whale extends Mammal {
    // 고래는 포유류 이면서 바다에 살며 수영이 가능하다.
    public void swimming() {
        System.out.println("수영하다.");
    }

    @Override
    public void feeding() {
        System.out.println("고래는 모유수유를 합니다.");
    }
}
------------------------------------------------------------------------

Mammal mammal = new Whale(); //부모클래스 mammal = new 자식클래스(); 즉 이렇게 생성해도 mammal임
//mammal.swimming(); swimming이 부모클래스에 선언되어있지 않기때문에 오류발생
//Whale whale = new Mammal(); 자식클래스 whale = new 부모클래스(); 오류발생 
mammal.feeding();
//자식객체 고래의 수영 기능을 사용하고 싶다면 강제형변환(자동형변환 후->강제형변환 가능이라는 조건이있음)
Whale whale = (Whale) mammal;
whale.swimming(); //사용가능

다형성(이해잘안됨)

여러 가지 형태를 가질 수 있는 능력

package Week3.poly;

public class Tire {
    String company; // 타이어 회사

    public Tire(String company) {
        this.company = company;
    }

    public void rideComfort() {
        System.out.println(company + " 타이어 승차감은?");
    }
}
------------------------------------------------------------------
package Week3.poly;

public class KiaTire extends Tire{

    public KiaTire(String company) {
        super(company);
    }

    @Override
    public void rideComfort() {
        System.out.println(super.company + " 타이어 승차감은 " + 60);
    }
}
------------------------------------------------------------------
package Week3.poly;

public class HankookTire extends Tire {

    public HankookTire(String company) {
        super(company); //부모 생성자가 기본생성자가 없고 매개변수가 있는 생성자만 있을때 super(매개변수) 사용
    }

    @Override
    public void rideComfort() {
        System.out.println(super.company + " 타이어 승차감은 " + 100);
    }
}
------------------------------------------------------------------
        Tire kiaSampleTire = new KiaTire("KIA"); //부모클래스 = 자식클래스, 부모클래스로 강제형변환 함으로써 다형성 가능
        Tire hankookSampleTire = new HankookTire("HANKOOK");
        Car car1Sample = new Car(kiaSampleTire);
        Car car2Sample = new Car(hankookSampleTire);
        // 매개변수 다형성 확인!
        Car car1 = new Car(new KiaTire("KIA")); //부모클래스 = 자식클래스, 부모클래스로 자동형변환 함으로써 다형성 가능
        Car car2 = new Car(new HankookTire("HANKOOK"));

        // 반환타입 다형성 확인!
        Tire hankookTire = car1.getHankookTire();
//      Tire kiaTire = car1.getKiaTire();
        KiaTire kiaTire = (KiaTire) car2.getKiaTire();//강제형변환

        // 오버라이딩된 메서드 호출
        car1.tire.rideComfort(); // KIA 타이어 승차감은 60
        car2.tire.rideComfort(); // HANKOOK 타이어 승차감은 100

instanceof

다형성 기능으로 인해 해당 클래스 객체의 원래 클래스명을 체크하는것이 필요한데 이때 사용할 수 있는 명령어

class Parent { }
class Child extends Parent { }
class Brother extends Parent { }

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

        Parent pc = new Child();

        Parent p = new Parent();

        System.out.println(p instanceof Object); // true 출력
        System.out.println(p instanceof Parent); // true 출력
        System.out.println(p instanceof Child);  // false 출력 p는 child의 인스턴스가 맞는지, child는 p의 인스턴스가 맞음
        System.out.println(pc instanceof Child); // true 출력

        Parent c = new Child();

        System.out.println(c instanceof Object); // true 출력
        System.out.println(c instanceof Parent); // true 출력
        System.out.println(c instanceof Child);  // true 출력

    }
}

추상클래스

클래스가 설계도라면 추상클래스는 미완성된 설계도

abstract 사용하여 추상클래스를 선언

추상클래스는 자식클래스에 상속되어 자식클래스에 의해서만 완성가능

public abstract class 추상클래스명 {

}

추상메서드

일반적인 메서드와는 다르게 {} 가 없음

public abstract class 추상클래스명 {
		abstract 리턴타입 메서드이름(매개변수, ...);
}

추상클래스 상속

상속받은 클래스에서 추상클래스의 추상메서드는 반드시 오버라이딩 되어야 함

public class 클래스명 extends 추상클래스명 {
		@Override
    public 리턴타입 메서드이름(매개변수, ...) {
		       // 실행문
    }
}

예시

공통적인 부분을 Car에 다 넣고 추상화 시킴, 원하는 horn만 @override시킴

public abstract class Car {
    String company; // 자동차 회사
    String color; // 자동차 색상
    double speed;  // 자동차 속도 , km/h

    public double gasPedal(double kmh) {
        speed = kmh;
        return speed;
    }

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

    public abstract void horn();
}
------------------------------------------------------------------------
public class ZenesisCar extends Car {

    @Override
    public void horn() {
        System.out.println("Zenesis 빵빵");
    }
}
------------------------------------------------------------------------
public class Main {
    public static void main(String[] args) {
        Car car1 = new BenzCar();
        car1.horn();
        Car car2 = new AudiCar();
        car2.horn();
        Car car3 = new ZenesisCar();
        car3.horn();
    }
}

인터페이스 선언

public interface 인터페이스명 { 

}

모든 멤버변수는 public, static, final임

모든 메서드는 public abstract(생략가능)

인터페이스구현

public class 클래스명 implements 인터페이스명 { 
			// 추상 메서드 오버라이딩
			@Override
	    public 리턴타입 메서드이름(매개변수, ...) {
			       // 실행문
	    }
}

인터페이스의 추상메서드는 구현될 때 반드시 오버라이딩 되어야함

인터페이스의 추상메서드를 일부만 구현하고 싶다면 해당 클래스(인터페이스)를 추상클래스로 바꿈

인터페이스상속

인터페이스간의 상속은 implements 가 아니라 extends 키워드를 사용

인터페이스는 일반클래스와는 다르게 다중상속을 허용함

package Week3.inter;

public class Main extends D implements C { //extends implements 순서 확인

    @Override
    public void a() {
        System.out.println("A");
    }

    @Override
    public void b() {
        System.out.println("B");
    }
    //interface C에 있는 A,B 인터페이스 void a,b사용 
    @Override
    void d() {
        super.d();
    } //interface 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();
}

interface C extends A, B { //interface는 다중상속 허용(interface끼리의 상속은 extends)
}

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

default

지정 메서드 public 생략가능

디폴트 설정 시 @Override 안함

public class Main implements A {

    @Override
    public void a() {
        System.out.println("A");
    }


    public static void main(String[] args) {
        Main main = new Main();
        main.a();
        // 디폴트 메서드 재정의(Override) 없이 바로 사용가능
        main.aa();
    }
}

interface A {
    void a();
    default void aa() { //public default void aa() 이지만 public 생략 가능
        System.out.println("AA");
    }
}

static

main으로 접근하지 않고 interface A로 바로 접근

(default, static -> interface 에서 작성)

public class Main implements A {

    @Override
    public void a() {
        System.out.println("A");
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.a();
        main.aa();
        System.out.println();

        // static 메서드 aaa() 호출
        A.aaa();
    }
}

interface A {
    void a();
    default void aa() {
        System.out.println("AA");
    }
    static void aaa() {
        System.out.println("static method");
    }
}

자동형변환

public class Main {
    public static void main(String[] args) {
      
        // A 인터페이스에 구현체 B 대입
        A a1 = new B();
        
        // A 인터페이스에 구편체 B를 상속받은 C 대입
        A a2 = new C();
    }
}

interface A { }
class B implements A {}
class C extends B {}

A를 상속받은 B, B를 상속받은 C

A -> B -> C이기 때문에

A a = new B(or c)가능

강제형변환

package Week3.interSample;

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

        // A 인터페이스에 구현체 B 대입
        A a1 = new B();
        a1.a();
        // a1.b(); // a1은 인터페이스 A 타입(자동형변환)이기 때문에 a()메서드만 가지고 있어서 불가능

        System.out.println("\nB 강제 타입변환");
        B b = (B) a1; 
        b.a();
        b.b(); // 강제 타입변환으로 사용 가능
        System.out.println();

        // A 인터페이스에 구편체 B를 상속받은 C 대입
        A a2 = new C();
        a2.a();
        //a2.b(); // 불가능
        //a2.c(); // 불가능

        System.out.println("\nC 강제 타입변환");
        C c = (C) a2;
        c.a();
        c.b(); // 강제 타입변환으로 사용 가능
        c.c(); // 강제 타입변환으로 사용 가능

    }
}

interface A {
    void a();
}

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

class C extends B {
    public void c() {
        System.out.println("C.c()");
    }
}

과제

package week3problem;

public class Main {
    public static void main(String[] args) {
        Calculator calculator = new Calculator(new AddOperation());
        System.out.println(calculator.calculation(1,2));

        calculator = new Calculator(new DivideOperation());
        System.out.println(calculator.calculation(4,2));

        calculator.setOperation(new MultiplyOperation());
        System.out.println(calculator.calculation(10,3));
    }
}
------------------------------------------------------------------------------------
package week3problem;

public class Calculator {
//    private final AddOperation addOperation;
//    private final SubstractOperation substractOperation;
//    private final MultiplyOperation multiplyOperation;
//    private final DivideOperation divideOperation;

    private AbstractOperation operation; //AbstractOperation의 상속을 받았음

    public Calculator(AbstractOperation operation){
        this.operation = operation;
    }

    public void setOperation(AbstractOperation operation){
        this.operation = operation;
    }
    public double calculation(int firstNumber, int secondNumber){
        double result = 0;
        result = operation.operate(firstNumber,secondNumber);
        return result;
    }
}
//    public double calculate(String operator, int firstNumber, int secondNumber) {
//        if (operator.equals("+")) {
//            result = addOperation.operate(firstNumber, secondNumber);
//        } else if (operator.equals("-")) {
//            result = substractOperation.operate(firstNumber, secondNumber);
//        } else if (operator.equals("*")) {
//            result = multiplyOperation.operate(firstNumber, secondNumber);
//        } else if (operator.equals("/")) {
//            result = divideOperation.operate(firstNumber, secondNumber);
//        } else if (operator.equals("%")) {
//            result = firstNumber % secondNumber;
//        }
//        return result;
//    }
------------------------------------------------------------------------------------
package week3problem;

public abstract class AbstractOperation {
    public abstract double operate(int firstNumber, int secondNumber) ;
}
------------------------------------------------------------------------------------
package week3problem;

public class AddOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return firstNumber + secondNumber;
    }

//    public double operate(int firstNumber, int secondNumber){
//        return firstNumber+secondNumber;
//    }

}
반응형
LIST

'K-Digital Training > 내일배움캠프' 카테고리의 다른 글

자바 5주차  (1) 2023.11.01
자바 4주차  (1) 2023.11.01
자바 2주차  (0) 2023.10.20
자바 1주차  (0) 2023.10.20
내일배움캠프 시작 그리고 과제  (0) 2023.10.05