JAVA

23-01-16 수업내용 정리

모건이삼촌 2023. 1. 16. 22:51

2023-01-16 09:30 ~ 18:30 수업진행

 

※ 수업내용

 

★ 과제 풀이

 

과제풀이는 추후 다른 게시판에 게시하겠다.

 

4. 필드

필드는 객체의 고유한 속성이나 상태값을 저장하는 곳이다.

필드는 클래스 중괄호 블록안에 어디서든 선언될 수 있으며, 필드를 선언하는 방법은 변수의 선언 방법과 동일하다.

초기값 역시 선언 시 넣어줄 수도 있고, 생략할 수도 있다.

필드는 멤버 변수라고도 부르며, 멤버 변수는 클래스 변수와 인스턴스 변수로 나눌 수 있다.

변수는 세가지로 분류 할수 있는데, 클래스변수, 인스턴스 변수, 지역변수로 나눠진다.

아래 표를 참고하자.

클래스변수 (class variable)는 클래스 블록 내의 영역에서 선언되며 선언 방법은 변수의 자료형 앞에 static이라는 키워드를 붙이면 된다.

클래스 변수는 모든 객체가 공유되는 변수이다.

객체를 생성하지 않아도 바로 사용할 수 있다.

사용방법은 클래스명.클래스변수명 형태로 사용한다.

 

인스턴스 변수(instance variable)도 클래스 변수와 같이 클래스 블록 내의 영역에 선언되지만, static키워드는 붙지않는다.

일반적인 변수 선언 방법으로 선언하면 된다.

인스턴스 변수는 객체를 생성할 때 생성되며, 객체는 서로 독립적이기 때문에 이 인스턴스 변수 역시 객체마다 독립적인 값을 갖는다.

사용방법은 객체명.인스턴스변수명 형태로 사용된다.

아래 예제를 살펴보자.

package chapter7;

public class VarEx {
	
	public static void main(String[] args) {
		
		// 클래스 변수 사용
		System.out.println("Avante 제조사 : " +Avante.company); // 아반떼 클래스의 클래스변수 이므로 인스턴스생성이 없어도됨
		
		Avante a1 = new Avante();
		Avante a2 = new Avante();
		
		//인스턴스 변수의 값 변경
		a1.color = "화이트";
		a2.color = "블랙";
		
		//인스턴스 변수 출력
		System.out.println("a1 색상 : "+a1.color);
		System.out.println("a2 색상 : "+a2.color);
		
		// 클래스 변수를 인스턴스 객체로 출력
		System.out.println("a1 제조사 : " +Avante.company);
		System.out.println("a2 제조사 : " +a2.company);
		
		// 클래스 변수의 값 변경
		a1.company = "기아";
		
		// 클래스 변수의 값 변경 후 클래스 변수와 인스턴스변수 출력
		System.out.println("Avante 제조사 : "+ Avante.company);
		System.out.println("a1 제조사 : "+ a1.company);
		System.out.println("a2 제조사 : "+ a2.company);
		
		
	}

}

 class Avante {
	 
	 String color; //인스턴스 변수
	 static String company = "현대"; // 클래스 변수
	 
	 
 }

실행 결과

예제를 작성하는 순서는 위 예제 하단부에 있는 class Avante를 먼저 작성하고 class Var를 작성해야한다.

컴파일 전에는 VarEx.java로 하나의 파일에 모두 저장되어있지만, 컴파일 과정에서 VarEx.class와 Avante.class로 나눠진다.

인스턴스 변수(static이 없는)는 객체마다 독립적인 값을 갖고, 클래스변수(static이 있는)는 모든 객체들이 공유되는 변수이다. 또한 클래스 변수는 객체생성 없이도 클래스명 만으로 사용할 수 있지만, 인스턴스 변수는 반드시 객체를 먼저 생성하고 객체를 통해 사용해야만 한다. 그렇지 않으면 에러가 나게 된다.

 

지역변수와 함께 변수의 범위(scope)에 대해 알아보자.

변수를 사용할 수 있는 범위가 정해저 있는데,  예제를 보자

package chapter7;

public class LocalValEx {
	
	public static void main(String[] args) {
		
		Local local = new Local();
		System.out.println(local.name); // null
		
		local.process();
		System.out.println(local.name); // 홍길동
		
		local.printAge1();
		local.printAge2();
		local.printAge();
		
		
		// for문 블록 내에서의 변수 선언
		for(int i=0; i<10; i++) {
			int temp = 0;
			temp +=i;
		}
//		System.out.println(temp); // 에러
	}

}



class Local {
	//인스턴스 변수를 쓰기 위해서 인스턴스 변수가 필요함 
	String name;
	int age; 
	
	void process() {
		name = "홍길동";
		
	}
	void printAge() {
		int age = 10; // 동일한 블록 안에 같은 이름의 변수가 선언되면 상위 메서드에서 선언된 변수를 찾아가 출력한다?
		System.out.println(age);
		
	}
	void printAge1() {
		int age = 20; // 메서드 내부에 선언되있기 때문에 age는 지역변수이다.
		System.out.println(age);
		
	}
	void printAge2() {
		int age = 30; // 메서드 내부에 선언되있기 때문에 age는 지역변수이다.
		System.out.println(age);
	}
	
	
}

실행 결과

Local local = new Local();
System.out.println(local.name); // null

Local 객체를 생성하고 name 인스턴스 변수를 출력했다.

이 변수는 아직 초기화 되지 않았기 때문에 기본값인 null이 출력되는 것이다.

 

아래 local.process(); 메서드가 실행되는데, Local클래스의 process()메서드를 보면 name 변수에 홍길동 문자열읠 대입하고 있다. 이 인스턴스 변수는 클래스 블록에 있기 때문에 사용 범위(scope)는 클래스 전체가 된다. 그래서 process()메서드가 실행되고 나서 name 인스턴스 변수를 출력하면 홍길동 이라고 출력된다.

아래

local.printAge1();
local.printAge2();
local.printAge();

도 위와 같이 출력된다고 보면 된다.

 

지역변수의 사용 가능한 범위를 쉽게 구분 지을 수 있는 방법은 범위(scope)는 중괄호 블록으로 구분지으면 쉽게 이해할 수 있다. 선언된 중괄호 안에서는 모두 사용 될 수 있다.

Local 클래스의 인스턴스 변수는 지역변수가 아니라, 전역변수 이다. 

메서드 안에 선언된 변수는 아니지만, 클래스 블록(중괄호) 안에 선언 되었기 때문에 클래스 중괄호 안에서는 모두 사용 될 수 있다.

 

5. 메서드

메서드는 클래스 멤버 중 기능에 해당하는 중괄호 블록이다.

이 블록은 이름을 가지고 있으며, 이 이름을 통해 메서드를 실행하게 되면 중괄호 블록에 있는 실행문들이 실행되게 된다.

쉽게 말해서 코드의 모음집 이라고 보면 된다.

 

 1) 메서드의 구조

메서드의 구조

메서드는 선언부와 실행부로 나눠지는데, 선언부에는 접근제한자, 리턴타입, 메서드명, 매개변수가 정의되고, 중괄호로 블록의 영역을 구분한다. 중괄호가 끝나는 부분까지가 해당 메서드의 영역이 되는것이다.

 

 2) 접근제한자

접근을 제한하는 키워드가 들어오는 자리다.

특정 키워드에 따라 이 메서드를 실행할 수 있는 권한을 제한할 수 있다.

 

 3) 리턴타입

메서드의 선언부 앞쪽에 리턴타입이 오는데, 리턴타입이란 리턴되는 타입이다. 리턴은 돌려준다라는 의미로 돌려주는 데이터 타입이 된다.

특정 기능을 실행한 후 어떤 값을 실행한 곳으로 돌려줄수 있는데, 이 돌려주는 값의 테이터 타입(자료형)을 이곳에 정의한다.

돌려주는 값을 리턴값이라고 하는데, 메서드는 리턴값이 있을 수도 있고 없을 수도 있다. 

만약 리턴값이 없다면 void라고 적어줘야 한다.

지금까지 예제로 만들었던 main() 메서드도 리턴값이 없기 때문에 리턴타입이 void로 정의한 것이다.

만약 리턴값이 정수라면 int, 문자열이라면 String이라고 적어줘야 한다.

반대로 메서드 선언부에 String 이라고 적었다면 메서드 중괄호 블록 내에서 반드시 String을 리턴값으로 정의해야한다.

 

 4) 메서드명 작성 규칙

메서드명도 변수명 작성 규칙과 같다.

1. 숫자로 시작하면 안됨

2. 특수기호는 $와 _만 사용 가능

3. camel 표기법으로 작성

4. 변수와 마찬가지로 영어로 작성하면 됨.

5. 의미를 부여하자

 

 5) 매개 변수

매개라는 말처럼 한쪽과 한쪽을 연결해주는 역할을 하는데, 메서드 블록안쪽과 메서드가 실행되는 곳을 변수로 연결해준다. 메서드 입장에서 외부로부터 변수를 입력받기위해 사용된다

예를들면 두 수의 합계를 리턴해주는 메서드라면 두 개의 수를 매개변수로 입력받아야 한다.

두 수를 합계로 구하는 메서드는 매개변수의 개수가 2개로 이미 정해져 있지만, 간혹 매개변수가 몇개가 올지 알 수 없는 경우가 있다. 두 수가 아닌 여러수의 합을 구하는 메서드라면 2개가 올수도, 10개가 올수도 있는 것이다.

이럴때 첫번째 방법은 매개변수를 배열로 선언하는 방법이고, 두번째는 매개변수를 선언할 때 타입과 변수명 사이에 ...을 추가하고 선언하는 것이다 (... = 가변인자)

아래 예제를 보자.

package chapter7;

public class ParamEx {
	
	public static void main(String[] args) { // 호출부
		
		Param p = new Param();
		p.add(10, 5); // 10과 5는 아규먼트이고 파라미터 안 add x, y값에 보낸다.
		p.add2(10, 5);
		p.add3(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
		int[] arr = {1, 2, 3};
		p.add3(arr);
		p.add4(arr);
		
	}

}

class Param { // 선언부
	void add(int x, int y) {// 파라미터 // x = 매개변수 // 매개변수와 지역변수는 같은 의미로 쓰임
		int z = x + y;
		System.out.println(z);
//		return; // 호출한 실행포인트쪽으로 되돌린다. // 생략가능
	}
	void add2(double x, double y) {
		double z = x + y;
		System.out.println(z);
	}
	
	void add3(int ...x) { // 선언당시에는 인트의 인자를 모르기 때문에 우선 선언부터 한다. , 가변인자 // 배열을 넣어도 가변인자에서 반응을 한다.
		int sum = 0;
		for(int i = 0; i<x.length; i++) {
			sum += x[i];
		}
		System.out.println(sum);
	}
	void add4(int[] x) { 
		int sum = 0;
		for(int i = 0; i<x.length; i++) {
			sum += x[i];
		}
		System.out.println(sum);
	}
}

실행 결과

 

 

 

 6) 리턴값

메서드를 선언할 때 선언부에 리턴타입을 지정해둔 경우 반드시 리턴값을 지정해야 한다.

반대로 선언부에 리턴타입을 void라고 선언한 경우는 리턴값을 지정할 수 없다.

따라서 메서드는 리턴값이 있을 수도, 없을 수도 있다.

키워드는 return을 사용하는데 return문의 용도는 두가지로 기억하자.

  가. 값을 가지고 돌아가는 경우.

  나. 그냥 돌아가는 경우

return은 돌아간다는 의미로, 해당 메서드를 실행한 곳으로 돌아가는데, return 뒤에 값이 있으면 값을 가지고 돌아가고, 없으면 그냥 돌아가게 된다. 그래서 return문을 메서드의 실행을 중지하는 용도로도 사용한다.

아래 예제를 보자.

package chapter7;

public class ReturnEx2 {
	
	public static void main(String[] args) {
		
		Return2 obj = new Return2();
		
		obj.getTest(0);
		obj.getTest(1);
		
		System.out.println(obj.getName(0)); // 홍길동
		System.out.println(obj.getName(1)); // ""
		
		
		
		
	}
	

}


class Return2 {
	
	void getTest(int type) {
		System.out.println("getTest() 메서드 시작");
		
		if (type==1) {
			return;
		}
		System.out.println("getTest() 메서드 끝");
		//return 생략됨
		
	}
	String getName(int type) {
		if (type==1) {
			return "12";
		}
		return "홍길동";
	}
}

실행 결과

위의 예제는 ReturnEx2 클래스에서 Return2 객체를 생성해서 메서드를 호출하는 예제이다.

System.out.println("getTest() 메서드 시작");

		System.out.println("getTest() 메서드 시작");
		
		if (type==1) {
			return;
		}
		System.out.println("getTest() 메서드 끝");
		//return 생략됨
		
	}

class Return2 에서 위의 코드 getTest() 메서드는 리턴타입이 void이고, 매개변수 type을 입력받아 type이 1이면 그냥 return문만 있다. 이 경우 "getTest() 메서드 끝"을 출력하는 실행문이 실행되지 않는다. 리턴값이 없어서 return문 뒤에 아무 값도 없지만, 메서드가 종료되는 것이다.아래 getName()메서드도 마찬가지다. type이 1이면 "12" 문자열을 리턴하고메서드는 종료된다.

type이 1이 아니라면 "홍길동"이 리턴된다. 그럼 if문 없이 return문을 여러개 쓰면서 중단 시킬 수 있을까?

물론 되지 않는다. return문은 두개 이상 존재할 수 없다. 이 전 예제는 if문을 통해 특정 조건에만 return문을 만나게 되므로, 무조건 하나의 return문만 실행된다. 

 

리턴을 끝으로 23-01-16 수업내용 정리를 마치겠다.

'JAVA' 카테고리의 다른 글

23-01-18 수업내용 정리  (0) 2023.01.18
23-01-17 수업내용 정리  (0) 2023.01.18
23-01-12 수업내용 정리  (0) 2023.01.15
23-01-13 수업내용 정리  (0) 2023.01.15
23-01-11 수업내용 정리  (0) 2023.01.13