본문 바로가기
얄코의 제대로 파는 자바/섹션5 객체지향 프로그래밍

기초 활용예제들

by 백엔드 개발자 2024. 3. 10.

 

 

요약 

1.  클래스의 메서드로 인스턴스를 받을 수 있다.
2. 윈시형은 값을 인자로 받아도 복사해서 받기 때문에 원 주소의 값이 바뀌지는 않지만
객체는 참조 자료형이라 인자로 전달해도 주소를 전달하므로 동일한 위치를 가리키고,
 값수정시 동일하게 바뀐다.
3. 인스턴스를 특정한 기능이 없더라도 복합적인 정보를 체계적으로 저장하는 용도로도 사용가능하다.
4. 인스턴스 배열을 클래스의 필드로 가질 수도 있다.

 

 

슬라임 클래스


public class Slime {
    double hp = 50;
    int attack = 8;
    double defense = 0.2;

    void attack (Slime enemy) { // 💡 다른 슬라임의 인스턴스를 인자로 받음
        enemy.hp -= attack * (1 - enemy.defense);
    }
}
package sec05.chap02.ex01;

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

        Slime slime1 = new Slime();
        Slime slime2 = new Slime();

        slime1.attack(slime2);
    }
}

 

 

  • 필드의 기본값을 클래스에 초기화할 수 있다.
  • 생성자 없음(필드값들이 고정값을 가지고 있어서 따로 변환할 필요가 없었다)
  • 클래스도 자료형이기 때문에, 변수나 인자로 활용될 수 있다.(위의 attack메서드의 인자로 슬라임 인스턴스를 받고 있다.)
  • 참조 자료형이기 때문에 주소값을 가지고 있다. 그래서 attact메서드에서 매개인자 인스턴스의 체력이 변경되도 실제 인스턴스 체력에 반영되는 것이다.->객체는 참조형 - 인자로 전달될 시 내용이 변경될 수 있음
  • 클래스는 같아도, 인스턴스 각각 필드값은 별개이다. (강남점의 값과 판교점의 값이 다르듯이)

 

정수배열 정보 클래스


public class IntArrayInfo {
    int count;
    int max;
    int min;
    int sum; // 기본 0
    double average;

    IntArrayInfo(int[] nums) {
        count = nums.length;
        max = nums[0];
        min = nums[0];

        for (int num : nums) {
            max = max > num ? max : num;
            min = min < num ? min : num;
            sum += num;
        }
        // 소수부를 잃지 않도록 먼저 1.0을 곱하여 double로 만듦
        average = 1.0 * sum / nums.length;
    }
}
		int[] ary1 = {3, 5, 9, 2, 8, 1, 4};
        int[] ary2 = {382, 194, 27, 915, 138};

        IntArrayInfo aryInf1 = new IntArrayInfo(ary1);
        IntArrayInfo aryInf2 = new IntArrayInfo(ary2);

        int ary1Max = aryInf1.max;
        double ary2Avg = aryInf2.average;
        int ary1n2Sum = aryInf1.sum + aryInf2.sum;

 

  • 배열을 인스턴스로 받아서 최대값, 최소값등 다소 복잡한 계산을 내부적으로 처리하고 있다.
  • 특정한 기능이 없더라도 복합적인 정보를 특정형식으로 체계적으로 저장하기 위해서 인스턴스와 클래스를 활용할 수도 있다. 

 

 

 

 

 

얄코치킨과 치킨메뉴 클래스


  • 클래스의 필드로 다른 클래스의 인스턴스를 담은 배열을 가짐
    • 클래스의 인스턴스가 배열 등 다른 자료형에도, 그 반대로도 포함될 수 있음
  • 클래스는 둘 이상의 생성자를 가질 수 있음
  • 인스턴스를 반환하는 메소드

인스턴스안에 다른 클래스 인스턴스 자료형 배열을 가지고 있는 모습

 

public class YalcoChicken {
    int no;
    String name;
    ChickenMenu[] menus;

    YalcoChicken (int no, String name, ChickenMenu[] menus) {
        this.no = no;
        this.name = name;
        this.menus = menus;
    }

    ChickenMenu orderMenu (String name) {
        for (ChickenMenu menu : menus) {
            if (menu.name.equals(name)) { // 🔴
                return menu;
            }
        }
        return null;
    }
}
public class ChickenMenu {
    String name;
    int price;
    String cook = "fry";

    ChickenMenu (String name, int price) {
        this.name = name;
        this.price = price;
    }

    ChickenMenu (String name, int price, String cook) {
        this.name = name;
        this.price = price;
        this.cook = cook;
    }
}
				ChickenMenu[] menus = {
                new ChickenMenu("후라이드", 10000),
                new ChickenMenu("양념치킨", 12000),
                new ChickenMenu("화덕구이", 15000, "bake")
        };
        YalcoChicken store1 = new YalcoChicken(3, "판교", menus);

        ChickenMenu order1 = store1.orderMenu("양념치킨");
        ChickenMenu order2 = store1.orderMenu("오븐구이");

 

YalcoChicken.orderMenu(String name) : 메뉴의 이름을 인자로 받는다. 얄코치킨 인스턴스의 메뉴 배열을 for문으로 돌면서 인자의 이름과 일치하면 반환하는 메서드.

 

 

 

 

주소 확인하기

  • Main클래스에서 생성헀던 menus의 2번을 보면 710 주소를 가지고 있고, 이 menus를 인자로 생성한 store1의 메뉴 2번 또한 710번을 가지고 있다.
  • 클래스,인스턴스, 인스턴스 배열 모두 참조 자료형이고, 인스턴스를 배열에 넣어도 모두 같은 곳을 가리키고 있어 수정하면 같이 바뀐다.

 

				int int1 = 1;
        int int2 = int1;
        int1 = 2;

        String str1 = "헬로";
        String str2 = str1;
        str2 = "월드";

        ChickenMenu menu1 = new ChickenMenu("후라이드", 1000);
        ChickenMenu menu2 = menu1;
        menu1.price = 1200;

 

menu2는 menu1의 인스턴스를 넣었기 때문에 menu1의 price가 바뀌면 menu2의 price도 바뀐다.

인스턴스끼리 참조할 때는 주소값이 참조되니 값을 공통으로 쓴다는 점을 고려해야겠다.

 

 

 

 

원시형과 참조형의 반영 비교

		public static void raisePrice (int avg, ChickenMenu menu, int amount) {
        avg += amount;
        menu.price += amount;
    }
				int avgChickenPrice = 12000;
        ChickenMenu chickenMenu1 = new ChickenMenu("양념치킨", 12000);

        raisePrice(avgChickenPrice, chickenMenu1, 1000);

raisePrice 메서드에서 avgChickenPrice와  chickenMenu1의 price 모두 증가시켰지만,

원시자료형은 값을 복사하고 참조자료형은 주소를 복사하기 때문에,

결국 chickenMenu1의 가격만 증가한 것을 볼 수 있다.

 

 

 

 

 

 

출처 

  • 사이트, 검색명 (날짜)

'얄코의 제대로 파는 자바 > 섹션5 객체지향 프로그래밍' 카테고리의 다른 글

다형성  (0) 2024.03.17
상속  (0) 2024.03.16
접근 제어자  (0) 2024.03.14
클래스(정적) 필드와 메소드  (0) 2024.03.12
클래스 기초  (0) 2024.03.06