인스턴스 멤버와 정적 멤버

인스턴스 멤버와 this

인스턴스 멤버는 객체마다 가지고 있는 멤버를 말하고

정적 멤버는 클래스에 위치시키고 객체들이 공유하는 멤버를 말함

인스턴스 멤버란 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드를 말함

이들은 각각 인스턴스필드, 인스턴스 메소드라고 부름

 

인스턴스 멤버 선언

 

this

객체 외부에서 인스턴스 멤버에 접근하기 위해 참조 변수를 사용하는 것과 마찬가지로 객체 내부에

서도 인스턴스 멤버에 접근하기 위해 this를 사용할 수 있음

 

실습 예제( 선언, 호출 ) 

package sec05.exam01;

public class Car {
	//인스턴스 멤버, this
	// 최고 시속 지정
	
	private int gas;
	private int speed;
	
	void keyTurnOn() {
		System.out.println("키를 돌립니다.");
	}
	
	// 남은 가스를 체크
	boolean isLeftGas() {
		if(gas > 0) {
			return true;
		}else {
			return false;
		}
	}
	
	//달린다
	void run() {
		while (isLeftGas()) { // 참일경우 계속 반복 
			System.out.println("달립니다. (gas 잔량:" + 
								gas + "시속:" + speed + "km/h");
			if (speed <= 100) { // 최고 시속은 110이 됩니다.
				speed += 10;
			}
		 gas -= 1;
		}
		System.out.println("멈춥니다 gas 잔량: " + gas);
	}

	public int getGas() {
		return gas;
	}


	public void setGas(int gas) {
		this.gas = gas;
	//  this.인스턴스변수 = 참조변수
	}


	public int getSpeed() {
		return speed;
	}


	public void setSpeed(int speed) {
		this.speed = speed;
	//  this.인스턴스변수 = 참조변수
	}


	public static void main(String[] args) {
		// 1. 차를 만든다.( 생성 )
		Car myCar = new Car();
		
		// 2. 주유한다. ( 연료 잔량 )
		myCar.setGas(10); // 메소드 
		
		// 3. 차키를 돌린다 ( 시동 )
		myCar.keyTurnOn();
		
		// 4. 달린다.( 주유, 속도 정보 출력 )
		myCar.run();
		

	}

}

 

결과

 

 

 

 

정적 멤버와 static

정적(static)은 고정된이란 의미, 정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고

사용할 수 있는 필드와 메서드를 말함, 이들을 각각 정적필드, 정적 메소드라고 부름

 

정적 멤버 선언

정적 필드와 정적 메소드를 선언하려면 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 됨

객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언

객체마다 가지고 있을 필요가 없는 '공용데이터'라면 정적 필드로 선언

 

 

정적 멤버 사용

클래스가 메모리로 로딩되면 정적 멤버로 바로 사용할 수 있음

사용 방법은 클래스 이름과 함께 도트(.) 연산자로 접근

 

실습

package sec05.exam01;

public class Calculator {
	//정적필드, 정적멤버 
	// 계산기
	
	//선언
	static double pi = 3.14159;
	
	static int plus(int x, int y) {
		return x + y;
	}
	
	static int minus(int x, int y) {
		return x - y;
	}

	public static void main(String[] args) {
		// 호출 
		double result1 = 10 * 10 * Calculator.pi;
		int result2 = Calculator.plus(10, 5);
		int result3 = Calculator.minus(10, 5);
		
		System.out.println("result1 : " + result1);
		System.out.println("result2 : " + result2);
		System.out.println("result3 : " + result3);
	}

}
결과
result1 : 314.159
result2 : 15
result3 : 5

 

 

정적 메소드 선언 시 주의할 점

객체가 없어도 실행된다는 특징 때문에 정적 메소드를 선언할 때는 이들 내부에 인스턴스 필드나

인스턴스 메소드를 사용할 수 없음, this 키워드도 사용 불가

main() 메소드도 동일한 규칙이 적용, main()메소드도 정적 메소드이므로 객체 생성 없이

인스턴스 필드와 인스턴스 메소드를 main()메소드에서 바로 사용할 수 없음

package sec05.exam01;

public class ClassName {
	 
	
	//인스턴스 변수 
	int field;
	void method1() {
	this.field = 10;
	field2 = 500;
	method2();
	}
	
	// 정적 필드, 메소드는 메모리에 할당 되있음
	// 정적 필드, 정적 메소드
	static int field2;
	static void method2() {}
	static void method3() {	
		
//	this.field = 10; // 컴파일 에러 
		
	ClassName cn = new ClassName();
	cn.field = 100;
	// 객체 생성 후 참조 변수로 접근가능
		
	field2 = 300;
	method2();
		
	}
	
}

 

 

싱글톤

 

가끔 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다.

단 하나만 생성된다고 해서 이객체를 싱글톤이라고 합니다.

인스턴스가 하나만 존재

한 번의 인스턴스화만 허용하고 해당 인스턴스를 전역적으로 접근

 

싱글톤을 만들기

1. 클래스 외부에서 new 연산자로 생성자를 호출할 수 없도록 막아야 함 ( 생성자를 호출한 만큼 객체가 생성       되서 ) 외부에서 호출할 수 없도록 하려면 생성자 앞에 private 접근 제한자 붙여주면 됨

2. 자신의 타입인 정적 필드를 하나 선언하고 자신의 객체를 자기가 생성해 초기화

    ( 정적 필드도 private 접근 제한자를 붙여 외부에서 필드값을 변경하지 못하도록 막음 )

3. 외부에서 호출할 수 있는 정적 메소드인 getInstance()를 선언하고 정적 필드에서 참조하고 있는 자신의 

    객체를 리턴 해줌

 

외부에서 객체를 얻는 유일한 방법은 getInstance()메소드를 호출하는 방법 

getInstance() 메소드는 단 하나의 객체만 리턴하기 때문에 아래 코드에서 변수1과 변수2는 동일한 객체 참조

클래스 변수1 = 클래스.getInstance();
클래스 변수2 = 클래스.getInstance();

 

실습 1

선언

package sec05.exam01;
// 싱글톤 개념
public class Aaa {
	// 정적 필드
	private static Aaa a1 = new Aaa();//자기 자신을 초기화 
	// 생성자
	private Aaa() {}
	// 정적 메소드
	static Aaa mmm() {
		return a1;
	}
	void test() {
		System.out.println(a1);
	}
	

}

 

호출

package sec05.exam01;
//싱글톤 개념

public class AaaEx {

	public static void main(String[] args) {
//		Aaa.a1.mmm();
		Aaa a2 = Aaa.mmm();
		a2.test();
		
		Aaa a3 = Aaa.mmm();
		a3.test();
	}

}
결과
sec05.exam01.Aaa@3b6eb2ec
sec05.exam01.Aaa@3b6eb2ec

실습 2

선언

package sec05.exam01;

public class Singleton {
	//싱글톤 선언
	
	//정적 필드
	private static Singleton singleton = new Singleton();
	
	//생성자
	private Singleton() {}
	//정적 메소드
	static Singleton getSingleton() {
		return singleton;
	}
}
호출

package sec05.exam01;

public class SingletonEx {

	public static void main(String[] args) {
		//싱글톤 호출
		
	/*	
		Singleton obj1 = new SingletonEx();
		Singleton obj2 = new SingletonEx(); */ //컴파일 에러
		
		Singleton obj1 = Singleton.getSingleton();
		Singleton obj2 = Singleton.getSingleton();
		
		if(obj1 == obj2) {
			System.out.println("같은 Singleton 객체입니다.");
		}else {
			System.out.println("다른 Singleton 객체입니다.");
		}
	}

}
결과
같은 Singleton 객체입니다.

 

 

 

final 필드와 상수

 

final 필드

final 타입 필드 [= 초기값];

final 필드는 저장된 초기값이 최종 값이므로, 수정할 수 없음

초기값을 줄 수 있는 방법은 2가지가 있음

1. 필드 선언 시에 주는 방법

2. 생성자에서 주는 방법

 

package sec05.exam01;

public class FinalTest {
	// 상수 선언
	static final int z = 23;
	
	final int x;
	final String ssn;
	
	// 생성자 자동 추가 
	public FinalTest(int x, String ssn) {
		super();
		this.x = x;
		this.ssn = ssn;
	}

	// 호출
	public static void main(String[] args) {
		FinalTest ft = new FinalTest(10, "홍");
//		ft.x = 40;
//		ft.ssn = "kim" 상수 값 변경 불가
		System.out.println(ft.ssn);
		final int y;
		y = 400;
//		y = 700; 컴파일 에러 상수 변경 불가
		System.out.println(FinalTest.z);
//		FinalTest.z = 30; 상수 변경 불가

	}

}

 

 

상수

일반적으로 불변의 값을 상수(static final)라고 부름

상수는 static이면서 final이어야 함

static final 필드는 객체마다 존재하지 않고 클래스에만 존재

한 번 초기값이 저장되면 변경할 수 없음

static final 타입 상수 = 초기값;

상수 이름은 모두 대문자로 작성하는 것이 관례

서로 다른 단어가 혼합된 이름이라면 언더바(_)로 단어들을 연결

 

 

 

패키지와 접근 제한자

패키지 선언

클래스를 작성할 때 해당 클래스가 어떤 패키지에 속할 것인지를 선언하는 것을 패키지 선언이라고 함

패키지는 클래스의 일부, 클래스만 따로 복사해서 다른 곳으로 이동하면 클래스를 사용할 수 없기 때문에

패키지 이름 규칙

1. 모두 소문자로 작성하는 것이 관례

2. java로 시작하는 패키지는 자바 표준 API에서만 사용하므로 사용해서는 안됨

3. 숫자로 시작하면 안되고 특수문자는 _, $ 만 허용

 

실습

같은 패키지 A, B

A

package sec06.exam03.package1;

public class A {
//	public A(boolean b) {}
//	A(int b){}// default
//	private A(String s) {}
	
	public int field1;
	int field2;// default
	private int field3;
	
	//메소드
	public void method1() {}
	void method2() {}
	private void method3() {}
}
B

package sec06.exam03.package1;

public class B {
//	A a1 = new A(true); // public A(boolean b) {} 가능
//	A a2 = new A(1);// A(int b){}// default 가능
//	A a3 = new A("문자열"); // private A(String s) {} 불가
	
	public B() {
		A a = new A();
		a.field1 = 1;
		a.field2 = 2;
//		a.field3 = 3; // 불가 
		
		a.method1();
		a.method2();
//		a.method3(); // 불가
	}
	
}

 

다른 패키지 C

C

package sec06.exam03.package2;


import sec06.exam03.package1.A;
import sec06.exam03.package1.B;

public class C {
	B b; // import 가능
//	A a; // default로 import 불가 public으로 바꿔줘야됨
	
//	A a1 = new A(true); // public A(boolean b) {} 가능
//	A a2 = new A(1);// A(int b){}// default 불가
//	A a3 = new A("문자열"); // private A(String s) {} 불가
public C() {
	A a = new A();
	a.field1 = 1;
//	a.field2 = 2; // 불가
//	a.field3 = 3; // 불가 
	
	a.method1();
//	a.method2(); // 불가
//	a.method3(); // 불가
	
}

}

 

 

import문

사용하고자 하는 클래스 또는 인터페이스가 다른 패키지에 소속 되어 있다면,

import문으로 해당 패키지의 클래스 또는 인터페이스를 가져와 사용할 것임을 컴파일러에게 알려줘야 함

import문은 패키지 선언과 클래스 선언 사이에 작성

만약 사용하고자 하는 클래스들이 동일한 패키지 소속이라면 개별 보다는 '*'를 이용

 

 

 

접근 제한자

접근 제한자(Access modifier)는 말 그대로 접근을 제한하기 위해 사용됨

접근이란 클래스 및 인터페이스 그리고 이들이 가지고 있는 멤버의 접근을 말함

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-02 13일차  (0) 2023.06.02
2023-06-01 12일차  (0) 2023.06.01
2023-05-30 10일차  (0) 2023.05.30
2023-05-26 9일차  (1) 2023.05.26
2023-05-25 8일차  (0) 2023.05.25

클래스

필드 

package static0531;

public class Student {
	// 인스턴스 변수 저장 공간
	public String name;
	public int kor;
	public int math;
	public int eng;
}

 

index,  배열 초기값 , 학생 정보를 저장하는 역활

싱글톤 대신 해당 코드로 할 시 주소값이 바뀌어서 새로고침하면 데이터가 바뀜 

package static0531;

public class HandleStu {
	// index, 배열 초기값 설정
	
	// stu 배열을 초기화하고 학생 정보를 저장하는 역할
	// 학생 정보를 저장하는 배열인 stu를 Singleton과 공유
	public static int index = 0;
	public static Student[] stu = new Student[3];
	public static void create() {
		for(int i=0; i < stu.length; i++ ) {
			stu[i] = new Student();
		}
	}

}

 

싱글톤 클래스

package static0531;

public class Singleton {
	
	//싱글톤 : 한 번의 인스턴스화만 허용하고 해당 인스턴스를 전역적으로 접근
	// 학생 정보를 저장하는 배열인 stu를 공유
	private static Singleton st = new Singleton();
	public Student[] stu = new Student[3];
	
	// 사용자가 입력한 정보는 stu 배열에 저장
	private Singleton() {
		for(int i=0; i < stu.length; i++ ) {
			stu[i] = new Student();
		}
	}
	public static Singleton getInstance() {
		return st;
	}
	
}

 


 

JSP 파일

사용자에게 입력 => 해당 값으로  처리하는 곳으로 이동

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
//번호, 이름, 국어 점수, 수학 점수, 영어 점수를 입력 받고 res.jsp로 이동
%>
<form action ="res.jsp">
번호(0~2)<input type="text" name="bunho" /><br/>
이름<input type="text" name="name" /><br/>
국어<input type="text" name="kor" /><br/>
수학<input type="text" name="math" /><br/>
영어<input type="text" name="eng" /><br/>
<input type="submit" />
</form>

</body>
</html>

 

입력 받아온 정보를 처리하는 역할

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="static0531.*" %>
<%
// Singleton 클래스의 인스턴스를 가져옴
// 한 번의 인스턴스화만 허용하고 해당 인스턴스를 전역적으로 접근
Singleton st = Singleton.getInstance();

//사용자가 입력한 학생 정보를 처리하는 역할

String bunho = request.getParameter("bunho");
int index = Integer.parseInt(bunho);
//request.getParameter => 사용자가 입력한 정보를 변수에 저장
String name = request.getParameter("name");
String kor = request.getParameter("kor");
// Integer.parseInt => 입력받은 문자열을 int타입으로 변경
int kscore = Integer.parseInt(kor);
String math = request.getParameter("math");
int mscore = Integer.parseInt(math);
String eng = request.getParameter("eng");
int escore = Integer.parseInt(eng);
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<br/>
<% 
//Singleton 인스턴스인 st의 stu 배열에서 입력된 인덱스(index)에 해당하는 학생 객체의 이름을 입력값으로 설정합니다. 
//예) st.stu[0].name = name;은 입력된 인덱스 0에 해당하는 학생 객체의 이름을 입력값으로 설정
st.stu[index].name = name;
st.stu[index].kor = kscore;
st.stu[index].math = mscore;
st.stu[index].eng = escore;
//입력된 학생 정보는 Singleton 인스턴스의 stu 배열에 저장됩니다. 
//이 배열은 HandleStu 클래스에서 생성되며, 각 인덱스에는 학생 객체가 할당

%>

</body>
</html>

 

출력

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="static0531.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
//HandleStu.create();
// Singleton 인스턴스를 생성하고, stu 배열의 각 학생 정보를 가져와 출력
Singleton s1 = Singleton.getInstance(); 
for (Student st : s1.stu){
	out.println(st.name);
	out.println(st.kor);
	out.println(st.math);
	out.println(st.eng);
	out.println("<br/>");
	}
%>
</body>
</html>

 


 

실행

1. stuForm.jsp 실행 후 사용자에게 입력 받음 번호는(0~2)는 배열 인덱스

2. 사용자에게 입력 받은 값 저장 ( 새로고침 후 적용 )

3. stuForm.jsp 뒤로 가기 후 번호 (1) 값 입력 후 제출

4. viewstu.jsp 페이지 새로고침하면 번호(1)값도 저장

5. 동일하게 3, 4번 동일하게 진행 번호(2)값도 저장

6. viewstu.jsp 페이지 새로고침해도 값이 초기화가 되지 않음 (  싱글톤 활용 ) 

싱글톤 : 한 번의 인스턴스화만 허용하고 해당 인스턴스를 전역적으로 접근

 

 

if_else 조건 1 

 

package Ifmoon;

public class Basic_if_else {

	// if문의 옵션 2종류
//		1. else
//			- 조건이 2가지인 경우 else를 이용
//		2. else if 
			
	
	public static void main(String[] args) {
		 int num = 1;
		 
		 if(num % 2 == 0) {
			 System.out.println("짝수");
		 }
		 if(num % 2 == 1) {
			 System.out.println("홀수");
		 }
		 System.out.println("-------------");
		 
		 if(num % 2 == 0) {
			 System.out.println("짝수");
		 }else {
			 // if의 조건이 아니면 무조건 실행
			System.out.println("홀수");
		}
	}

}


if_else 조건 2

 

package Ifmoon;

public class Basic_if_else {

			
	
	public static void main(String[] args) {
		int select = 1;// 번호 입력
		
		System.out.println(">> 자판기 <<");
		System.out.println("[1.과자 2.음료수 3.라면]");

		System.out.println("번호를 입력하세요 : " + select );
		
		if(select == 1) {System.out.println("1.과자");}
		if(select == 2) {System.out.println("2.음료수");}
		if(select == 3) {System.out.println("3.라면");}
		else { System.out.println("오류"); }
		//else는 바로 위에 있는 if문이랑만 연결 되있음
		//바로 위에 있는 if문이 false이므로 "오류" 출력됨
		
		System.out.println("---------------");
		
		System.out.println(">> 자판기 <<");
		System.out.println("[1.과자 2.음료수 3.라면]");
		select = 1;
		if(select == 1) {System.out.println("1.과자");}
		if(select == 2) {System.out.println("2.음료수");}
		if(select == 3) {System.out.println("3.라면");}
		if(3 < select || select < 1) { System.out.println("오류"); }
		// 1 ~ 3 숫자가 아닌 경우 오류
	}

}

 

 


 

else if 조건

package Ifmoon;

public class Basic_if_else {
/*
	if문의 옵션 else if 
	1. if문 가지고도 정확한 코드를 작성할 수 있지만,
	   else if를 사용하면 조건문의 조건이 여러개인 경우
	   보다 호율적으로 코드를 작성할 수 있다.
	2. 구조
		if(조건식1) {
			조건식1이 참(true)일 때, 실행할 문장;
		}else if(조건식2){
			조건식2가 참(true)일 때, 실행할 문장;
		}else if(조건식3){
			조건식3이 참(true)일 때, 실행할 문장;
		}else {
			위 조건을 모두 만족하지 않을 때, 실행할 문장;
		}
	
										*/
	
	public static void main(String[] args) {
		
		// if에서 else if 2개를 거쳐
		System.out.println("-----------------");
		System.out.println(">>> 과일");
		System.out.println("[1.사과 2.포도 3.감]");
		System.out.println("번호를 입력하세요 : 5");
		
		int selsect = 5;
		if(selsect == 1) {System.out.println("1.사과");}
		else if(selsect == 2) {System.out.println("2.포도");}
		else if(selsect == 3) {System.out.println("3.감");}
		else {System.out.println("오류1");}
		//위에 전부 false이기 때문에 "오류" 출력
		
		System.out.println("-----------------");
		
	
		
	}

}

 

 

package Ifmoon;

public class Skip_if {

	public static void main(String[] args) {
		int a = 10;
		int b = 10;
		
		// 코드공유 측면에서 중괄호 쓰는걸 권장 
		if(a == b) { // if문 중괄호 있음
			System.out.println("실행O-(1)");
		}
		if(a == b) // if문 중괄호 없음 
			System.out.println("실행O-(2)");
			System.out.println("------------");
			
		if(a != b) {
			System.out.println("실행X-(1)");
			System.out.println("실행X-(2)");
		}
		if(a != b)// 중괄호 없음 
			System.out.println("실행X-(3)");
			System.out.println("실행X-(4)");
			// 실행X-(4)는 if문에 포함이 안되기때문에 출력됨
	

}
}

 

package Ifmoon;

import java.util.Random;// Random import

public class Random01 {

	public static void main(String[] args) {
		Random ran = new Random();
		
		// 예) 0 ~ 2 사이의 랜덤
		int rNum = ran.nextInt(3);// 0, 1 , 2
		System.out.println(rNum);
		
		// 문제1) 1 ~ 5 사이의 랜덤
		rNum = ran.nextInt(5) + 1;// [ 0 ~ 4 ] + 1
		// 랜덤으로 출력되는 값에 +1씩 1~6 출력 
		System.out.println(rNum);
		
		// 문제2) -3 ~ 3 사이의 랜덤
		rNum = ran.nextInt(7) - 3; // [0 ~ 6] - 3
								   //=[ -3 ~ 3 ] 출력
		System.out.println(rNum);
		
		// 문제3) 150 ~ 250 사이의 랜덤
		rNum = ran.nextInt(101) + 150;
		//     [ 0 ~ 100] + 150
		System.out.println(rNum);
	}

 

 

+ Recent posts