사이먼's 코딩노트

[Java] 클래스와 메서드(2) 본문

Java/Java

[Java] 클래스와 메서드(2)

simonpark817 2024. 2. 2. 17:20

[클래스와 메서드 2]

  • 아래는 게임 참여자와 무기라는 클래스를 지정하여 속성을 부여하는 코드이다.
public class Main {
    public static void main(String[] args) {

        Player p1 = new Player();

        p1.name = "홍길동";

        Weapon sword = new Weapon();

        sword.type = "칼";
        sword.damage = 1;

        p1.weapon = sword;

        Weapon bow = new Weapon();

        bow.type = "활";
        bow.damage = 2;

        Player p2 = new Player();
        p2.name = "홍길순";

        p2.weapon = bow;

        System.out.println(p2.weapon.type);
        System.out.println(p2.weapon.damage);

        p1.attack();
        p2.attack();

    }
}

class Player {
    String name;
    Weapon weapon;

    void attack() {
        System.out.println(this.name + "이 " + this.weapon.type +"로 공격합니다.");
    }
}
class Weapon {
    String type;
    int damage;
}
  • Player 라는 클래스를 생성하여 p1 객체 변수를 생성하였고, p1의 이름(name)은 홍길동으로 정의하였다.
  • Weapon 이라는 클래스를 생성하여 sword 객체 변수를 생성하였고, sword의 이름(name)은 칼이고 공격력(damage)는 1로 정의하였다. 
  • 이 때 말하는 객체 변수 즉, 객체를 가르키고 있는 변수를 레퍼런스 변수라고 부른다.
  • 또한 객체 하나하나를 인스턴스라고 부른다.
  • 클래스 영역에서 선언된 변수를 인스턴스 변수라고 한다.
  • Player 타입을 가진 p1에게 칼이라는 무기를 장착하기 위해서는 Player 클래스의 인스턴스 변수로 타입이 Weapon인 weapon 변수를 새로 선언해야한다.
  • 선언 후에 main 메서드에서 p1.weapon = sword 와 같이 작성하면 p1의 인스턴스 변수인 weapon은 Weapon 객체와 연결되었다는 의미이다.
  • 실제로 출력문에서 p1.weapon.type과 p1.weapon.damage를 출력해보면 칼과 1이 출력된다.

 

[매개변수와 인자]

  • 여지껏 봤던 메서드는 모두 메서드명과 함께 () 괄호만 되어있는 모습을 봤다.
  • 메서드는 값을 넘겨받는 매겨변수와 값을 메서드로 넘겨주는 인자가 포함될 수 있다.
  • 아래는 메서드 2개를 main 함수 안에 생성하여 실행시키는 코드이다.
public class Main {
    public static void main(String[] args) {
        System.out.println("== main ==");
        int a = 5;
        funA(a);
        System.out.printf("a : %d\n", a);

        int[] arr = new int[3];
        arr[0] = 10;
        arr[1] = 20;
        arr[2] = 30;
        funB(arr);
        System.out.printf("arr[0] : %d\n", arr[0]);
    }

    static void funA(int n) {
        System.out.println("== funA ==");
        n = 50;
    }

    static void funB(int[] arr) {
        System.out.println("== funB ==");
        arr[0] = 50;
    }
}
  • funA(a)는 a라는 인자값을 funA() 라는 메서드에 a라는 데이터를 넘겨 실행시킨다는 의미이다. 
  • Main 메서드의 a라는 변수는 정수 5라고 선언이 되었고, 매개변수 n을 받는 funA() 라는 메서드에서는 5라는 값을 받아 해당 n 값을 50으로 바꿔주고 메서드 역할이 종료된다.
  • funA() 메서드를 거친 변수 a는 출력문을 통해 5가 아닌 50이 출력되는 것을 확인할 수 있다. 그 이유는 funA()라는 메서드는 단지 5를 50으로 변경만 해주고 다시 Main 메서드로 변경된 값을 넘겨주지 않기 때문이다.
  • 마찬가지로 funB() 메서드도 값을 바꿔주는 메서드이다.
  • funA()와 다른점은 funB()의 인자에는 배열 객체 변수인 arr이 들어간다는 것이다.
  • 이럴 경우는 funB()의 매개변수에서도 인자와 타입이 반드시 같도록 배열 타입으로정의해야 된다는 것이다.
  • 그래서 funB 메서드의 () 안에는 매개변수 int arr이 아닌 배열을 의미하는 int[] arr이 들어간다.
  • funB() 메서드를 거친 변수 arr는 출력문을 통해 값이 10이 아닌 50으로 출력되는 것을 확인할 수 있다. 그 이유는 arr은 객체 변수로서 arr에는 new int[3] 이라는 객체와 연결된 리모콘이 있기 때문에 funB() 메서드를 통해 연결된 객체로 접근하여 값을 변경하였기 때문이다.

 

[static]

  • 지금까지는 클래스 선언과 함께 메서드를 정의하고 main 함수에서 해당 클래스 타입에 맞는 객체를 일일이 만들어 메서드를 호출시켰다.
  • 객체를 일일이 생성하지 않고 각 클래스의 메서드를 바로 호출시키는 방법도 있다.
public class Main {
    public static void main(String[] args) {

        calculator.plus(10, 20);
        calculator.plus(50, 20);
        calculator.minus(50, 20);
        calculator.minus(5, 2);
        calculator.multiply(5, 2);

    }
}

class calculator {
//    void는 return 하지 않겠다라는 의미이고, a+b의 타입에 맞춰 int로 바꿔주면 return이 가능하다.
    static void plus(int a, int b) {
        System.out.println(a + b);
    }
    static void minus(int a, int b) {
        System.out.println(a - b);
    }
    static void multiply(int a, int b) {
        System.out.println(a * b);
    }
}
  • 위 코드는 계산기 기능을 하는 클래스인 calculator 설계도를 작성하고 합, 차, 곱을 구하는 코드이다.
  • 여지껏 학습한 내용에 빗대면 c1과 같은 객체를 calculator c1 = new calculator()와 같이 하나 생성해서 c1.plus(10, 20) 과 같이 합을 구해야했지만, 클래스 안에 메서드를 생성할 때 static를 붙히면 객체 생성없이 바로 메서드를 호출할 수 있다.
  • 각 메서드는 매개변수인 a, b를 가지고 있고 출력문을 통해 합, 차, 곱을 출력한다.
  • main 함수에서는 calculator.plus(10, 20) 과 같이 클래스명과 함께 메서드를 바로 호출하면 해당 메서드가 실행되면서 합을 구하게 된다.

 

[return]

  • 다음은 같은 계산기 기능을 하는 코드이지만 반환 형식을 다르게 한 코드이다.
public class Main {
    public static void main(String[] args) {

        System.out.printf("%d\n", calculator.plus(10, 20));
        System.out.printf("%d\n", calculator.plus(50, 20));
        System.out.printf("%d\n", calculator.minus(50, 20));
        System.out.printf("%d\n", calculator.minus(5, 2));
        System.out.printf("%d\n", calculator.multiply(5, 2));

    }
}

class calculator {
//    void는 return 하지 않겠다라는 의미이고, a+b의 타입에 맞춰 int로 바꿔주면 return이 가능하다.
    static int plus(int a, int b) {
        return a + b;
    }
    static int minus(int a, int b) {
        return a - b;
    }
    static int multiply(int a, int b) {
        return a * b;
    }
}
  • 메서드에 static를 붙혀 main 함수에서 메서드를 바로 호출하는 것은 동일하다.
  • 이번에 다른 점은 main 함수에서 출력문을 사용하여 두 수의 합, 차, 곱을 계산하여 반환한 값을 바로 출력한다.
  • 각 plus, minus, multiply 메서드는 똑같이 매개변수 a, b를 받고 이번에는 return을 사용해서 바로 연산을 한 값을 반환하였다.
  • return을 사용할 때는 메서드에 void를 사용하지 않고 반환되는 해당 값의 타입을 맞춰 써줘야한다.
  • void는 return을 하지 않겠다는 뜻이기 때문에 각 메서드는 static int를 작성하여 반환하는 값이 있고 그 값이 정수라는 것을 단번에 알아차릴 수 있어야 한다.
  • 만약 return에 각 연산이 아닌 정수 값 5와 같이 작성했다면, main 함수에서 실행되는 모든 출력문은 5를 출력할 것이다.
반응형