본문 바로가기

📚Study Note/JAVA

[ JAVA ] 정보은닉(private) , static 변수와 static 메소드

 

/*==========================================
 ■■■  클래스와 인스턴스 ■■■
   - 정보은닉과 접근제어지시자 
 ===========================================*/
import java.util.Scanner;
class CircleTest2
{
	// 정보은닉(Information Hiding)
	// 멤버변수= 인스턴스변수= 전역변수
	// 『private』 이라는 접근제어 지시자의 선언은 클래스 내부에서만 접근 및 참조가 가능하게 하겠다는 의미
	// int 형 변수 0으로 초기화 지원.


	private int r;

	//가만히 두면 0으로 계속 간다.
	
	//★★테스트용
	/*void input()
	{
		Scanner sc = new Scanner(System.in);
		System.out.print("반지름 입력 : ");
		r= sc.nextInt();
	}*/
	
	
	void setR(int r)
	{
		this.r = r; //this안쓰면 매개변수로 인식한다.
		//이와 같은 형태로 표기하게 되면 멤버변수와 지역변수가 같은 이름을 갖고있는 상황이기 때문에 
		//둘다 같은 지역변수로 인식하여 처리한다. 『this』는 자기 자신을 나타내는 예약어이다.
		// -- 멤버 변수를 지역 변수와 구분하기 위해서 클래스의 멤버 변수 앞에 『this』 표기!
	}

	double calArea()
	{
		return r*r*3.141592;
	}

	void write(double a)
	{
		System.out.println("반지름 : " + r);
		System.out.println("넓  이 : " + a);

	}
}
//main() 메소드를 포함하고 있는 외부의 다른 클래스




public class Test091
{
	public static void main(String[] args)
	{
		// CircleTest2 클래스 기반의 인스턴스 생성
		CircleTest2 ob1 = new CircleTest2();
		CircleTest2 ob2 = new CircleTest2();
		
		
		//넓이 연산 결과를 담을 변수 선언
		double result;

		//ob1.r =10; //-==>Test091.java:38: error: r has private access in CircleTest2 컴파일 에러 발생한다.     
		//System.out.println(ob1.r); //-==>>10 → 아마 private 으로 바꾸기 이전의 결과값.

		//	멤버 r에 10을 직접 대입했으므로 메소드를 통해 기능하는 것이 아니다.(=즉 속성값에 직접 접근하는 경우로 오류가 발생한다)
		//	정보은닉하려면 private int r; 
		//	『private』 변수는 외부에서 접근이 불가능하다.

		// ★★테스트한 후 주석처리
		//ob1.input();

/*
반지름 입력 : 3
반지름 : 20
넓  이 : 1256.6368
계속하려면 아무 키나 누르십시오 . . .*/

		

		//ob2.r=500; → 오류뜸(r has private access in CircleTest2 )
		// 두 번째 인스턴스(ob2)의 반지름을 20으로 초기화!
		ob2.setR(20);
		result = ob2.calArea();
		ob2.write(result);

		/*
		반지름 : 20
		넓  이 : 1256.6368
		계속하려면 아무 키나 누르십시오 . . .*/
		
	}
}

    private 접근제어 지시자가 붙은 변수는 메소드를 통해서 접근 가능하기 때문에 인스턴스명.변수명 의 형태로는 접근이 불가하다.

 

 

 

 

 

 

 

 

 

 

/*==========================================
 ■■■  클래스와 인스턴스 ■■■
   - 정보은닉과 접근제어지시자
   - 배열 활용
 ===========================================*/
// ○ 실습문제 

// 아래의 클래스 ( Weekday)를 완성한다.
// 사용자로부터 년, 월, 일을 입력받아 해당 날짜의 요일을 출력하는 프로그램을 구현한다. 단 , 달력 클래스(Calendar)는 사용하지 않는다.
// 또한, 클래스의 개념을 활용하여 작성할 수 있도록 한다. 그리고 배열의 개념도 적용시켜 작성할 수 있도록 한다.

// 실행 예
// 년 월 일 입력(공백 구분) : 1997 10 6

// >> 1997년 10월 6일 → 월요일 
// 계속하려면 아무 키나...

// ※ 문제 인식 및 분석
// - 윤년 및 평년의 개념 적용
// 1년 1월 1일 → 월요일
import java.util.Scanner;

class Weekday
{
	


	//★★★주요 변수 선언(속성 구성)
	private int y, m, d;
	
	
	// ★★★메소드 정의(입력받기)
	void input()
	{
		Scanner sc = new Scanner(System.in);

		System.out.print("년 월 일 입력(공백 구분) : ");
		y = sc.nextInt();
		m = sc.nextInt();
		d = sc.nextInt();

	}	
		
	// ★★★메소드 정의(요일산출하기)	
	
	String week()
	{
		// 각 월의 마지막 날짜(각 월의 최대값)을 배열 형태로 구성
		int[] arr = {31,28,31,30,31,30,31,31,30,31,30,31};
		String[] arr2 = {"월요일", "화요일", "수요일", "목요일", "금요일", "토요일", "일요일"};

		// 날수, 루프, 요일 선언
		int nalsu, i, w;

		// 윤년이라면 2월의 마지막날짜는 29일
		// 평년이라면 2월의 마지막날짜는 28일

		if (y%4==0 && y%100!=0 || y%400==0)
		{
			arr[1]=29;
		}



		int r=0; //윤년의 개수
		

		for (i=1; i<=(y-1); i++)
		{
			
			if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)
			{
				++r;
				continue;
			}	
						
		}

		// 1년 1월 1일부터 입력받은 년도 이전 년도인 12월 31일까지의 날 수 계산
		nalsu = 365*(y-1-r) + 366*r ;

		// 테스트
	    //System.out.println(nalsu);

		// 입력받은 월 이전 월까지의 날 수 계산 후 nalsu에 더하는 연산

		for (i=0; i<m-1; i++)
		{
			nalsu +=arr[i];
		}
		
		
		nalsu +=d; // 전체 날 수 

		w=nalsu % 7; // 전체날수 % 7 =0 일요일

		return arr2[w-1];
	}

	// 메소드 정의(결과 출력하기)
	void print(String day)
	{
		System.out.printf("\n%d년 %d월 %d일 → %s\n", y, m, d, day);
	}
}
public class Test092
{
	public static void main(String[] args)
	{

		Weekday wd = new Weekday();
		wd.input();
		
		String result = wd.week();
		wd.print(result);

	}
}
/*[출력결과]
년 월 일 입력(공백 구분) : 1 1 1

1년 1월 1일 → 월요일
계속하려면 아무 키나 누르십시오 . . .

년 월 일 입력(공백 구분) : 2021 3 25

2021년 3월 25일 → 목요일
계속하려면 아무 키나 누르십시오 . . .


*/

 

 

 

 

 

 

 

 

 

/*==========================================
 ■■■  클래스와 인스턴스 ■■■
   - 클래스 변수(static 변수) 와 클래스메소드(static메소드)
 ===========================================*/

/*※ 실습 편의상 접근제어 지시자 생략
클래스 변수 또는 클래스 메소드는 클래스 정보가 로딩되는 순간 메모리에 할당이 이루어지며
클래스 이름 또는 객체(인스턴스)를 통해 접근할 수 있다.

즉 new연산자를 통해 메모리를 할당받지 않아도 사용이 가능하다는 것이다. 

인스턴스 변수는 동일한 클래스의 메소드에서는 바로 접근하는 것이 가능하지만 클래스 
메소드에서는 접근할 수 없다.

*/
public class Test093
{
	static int a =10; //클래스 변수
	int b = 20;//인스턴스 변수 

	void write()//인스턴스 메소드
	{
		System.out.println("클래스 변수 a : " + a);
		System.out.println("인스턴스 변수 b : " + b); 

	}//write메소드끝
	static void print()//클래스 메소드
	{
		System.out.println("클래스 변수 a : " + a);
		System.out.println("인스턴스 변수 b : " + b);//에러발생 b가 static변수가 안니라서

	}//print메소드끝
	
	
	
	
	
	public static void main(String[] args)
	
	{
		System.out.println("main() → 클래스 변수 a : " + Test093.a);
		//-==>>main() → 클래스 변수 a : 10
		//계속하려면 아무 키나 누르십시오 . . .


		// 클래스 변수에 접근하기 위해서는 『클래스명.변수명』 의 형태로 가능하다.

		//this.__ 이걸 하게 된 이유 : 바로 여기서 이 문법을 선점했기 때문이다.

		System.out.println("main() → 클래스 변수 a : " + a);
		//-==>main() → 클래스 변수 a : 10
		// 같은 클래스 내부에 존재하기 때문에 클래스 이름은 생략 가능
		
		Test093.print();
		//--==>클래스 변수 a : 10

		print();
		//-==>>클래스 변수 a : 10
		// 클래스 메소드에서 클래스 메소드의 호출은가능하며 『 클래스명.메소드명()』 의 형태로 접근하여 호출하는 것이 가능하다.
		// 또한 지금은 같은 클래스 내부에 존재하기 때문에 클래스의 이름을 생략하는 것이 가능하다,

		//System.out.println("main() → 인스턴스 변수 b : " + Test093.b); //error: non-static variable b cannot be referenced from a static context
		//System.out.println("main() → 인스턴스 변수 b : " + b); // error: non-static variable b cannot be referenced from a static context

		//write(); 인스턴스 메소드이기 때문에 (안태어났기 때문에) 이렇게 부를 수 없다.

		//인스턴스 생성이 되어야 태어나는 것이다. (길동이라고 짓자 라고는 했지 태어나지는 않았다)

		//Test093.write(); 
        
		//Test093기반의 인스턴스 생성
		Test093 ob1 = new Test093();

		System.out.println("main() → 인스턴스 변수 b 접근 : "+ ob1.b);
		//-==>>main() → 인스턴스 변수 b 접근 : 20

		//생성된 인스턴스를 통한 인스턴스 메소드 접근(호출)
		ob1.write();
		/*
		클래스 변수 a : 10
		인스턴스 변수 b : 20*/

		// 생성된 인스턴스를 통한 클래스 변수 접근
		System.out.println("main() → 클래스 변수 a : " + ob1.a);
		//-==>> main() → 클래스 변수 a : 10

		//생성된 인스턴스를 통한 클래스 메소드 접근
		ob1.print();
		//-==>>클래스 변수 a : 10


		// ※ 클래스 변수나 클래스 메소드는 『생성된인스턴스명.변수명
		//『생성된인스턴스명.메소드명() 
		//의형태로도 접근(호출)이 가능하지만 
		//『생성된클래스명.변수명   『생성된클래스명.메소드명() 
		//의 형태로 접근호출하는것이 일반적이다. 


		//Test093클래스 기반 두 번째 인스턴스 생성
		Test093 ob2 = new Test093();

		ob2.a = 1000;     //클래스변수 초기화
		ob2.b = 2000;	  //인스턴스변수 초기화


		System.out.println("ob2 확인 ----------------------------------");


		ob2.write();
		ob2.print();
		/*
		클래스 변수 a : 1000
		인스턴스 변수 b : 2000
		클래스 변수 a : 1000*/

		System.out.println("ob1 확인 --------------------------------");
		ob1.write();
		ob1.print();

		/*ob1 확인 --------------------------------
		클래스 변수 a : 1000
		인스턴스 변수 b : 20
		클래스 변수 a : 1000
		계속하려면 아무 키나 누르십시오 . . .*/
		
	}
}

 

 

 

 

 

 

 

 

 

 

 

/*==========================================
 ■■■  클래스와 인스턴스 ■■■
   - 클래스와 인스턴스 활용
 ===========================================*/

// ○ 실습 문제
// 1 ~ 3 사이의 정수 형태의 난수를 발생시켜 가위, 바위, 보 게임프로그램을 구현하다. 단 클래스의 개념을 활용하여 처리할 수 있도록 한다.
//또한 배열을 활용하여 처리할 수 있도록 한다.

// 기준 데이터 → 1: 가위 2: 바위 3: 보
// 실행 예)
// 1: 가위, 2: 바위, 3: 보 중 입력(1~3) : 4
// 1: 가위, 2: 바위, 3: 보 중 입력(1~3) : -10
// 1: 가위, 2: 바위, 3: 보 중 입력(1~3) : 2
// - 유저 : 바위
// - 컴퓨터 : 보
// >> 승부최종결과 : 컴퓨터가 이겼습니다!
// 계속하려면 아무 키나...


import java.util.Random;
import java.util.Scanner;
class RpsGame
{
	int user; //가위바위보 중 무엇을 냈는지 담는 변수들 선언
	int com;



//가위바위보 랜덤값 받아오는 메소드
//사용자에게 번호 받는다
//번호로 받은 거슬 가위바위보로 바꿀것
//승부에 대한 결과를 가리는 것 그리고 결과반환
//최종적으로 출력하는메소드

	
	
	//가위바위보 랜덤값 받아오는 메소드
	private void runCom()
	{
		Random rd = new Random();
		com = rd.nextInt(3) +1 ; // 012 로 출력되는데 +1로 해서 123형태로 만듦
		

	}

	//사용자에게 번호 받는다
	public void input()
	{

		runCom(); //컴퓨터가 먼저 가위바위보 중에 하나를 입력하도록 함 
		Scanner sc = new Scanner(System.in);

		do
		{
		System.out.print(" 1: 가위, 2: 바위, 3: 보 중 입력(1~3) : ");
		user = sc.nextInt();
		}
		while (user<1 || user>3);
		

	}

	//번호로 받은 거슬 가위바위보로 바꿀것
	public void middleCalc()
	{
		String[] str = {"가위", "바위", "보"};
		System.out.println(" - 유저 : " + str[user-1]);
		System.out.println(" - 컴퓨터 : " + str[com-1]);


	}

	//승부에 대한 결과를 가리는 것 그리고 결과반환
	public String resultCalc()
	{
		String result = "무승부";

		if ((user==1&&com==3)|| (user==2&&com==1) || (user==3 && com==2))
			result = "당신이 승리했습니다!!!!!!!!!!!!";
	
		if ((user==1&&com==2) || (user==2&&com==3)||(user==3&&com==1))
			result = "컴퓨터가 승리했습니다~!!!!!!!!!!!!!!!!";

		return result;

	}

	//최종적으로 출력하는메소드
	public void print(String result)
	{
		System.out.println(">> 승부 최종 결과 : " + result);
		
	}



}

public class Test095
{
	public static void main(String[] args)
	{
		RpsGame ob= new RpsGame();
		ob.input();
		ob.middleCalc();
		String result = ob.resultCalc();
		ob.print(result);


	

		
	}

}

/*
 1: 가위, 2: 바위, 3: 보 중 입력(1~3) : 2
 - 유저 : 바위
 - 컴퓨터 : 바위
>> 승부 최종 결과 : 무승부
계속하려면 아무 키나 누르십시오 . . .
*/