https://jinnnkcoding.tistory.com/32
스코프(Scope)
스코프(scope)란, 변수의 활동 영역
이러한 스코프는 크게 두 종류로, 클래스 스코프와 메소드 스코프로 나누어짐
클래스 스코프 : 클래스 전역에서 활동(예: 필드)
메소드 스코프 : 메소드 내부에서 활동(예: 파라미터, 지역변수)
클래스 스코프(Class Scope)
필드(변수)의 활동 영역은 클래스 전체 (클래스 전역)
따라서 메소드 호출 시 필드를 사용할 수 있음
클래스 스코프 예시
class Cat {
// 필드(상태) 영역
String name;
// 메소드(동작) 영역
// 필드값인 name의 활동영역은 클래스 전체, 즉 클래스 스코프를 갖는다.
void meow() {
System.out.printf("%s의 야옹\n", name);
}
void claw() {
System.out.printf("%s의 할퀴기 공격\n", name);
}
}
public class CatTest {
public static void main(String[] args) {
// 두 고양이 객체 생성
Cat cat1 = new Cat();
Cat cat2 = new Cat();
// 객체 필드 초기화
cat1.name = "네로";
cat2.name = "나비";
// 두 고양이의 야옹
cat1.meow();
cat2.meow();
// 두 고양이의 할퀴기
cat1.claw();
cat2.claw();
}
}
결과
네로의 야옹
나비의 야옹
네로의 할퀴기 공격
나비의 할퀴기 공격
메소드 스코프(Method Scope)
파라미터와 지역변수의 경우, 메소드 스코프를 가짐
이들의 활동 영역은 해당 메소드 내부로 제한됨
(※ 지역변수 : 메소드 내부에서 선언된 변수)
class DrinkMachine {
String output;
void pushButton(int num) { // int num은 파라미터
String[] drinks = {"콜라", "사이다", "환타"}; // drinks은 지역변수
output = drinks[num]; // output은 필드
}
void printOutput() {
System.out.println(output);
}
}
num은 pushButton 메소드의 파라미터이고,
drinks는 pushButton 메소드 내부에서 선언되었으므로 지역변수이다
이들은 해당 메소드를 벗어나서 호출하면 에러가 생긴다.
이렇게 빨간 밑줄이 생김
메소드 스코프 예시02) 변수의 이름이 같은 경우
class Whatever {
public void cool(int score) {
String result = "";
}
public void great(int score) { // cool 메소드의 파라미터 이름과 동일
String result = ""; // cool 메소드의 지역변수 이름과 동일
}
두 메소드의 파라미터 이름과 지역변수 이름이 동일해도(=변수 이름이 동일해도)
에러는 생기지 않는다!
각기 다른 변수로 인식하고 컴파일하는 데에는 아무런 문제가 없다.
package Exam;
public class MethodScope {
public static void main(String[] args) {
int score = 88;
// main메소드의 score를 출력
System.out.printf("score = %d in main()\n", score);
// Record 클래스의 메소드 호출, 수행
Record.minusTen(score);
// main 메소드의 지역변수 score를 출력
System.out.printf("score = %d in main()\n", score);
}
}
class Record {
static void minusTen(int score) {
// minusTen 메소드의 파라미터 score의 값을 10 감소
score-=10;
// minusTen 메소드의 파라미터 score의 값을 출력
System.out.printf("score : %d in minusTen()\n", score);
}
}
결과
score = 88 in main()
score : 78 in minusTen()
score = 88 in main()
메인 메소드에서 minusTen 메소드를 호출하고 난 후인데도 그 다음 출력문에는 본래값인 88이 출력되었다.
즉, 메인메소드의 지역변수 값과, minusTen메소드의 파라미터 값을 구별하고 있음을 알 수 있다.
스코프와 this
위에서 지역변수와 파라미터 이름이 같은 경우는 문제가 생기지 않는다는 걸 확인했다.
다만, 클래스의 필드와 메소드의 파라미터 이름이 같은 경우 문제가 생길 수 있다.
public class exCookie {
public static void main(String[] args) {
Cookie cookie = new Cookie("버터링", 1500);
}
}
class Cookie {
// 필드 영역
private String name;
private int price;
// 메소드 영역
public Cookie(String name, int price) {
name = name; // 인스턴스 변수 name 초기화 되지 않음
price = price; // 인스턴스 변수 price 초기화 되지 않음
System.out.printf("%s, %d원", name, price);
}
}
이클립스에서 위 코드를 적어보면
이렇게 노란색 밑줄(=경고)가 뜨면서 커서를 대면
이렇게 변수를 쓰는 건 효과가 없다. 고 친절히 알려준다
뭐 결과는..
버터링, 1500원
잘 떴지만 말이다.
아무튼 비추천
this()
파라미터와 필드의 이름이 같은 경우 위와 같은 문제를 해결할 때, this 키워드를 사용하면 된다.
this 키워드는 메소드 수행의 주체 객체를 가리킨다.
package Exam;
public class exCookie {
public static void main(String[] args) {
Cookie cookie = new Cookie("버터링", 1500);
}
}
class Cookie {
// 필드 영역
private String name;
private int price;
// 생성자 메소드
public Cookie(String name, int price) {
this.name = name; // this.name => 인스턴스 변수
this.price = price; // this.price => 인스턴스 변수
// 파라미터 네임을 this로 던짐
}
}
주체객체의 파라미터값을 this로 던짐
=> 버터링 -> this.name으로 던짐
=> 1500 -> this.price로 던짐
버터링, 1500원
this 예제문제 02
커피 객체를 생성하고 그 가격을 인상하려 한다.
this를 활용하여 문제를 풀어보자
package Exam;
public class CoffeePrice {
public static void main(String[] args) {
// 커피 객체 생성
Coffee americano = new Coffee("아메리카노",1500);
System.out.printf("커피값 인상 전 => %s\n", americano.toString());
// 커피값 인상
// setter로 값을 우회하여 변경
americano.setPrice(2000);
System.out.printf("커피값 인상 후 => %s\n", americano.toString());
}
}
class Coffee {
private String name;
private int price;
// 생성자
public Coffee(String name, int price) {
this.name=name;
this.price=price;
}
// Setter 생성 (=>값을 우회하여 변경)
public void setPrice(int price) {
this.price = price; // 파라미터 값을 대입하겠다.
}
public String toString() {
return String.format("Coffee [name : %s, price :%,d]",
this.name, this.price);
}
}
결과
커피값 인상 전 => Coffee [name : 아메리카노, price :1,500]
커피값 인상 후 => Coffee [name : 아메리카노, price :2,000]
'Back-End > Java' 카테고리의 다른 글
[JAVA] 다양한 형태의 클래스 선언 방법과 중첩클래스(inner class) (0) | 2021.09.17 |
---|---|
[Java] Object 클래스 (0) | 2021.09.16 |
[Java] 캡슐화(Encapsulation)_getter와 setter (0) | 2021.08.26 |
(스크랩) [Java] Public class 와 class의 차이 (0) | 2021.08.25 |
[Java] 객체 배열 (0) | 2021.08.23 |
댓글