변수와 메서드

김민성·2022년 7월 14일
0

Java

목록 보기
11/47
post-thumbnail

변수와 메서드

변수의 종류

  1. 인스턴스변수

    멤버변수중 static이 붙지 않은 변수. 클래스의 객체를 생성할 때 메모리에 올라오므로 인스턴스 변수의 값을 읽어오거나 저정하기 위해서는 객체를 먼저 생성해야 한다.

    인스턴스변수의 사용은 참조변수.변수명 으로 사용한다.

  2. 클래스변수

    멤버변수중 static이 붙은 변수. 객체의 생성과 상관없이 메모리에 먼저 올라가기 때문에, 모든 객체가 이를 공유하게 된다. 따라서 한 클래스의 모든 객체들이 공통적인 값을 가져야할 때는 클래스변수로 선언해야한다.

    클래스변수의 사용은 클래스명.변수명 으로 사용한다.

  3. 지역변수

    메서드 내에 선언되어 있는 변수이며, 메서드 내에서만 사용 가능하다.

    public class Main {
    	public static void main(String[] args) {
    	System.out.println(Car.wheel);		// 4
    	
    	Car myCar = new Car();
    	System.out.println(myCar.car);		// "페라리"
    	System.out.println(myCar.price);	// 200000000
    	}
    }
    
    class Car {
    	String car = "페라리";
    	int price = 200000000;
    	static int wheel = 4;
    }

    위의 코드에서 Car 클래스에서 static int wheel = 4 로 wheel 변수를 클래스변수로 선언했기 때문에 Main 클래스에서 객체를 만들지 않고도 Car.wheel 값이 4로 출력이 잘 된다.

    그러나 car과 price 변수는 인스턴스변수로 선언했기 때문에 Car myCar = new Car()'를 통해 myCar이라는 객체를 만들어 줘야 사용할 수 있다. 객체를 생성 한 후 myCar.carmyCar.price가 "페라리"와 200000000 으로 잘 출력이 된다.

메서드

  • 메서드는 특정 작업을 수행하는 문장을 하나로 묶은 것으로 함수와 비슷한 성질을 가지고 있다.

  • 메서드는 반복되는 기능, 처리, 코드등을 쉽게 관리하기 위해, 그리고 코드의 가독성을 위해서 사용한다.

  • 메서드의 구조

    ①리턴타입 ②메서드명(③자료형 매개변수1, 자료형 매개변수2, ...) {

    ​ ④ 호출시 실행할 문장

    ​ ⑤ return 리턴값

    }

    ① return 뒤의 값에 타입에 맞는 자료형을 작성해 준다. 리턴값이 없을 때에는 void로 작성한다.

    ② 메서드명은 이름만으로 기능을 쉽게 알수있는 동사형으로 작성하는 것이 좋다.

    ③ 매개변수는 생략이 가능하다. 그러나 생략시에는 외부(사용하는 곳)에서 값을 전달받을 수 없고, 여러 값을 전달 받아야 할 때는 ','로 구분하여 값의 개수만큼 선언해준다. 사용시에는 매개변수의 타입과 개수에 맞게 순서대로 값을 전달해 주어야 한다.

    ④ 생략이 가능하다. 호출하게 되면 내부로 흐름이 이동되어 안에 있는 문장들을 수행하게 된다.

    ⑤ 생략이 가능하다. 메서드를 사용한 부분 통째로를 뒤에 오는 값으로 덮어씌운다. (예시에서 확인)

    public class Main {
    	public static void main(String[] args) {
    		int result = add(1,4);
            // 메서드의 사용부분인 add(1,4) 통째로를 a+b의 값인 5로 덮어씌운다.
            // 따라서 add(1,4)는 하나의 값이 되어 int타입의 result에 저장할 수 있다.
    		System.out.println(result);
    	}
    	
        // int타입의 매개변수 a와 b를 받아 a+b의 값을 반환하는 메서드
    	public static int add(int a, int b) {	
    		return a+b;			// 사용한 부분 통째로를 a+b라는 값으로 덮어씌운다
    	}
    }

    위의 코드에서는 a+b의 값을 반환하는 메서드를 만들었기 때문에 매개변수로 int 타입의 데이터라면 어떤 것이 와도 괜찮겠지만, 만약 a/b나 a%b의 값을 반환하는 메서드를 만든다고 가정하면 매개변수 b에는 0이 와서는 안될 것이다. 따라서 메서드를 만들 때는 매개변수의 유효성 검사를 해주고 필요시에는 조건문을 이용해 적절히 조치해주어야 한다.

메서드의 매개변수

  • 기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.

    public class Main {
    	public static void main(String[] args) {
    		Data d = new Data();
    		d.x = 10;
    		System.out.println("main() : x = " + d.x);		// main() : x = 10
    		
    		change(d.x);
    		System.out.println("main() : x = " + d.x);		// main() : x = 10
    	}
    	
    	static void change(int x) {
    		x = 1000;
    	}
    }
    
    class Data {
    	int x;
    }

    위의 코드에서 change(d.x); 메서드를 호출해 x에 1000의 값을 할당했는데도 결과를 출력해보면 x = 10의 값이 나오는 이유가 뭘까?

    이는 d.x의 값이 변경된 것이 아니라, change메서드의 매개변수 x의 값이 변경된 것이다. 즉 원본이 아닌 복사본이 변경된 것이라 원본에는 아무 영향을 미치지 못한다.

  • 참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.

    public class Main {
    	public static void main(String[] args) {
    		Data d = new Data();
    		d.x = 10;
    		System.out.println("main() : x = " + d.x);		// main() : x = 10
    		
    		change(d);
    		System.out.println("main() : x = " + d.x);		// main() : x = 1000
    	}
    	
    	static void change(Data d) {
    		d.x = 1000;
    	}
    }
    
    class Data {
    	int x;
    }

    위의 코드는 이전 코드와 다른점이 매개변수를 int타입의 x에서 Data타입의 d로 바꾸었다는것 밖에 없다. 하지만 change메서드를 호출해 d.x에 1000을 할당한 후 결과를 보면 x값이 1000으로 바뀌는 것을 볼 수있다.

    이는 매개변수로 '값이 저장된 주소'를 넘겨주었기 때문이다. 주소가 복사된다 하더라도 그 주소가 참조하고 있는 값은 같기 때문에 원본이나 복사본 둘 다 같은 객체를 가리키게 된다. 따라서 매개변수 d로 x의 값을 읽고 변경할 수 있는 것이다.

참조형 반환타입

  • 매개변수뿐만 아니라 반환타입도 참조형이 될 수 있다.

    public class Main {
    	public static void main(String[] args) {
    		Data d = new Data();
    		d.x = 10;
    		
    		Data d2 = copy(d);
    		System.out.println(d.x);		// 10
    		System.out.println(d2.x);		// 10
    
    	}
    	
    	static Data copy(Data d) {
    		Data tmp = new Data();
    		tmp.x = d.x;
    		
    		return tmp;
    	}
    }
    
    class Data {
    	int x;
    }

    위의 코드에서 copy 메서드 내부를 보면 Data 타입의 tmp객체를 생성하고 tmp.x에 매개변수로 넘겨준 d.x를 대입하고 리턴했다.

    따라서 main 메서드에서 Data 타입의 d2에 copy(d)라는 값을 할당해줘서 d2.x를 출력할 수 있는 것이다.

클래스 메서드와 인스턴스 메서드

  • 변수와 마찬가지로 메서드도 static이 붙어 있으면 클래스 메서드라고 하고 붙어있지 않으면 인스턴스 메서드라고 한다.

    • 인스턴스 메서드 : 인스턴스 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드이다.
    • 클래스 메서드(static 메서드) : 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드를 클래스 메서드로 정의한다. 필수는 아니지만 인스턴스와 관련이 없으면 클래스 메서드로 정의해주는게 메서드 호출시간이 짧아지므로 일반적으로 클래스 메서드로 정의한다.
    public class Main {
    	public static void main(String[] args) {
    		int add2Result = MathTest.add2(3,4);
    		System.out.println(add2Result);				// 7
    		
    		MathTest mt = new MathTest();
    		mt.a = 5;
    		mt.b = 6;
    		int add1Result = mt.add1();
    		System.out.println(add1Result);				// 11
    	}
    }
    
    class MathTest{
    	int a, b;
    	
    	int add1() {
    		return a+b;
    	}
    	
    	static int add2(int x, int y) {
    		return x + y;
    	}
    }

    위의 코드에서 먼저 MathTest 클래스를 보자. 여기엔 인스턴스변수 a, b와 인스턴스 메서드 add1, 클래스메서드 add2가 선언되어 있다.

    여기서 add1을 연산할 때는 인스턴스 변수 a와 b로만 가능하기 때문에 매개변수를 넘겨주지 않았고, 인스턴스 변수를 사용해 연산하기 때문에 static을 붙이지 않은 인스턴스 메서드로 선언했다. 따라서 main 메서드에서 add1 메서드를 사용하려면 먼저 객체를 생성해주고 a와 b에 값을 할당해준 후 호출해야 할 것이다.

    add2 메서드는 넘겨준 x와 y 매개변수로만 연산하기 때문에 static을 붙여서 클래스 메서드로 선언했다. 따라서 main 메서드에서 add2 메서드를 사용할 때는 객체의 생성 없이 매개변수만 넘겨주면 된다.

  • 따라서 클래스 멤버(변수, 메서드)와 인스턴스 멤버간의 참조와 호출을 할 때에는 멤버의 생성 시기를 잘 이해하고 사용해야 할 것이다.

0개의 댓글