어리바리 신입 개발자의 얼렁뚱땅 개발 기록 ✨
23.03.14 / 하나의 패키지 서로 다른 클래스 (메서드를 통해 접근) 본문
데이터 영역의 필드(전역변수)에 바로 접근할 수 없는 경우 필드 마다 셋팅하는 메서드와 겟팅하는 메서드를 선언해서 셋팅하는 메서드를 호출하면 셋팅하고 겟팅하는 메서드를 호출하면 겟팅하도록 한다.
[언제 필드에 접근이 불가능 할까?]
필드의 접근지정자를 public 대신 private를 사용할 경우 같은 클래스를 통해서 생성된 객체 내에서만 접근 가능
즉, 다른 클래스에서 생성된 객체에서는 접근이 불가능하다.
- 접근지정(제어)자(access modifier) 종류
public (전체 접근 가능)
protected (같은패키지)
default (없는 상태)
private (같은 클래스)
객체 참조 변수의 주소를 불러오는 코드를 작성했을 때 (u01.)
오른쪽에 User 클래스의 전역변수가 뜨면 사용 가능한 상태(public)
뜨지 않으면 사용 불가능 상태 (private)
package kr.or.ksmart.a;
public class User {
private String uid;
private String upw;
String uphone;
private char ugender;
private int uage;
private String ulevel;
}
[ 그렇다면
Main 클래스에서 생성된 객체가 /
User 클래스를 통해 생성된 객체 내에 있는 필드에 접근하는 방법은?]
User 클래스를 통해 생성된 setUid메서드와 getUid메서드에서는 접근 가능
(User클래스 데이터 영역의 전역변수와 setUid 메서드와 getUid 메서드는 같은 클래스 내에서 생성된 객체이기 때문)
그래서 public으로 setUid 메서드와 getUid 메서드를 모든 클래스에서 접근 가능하게 선언해서 대신 접근한다.
모든 클래스에서 접근 가능한 public의 setUid 메서드에 접근해서 uid 매개변수에 값을 셋팅해주면 setUid 메서드 내에서 매개변수에 담긴 값이 같은 클래스 내에서 생성된 객체만 접근 가능한 전역변수 uid에 셋팅된다. (User 클래스 내에 있는 데이터 영역의 전역변수와 같은 것)
그리고 모든 클래스에서 접근 가능한 public의 getUid 메서드를 호출하면 같은 클래스 내에서 생성된 객체만 접근 가능한 전역변수 uid를 같은 클래스 내에서 생성된 getUid 메서드에 값을 불러와 호출한 위치로 리턴한다.
그 값은 이제 public에 담긴 것이기 때문에 다른 클래스인 Main 클래스에서도 접근 가능하다.
package kr.or.ksmart.a;
public class User {
//data 영역
private String uid; //private : 클래스 통해서 생성된 객체 내에서만 접근 가능
private String upw;
private String uphone;
private char ugender;
private int uage;
private String ulevel;
//method 영역
public void setUid(String uid) {
System.out.println(uid + "<- a setUid User.java");
this.uid = uid ; // 셋팅 코드
}
public String getUid() {
return uid;
}
}
package kr.or.ksmart.a;
public class Main {
//실행은(Ctrl+F11) main 메서드 포함 된 클래스에서 한다.
public static void main(String[] args) {
// User라는 클래스 타입
User u01 = new User();
System.out.println(u01+"< - u01");
u01.setUid("id001");
System.out.println(u01.getUid()+ "<- u01.getUid()");
}
}
[ 셋팅 코드와 지역변수 전역변수]
1. 셋팅이 안 됨 - 뭐가 빠졌을 까? - 셋팅 코드 ( uid = uid ;)
다른 클래스에서 setUid 메서드에 대신 셋팅한 값을 같은 클래스의 전역 변수에 셋팅해줘야 한다.
public void setUid(String uid) {
System.out.println(uid + "<- a setUid User.java");
}
2. 셋팅 코드를 추가해서 셋팅은 됐는데 겟팅이 안됨 - 전역변수의 지역변수화
public void setUid(String uid) {
System.out.println(uid + "<- a setUid User.java");
uid = uid ;
}
중괄호 안에 있는 uid는 지역변수 (원래는 가장 왼쪽에 있는 uid는 전역변수다.)
그런데 전역변수(필드) 이름과 지역변수(매개변수 포함) 이름이 같으면 메서드 내에서는 지역변수로 처리 된다.
(값을 셋팅해야하는 uid 전역변수 까지 지역변수가 됨)
지역변수는 처리 후 휘발되기 때문에 값을 셋팅해야하는 uid (전역변수였어야 할)지역변수에 값이 저장 되지 않음.
(담기기는 하지만 휘발돼서 계속 담겨있지 않다.)
해결 방법 ?
지역변수 이름을 바꿔도 되지만 전역변수 지역변수 이름이 같은 때 구분 필요 - 전역변수 앞에 this. 를 붙여준다.
this. 의 뜻 : 유저클래스를 통해 생성된 객체이다.
public void setUid(String uid) {
System.out.println(uid+ "<- uid setUid User.java");
this.uid = uid;
}
public String getUid() {
return uid;
}
[ 자동으로 셋팅 겟팅 메서드를 선언하는 방법]
데이터 영역 드래그 - 오른쪽 마우스 - source - generate getters and setters
package kr.or.ksmart.a;
public class Main {
public static void main(String[] args) {
User u01 = new User();
User u02 = new User();
//id001 pw001 010-0001 남 20 구매자
u01.setUid("id001");
u01.setUpw("pw001");
u01.setUphone("010-0001");
u01.setUgender('남');
u01.setUage(20);
u01.setUlevel("구매자");
uPrint(u01);
//id002 pw002 010-0002 여 30 판매자
u02.setUid("id002");
u02.setUpw("pw002");
u02.setUphone("010-0002");
u02.setUgender('여');
u02.setUage(30);
u02.setUlevel("판매자");
uPrint(u02);
Goods g01 = new Goods();
//p001 id002 노트북 2000000 1000000 SW개발용
g01.setPcode("p001");
g01.setUid(u02.getUid());
g01.setPname("노트북");
g01.setPjungsang(2000000);
g01.setPhalin(1000000);
g01.setPsangse("SW개발용");
gPrint(g01);
Order o01 = new Order();
//o001 p001 id001 3 2000000 6000000 금암동
o01.setOcode("o001");
o01.setPcode(g01.getPcode());
o01.setUid(u02.getUid());
o01.setOcount(3);
o01.setOprice(2000000);
o01.setOtotal(o01.getOcount() * o01.getOprice());
o01.setOaddress("금암동");
oPrint(o01);
}
public static void oPrint(Order geto) {
System.out.println("--- 주문 출력 시작 ---");
System.out.println("주문코드 : "+geto.getOcode());
System.out.println("상품코드 : "+geto.getPcode());
System.out.println("구매자아이디 : "+geto.getUid());
System.out.println("주문수량 : "+geto.getOcount());
System.out.println("주문단가 : "+geto.getOprice());
System.out.println("주문합계 : "+geto.getOtotal());
System.out.println("배송주소 : "+geto.getOaddress());
System.out.println("--- 주문 출력 끝 ---");
}
public static void gPrint(Goods getg) {
System.out.println("--- 상품 출력 시작 ---");
System.out.println("상품코드 : "+getg.getPcode());
System.out.println("판매자아이디 : "+getg.getUid());
System.out.println("상품이름 : "+getg.getPname());
System.out.println("정상가격 : "+getg.getPjungsang());
System.out.println("할인가격 : "+getg.getPhalin());
System.out.println("상세설명 : "+getg.getPsangse());
System.out.println("--- 상품 출력 끝 ---");
}
public static void uPrint(User getu) {
System.out.println("--- 회원 출력 시작 ---");
System.out.println("아이디 : "+getu.getUid());
System.out.println("비번 : "+getu.getUpw());
System.out.println("휴대폰 : "+getu.getUphone());
System.out.println("성별 : "+getu.getUgender());
System.out.println("나이 : "+getu.getUage());
System.out.println("권한 : "+getu.getUlevel());
System.out.println("--- 회원 출력 끝 ---");
}
}
[ 왜 변수를 선언해서 바로 출력하지 않고 굳이 getUid를 호출하는 메서드를 선언하고 호출하는걸까? ]
- String result = u01.getUid ;
system.out.println(result) ; - 변수를 선언해서 값을 리턴 받을수도 있다.
하지만 이렇게 하면 객체 참조 변수 u01이 바뀔때 마다 일일이 바꿔줘야 하고
객체 참조 변수를 여러 개 사용할때 객체 참조 변수 마다 코드를 입력해줘야 한다.
메서드를 이용하면 한 번 선언하고 호출 값만 바꿔주면 된다.
package kr.or.ksmart.a;
public class User {
//data 영역
private String uid; //private : 클래스 통해서 생성된 객체 내에서만 접근 가능
private String upw;
private String uphone;
private char ugender;
private int uage;
private String ulevel;
public String getUid() {
return uid;
}
public void setUid(String uid) {
System.out.println(uid+ "<- uid setUid User.java");
this.uid = uid;
}
public String getUpw() {
return upw;
}
public void setUpw(String upw) {
System.out.println(upw+ "<- upw setUid User.java");
this.upw = upw;
}
public String getUphone() {
return uphone;
}
public void setUphone(String uphone) {
System.out.println(uphone+ "<- uphone setUid User.java");
this.uphone = uphone;
}
public char getUgender() {
return ugender;
}
public void setUgender(char ugender) {
System.out.println(ugender+ "<- ugender setUid User.java");
this.ugender = ugender;
}
public int getUage() {
return uage;
}
public void setUage(int uage) {
System.out.println(uage+ "<- uage setUid User.java");
this.uage = uage;
}
public String getUlevel() {
return ulevel;
}
public void setUlevel(String ulevel) {
System.out.println(ulevel+ "<- ulevel setUid User.java");
this.ulevel = ulevel;
}
}
[ 다른 클래스1에서 다른 클래스2에 선언된 객체를 호출하고 그걸 다시 다른 클래스3(Main 클래스)에서 호출하기 ]
/* 문제)
* Main 클래스와 If 클래스에서만 작성한다.
*
* IF 클래스에서 작성할 것
* 권한이 판매자라면 - > 상품 등록하고 판매 권한 있음 출력 / TotalPrint 클래스 내 상품출력 메서드를 호출해서 콘솔창에 출력
* 아니면 -> 판매자 권한이 없어요. 상품 등록 불가! 출력
* 리턴 없고 입력있는 메서드 선언
*
* Main 클래스에 작성할 것
* 힌트 없음 알아서 생각해보기
*/
package kr.or.ksmart.a;
public class Main {
//실행은(Ctrl+F11) main 메서드 포함 된 클래스에서 한다.
public static void main(String[] args) {
// User라는 클래스 타입
User u01 = new User();
User u02 = new User();
TotalPrint tp01 = new TotalPrint();
If b2 = new If();
//id001 pw001 010-0001 남 20 구매자
u01.setUid("id001");
u01.setUpw("pw001");
u01.setUphone("010-0001");
u01.setUgender('남');
u01.setUage(20);
u01.setUlevel("구매자");
tp01.uPrint(u01);
b2.levelCheck(u01);
//id002 pw002 010-0002 여 30 판매자
u02.setUid("id002");
u02.setUpw("pw002");
u02.setUphone("010-0002");
u02.setUgender('여');
u02.setUage(30);
u02.setUlevel("판매자");
tp01.uPrint(u02);
b2.levelCheck(u02);
Goods g01 = new Goods();
//p001 id002 노트북 2000000 1000000 SW개발용
g01.setPcode("p001");
g01.setUid(u02.getUid());
g01.setPname("노트북");
g01.setPjungsang(2000000);
g01.setPhalin(1000000);
g01.setPsangse("SW개발용");
tp01.gPrint(g01);
}
}
package kr.or.ksmart.a;
public class TotalPrint {
public void oPrint(Order geto) {
System.out.println("--- 주문 출력 시작 ---");
System.out.println("주문코드 : "+geto.getOcode());
System.out.println("상품코드 : "+geto.getPcode());
System.out.println("구매자아이디 : "+geto.getUid());
System.out.println("주문수량 : "+geto.getOcount());
System.out.println("주문단가 : "+geto.getOprice());
System.out.println("주문합계 : "+geto.getOtotal());
System.out.println("배송주소 : "+geto.getOaddress());
System.out.println("--- 주문 출력 끝 ---");
}
public void gPrint(Goods getg) {
System.out.println("--- 상품 출력 시작 ---");
System.out.println("상품코드 : "+getg.getPcode());
System.out.println("판매자아이디 : "+getg.getUid());
System.out.println("상품이름 : "+getg.getPname());
System.out.println("정상가격 : "+getg.getPjungsang());
System.out.println("할인가격 : "+getg.getPhalin());
System.out.println("상세설명 : "+getg.getPsangse());
System.out.println("--- 상품 출력 끝 ---");
}
public void uPrint(User getu) {
System.out.println("--- 회원 출력 시작 ---");
System.out.println("아이디 : "+getu.getUid());
System.out.println("비번 : "+getu.getUpw());
System.out.println("휴대폰 : "+getu.getUphone());
System.out.println("성별 : "+getu.getUgender());
System.out.println("나이 : "+getu.getUage());
System.out.println("권한 : "+getu.getUlevel());
System.out.println("--- 회원 출력 끝 ---");
}
}
package kr.or.ksmart.a;
public class If {
public void levelCheck(User u) {
if(u.getUlevel().equals("판매자") ) {
System.out.println("판매자 권한이 있어요.");
Goods g01 = new Goods();
TotalPrint tp01 = new TotalPrint();
tp01.gPrint(g01);
}else {
System.out.println("판매자 권한이 없어요. 상품 등록 불가!");
}
}
}
[ 객체 참조 변수의 주소를 어디에 생성할까? ]
package kr.or.ksmart.a;
public class If {
Goods g01 = null ;
public void levelCheck(User u) {
if(u.getUlevel().equals("판매자") ) {
System.out.println("판매자 권한이 있어요.");
g01 = new Goods();
TotalPrint tp01 = new TotalPrint();
tp01.gPrint(g01);
}else {
System.out.println("판매자 권한이 없어요. 상품 등록 불가!");
}
}
}
객체 주소를 지역변수 위치에 선언하면 안에서만 사용하고 휘발된다.
전역변수 위치에 선언하면 안에서도 사용이 가능하다.
그런데, 전체 코드에서 사용할 필요가 없을때 굳이 전역 변수 위치에 선언하면 필요 없는 주소가 계속 할당되기 때문에
전역변수 위치에 객체만 생성하고 주소는 생성하지 않고 ( Goods g01 = null ; )
필요한 위치에서만 주소를 생성해주고 휘발시킨다 ( g01 = new Goods(); )
static = 객체를 생성하여 주소를 할당하지 않아도 호출가능 / 이미 메모리에 고정되어있다 - 정적 모든 메서드나 변수를 static으로 선언하면 메모리 공간이 확보가 x nonstatic - static이 없는 경우 주소를 생성해야한다 (new 생성자메서드) 만약 static으로 데이터 영역에 전역변수를 선언하면 데이터가 계속 갱신됨 -하나의 메서드에 데이터를 계속 갱신해야한다 static / 데이터를 계속 쌓아야한다. nonstatic static으로 선언한 메서드는 주소를 생성하지 않고 클래스이름.메서드이름(변수); 를 이용해서 호출가능 (원래는 주소를 생성해서 객체참조변수를 이용해서 tp.getUid() 로 사용 - TotalPrint.getUid() 로 사용가능하다는뜻)
완성 파일
문제 파일 ( 혼자서 문제 풀어보기 )
'Back - end > JAVA' 카테고리의 다른 글
23.03.15 / jsp와 Java (0) | 2023.03.15 |
---|---|
23.03.15 / 서로 다른 패키지 import (0) | 2023.03.15 |
23.03.13 / 하나의 패키지 서로 다른 클래스 (필드에 바로 접근) (0) | 2023.03.13 |
23.02.28 / 하나의 패키지 하나의 클래스 (if문 조건식) (0) | 2023.03.08 |
23.02.28 / 메서드 선언과 호출의 원리 (0) | 2023.03.08 |