클래스 사이의 관계를 파악하여 필요한 곳에 인스턴스화를 할 수 있어야 한다.
인스턴스화의 위치에 따라 NullPointException 발생할 수 있다는 것을 설명하고, 해결할 수 있어야 한다.
static 대신 생성자 호출을 통해 객체 주입을 받아내는 코드를 작성할 수 있어야 한다.
package com.step4;
class M{ //변수
int tot;
double avg;
}
class M1{//메소드
void hap() {
System.out.println("hap()");
}
void hap(int n1) {
int n2 = 2;
System.out.println("hap(int n1)");
System.out.println("hap(int n2)" + n2); //지변은 초기화 생략x
}
void hap(M1 m1) { //목적지!
System.out.println("hap(M1 m1)" + m1);
}
}
public class MMain {
public static void main(String[] args) {
int n1 = 70;
int n2 = 80;
int n3 = 90;
M1 m1 = null;
System.out.println(m1); //주소x, NullPointerException 발생
//나누는 순간 공백, 시점의 문제 발생
m1 = new M1();
System.out.println(m1); //주소o
m1.hap(m1); //선언은 클래가 들어가지만, 호출하는 자리에는 변수가 들어감
//지변이더라도 파라미터를 통해 원본을 넘기면 다른 메소드에서도 사용이 가능함.
}
}
id | age | name … |
---|---|---|
세로 방향이라 같은 타입만 담기는 한계 있음.(데이터 간의 관계 확인x)
생성자를 통해 사이즈가 결정되면 변경 x
데이터 끼워넣기 x
public static void main(String[] args) {
int com[] = new int[3];
for(int i=0;i<3;i++) {
System.out.println("com ["+i+"]"+com[i]);
}
}
public static void main(String[] args) {
int my[] = {1, 2, 3};
//가진 전부를 처리할 땐 개선된 for 문 사용
for(int i:my) {
System.out.print(i); // 1, 2, 3 출력
}
System.out.println();
int other[] = new int[] {1,2,3};
for(int i:other) {
System.out.println(i);
}
}
class F2{
//생성자
F2(){}
F2(int i){ }
// F2(int j){ } //타입, 갯수 같음
F2(boolean isOk){System.out.println(isOk);}
F2(String s, int i){ }
F2(int i, int j){System.out.println(i+","+j);}
}
public class Fmain2 {
public static void main(String[] args) {
F2 f = new F2(1,2);
System.out.println(f);
f = new F2(true); //객체 배열, 자료구조, 웹 or 하이브리드, JSON
System.out.println(f); //다른 주소번지를 갖는다.
}
}
class GLogic{
int i = 1;
public GLogic(GView gv) { //null
System.out.println(gv);
}
}
public class GView {
//디폴트 생성자만 생략 가능함!
GView() {
GLogic gl = new GLogic(this); //this는 현재 스레드가 관리하는 클래스이고 원본 나 자신
//원본인지 확인하는 법? 전역변수로 확인 가능??
}
public static void main(String[] args) {
//static 안에서는 this나 supper(부모클래스 수정자?) 사용 불가 -> 생성자에서는 가능하다
GView gv = new GView();
System.out.println(gv);
}
}
class Dept{
//전변은 초기화를 생략할 수 있다. 생성자가 대신 해준다.
public Dept() {}
private int deptno; //부서번호
private String dname; //부서명
private String loc; //지역
public Dept(int deptno, String dname, String loc) {
//지역변수와 전역변수의 동기화! (생성자의 파라미터값으로 재정의, 초기화)
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
}
public class DeptMain {
public static void main(String[] args) {
//인스턴스화를 해도 안된다. -> 캡슐레이션(캡슐화) 그 사물을 정의하는 중요한 고유명사 만들기 private
Dept dept = new Dept(); //기본값
Dept dept1 = new Dept(10, "개발1팀", "부산"); //10 새로운 객체 생성
System.out.println(dept.getDeptno()); //0
dept1.setDeptno(100); //10->100 초기화 by 생성자의 인터셉트
System.out.println(dept1.getDeptno()); //10
dept1 = null; //캔디데이트 상태 -> 너는 앞으로 쓰레기 값이 됨
//- > dept1 = new dept1(); 실행되면 앞의 38번에서 생성된 객체는 사라짐
// dept1.setDeptno(100); //NullPointerException 발생
dept1 = new Dept();
dept1.setDeptno(100); //10->100 초기화 by 생성자의 인터셉트
dept1.setDname("운영1팀");
dept1.setLoc("제주");
System.out.println(dept1.getDeptno()+", "+dept1.getDname()+", "+dept1.getLoc());
System.out.println(dept.getDeptno()+", "+dept.getDname()+", "+dept.getLoc());
}
}
/*
Dept 클래스에 Getter Setter를 두는 것은 결국 전역변수를 사용하기 위함이다.
web서비스 - 동기화 가능
150명 사용 -> 인스턴스를 갖는다 ->하나임 ->싱글톤
*/
int i = 1;
int j = i++; //j=1, i=2
int a = 1;
int b = ++a; //b=2, a=2
public class Oper4 {
public static void main(String[] args) {
int i = 1;
int j = 10;
do {
System.out.println("나는 do문과 함께 무조건 실행된다. "+i+", "+j);
if( i>j ) break;
System.out.println("if문의 조건 만족하면 나는 못 본다."+i+", "+j);
j--;
}while( ++i < 5 );
System.out.println("i는 "+i+", j는 "+j);
}
}
/*
나는 do문과 함께 무조건 실행된다. 1, 10
if문의 조건 만족하면 나는 못 본다.1, 10
나는 do문과 함께 무조건 실행된다. 2, 9
if문의 조건 만족하면 나는 못 본다.2, 9
나는 do문과 함께 무조건 실행된다. 3, 8
if문의 조건 만족하면 나는 못 본다.3, 8
나는 do문과 함께 무조건 실행된다. 4, 7
if문의 조건 만족하면 나는 못 본다.4, 7
i는 5, j는 6
*/
public void ranCom() {
Random r = new Random();
com[0] = r.nextInt(10); //0~9 사이 숫자 채번
//do..while문 조건검사를 나중에 하므로 무조건 한 번은 실행되고, while문은 먼저 조건검사를 하니 한번도 실행이 안될 수 있음.
do {
com[1] = r.nextInt(10);
}while(com[0] == com[1]);
do {
com[2] = r.nextInt(10);
}while(com[0] == com[1] || com[1] == com[2]);
}
public class UnitTest {
public static void main(String[] args) {
BaseballGame bbg = new BaseballGame();
String hint = null;
int cnt = 0;
for(int i=0;i<3;i++) {
hint = bbg.account(++cnt +"회차 : "+"25"+ ++i);
System.out.println(hint);
}
public String account(String user) {
System.out.println("사용자가 입력한 숫자는 "+user);
if(user.length()!=3) {
return "세자리 숫자를 입력하세요.";
}
//사용자가 jtf_user에 입력한 숫자는 보기에는 숫자 처럼 보여도 알맹이는 문자열로
//인식을 합니다. 그래서 형전환을 한 후 my[]배열에 담아야 함니다.
//문자열 "256"을 숫자로 담을 변수 선언
int temp = 0;
int strike = 0;//힌트로 사용될 스트라이크를 담을 변수 선언
int ball = 0;//볼을 담을 변수 선언
//strike와ball을 지역변수로 해야 하는건 매 회차 마다 값이 변해야 하기 때문이다.
try {
temp = Integer.parseInt(user);
} catch (NumberFormatException e) {
return "숫자만 입력하세요.";
}
my[0] = temp/100; //2.56 -> int 2만 담김(백의자리)
my[1] = (temp%100)/10; //5.6 -> int 5만 담김(십의자리)
my[2] = temp%10; //6 -> int 6만 담김(일의자리)
System.out.println(my[0]+""+my[1]+""+my[2]);
for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
if(com[i] == my[j]) { //숫자 같니?
if(i == j) { //위치 같니?
strike++;
}else {
ball++;
}
}
}
}
return strike+"스 "+ball+"볼";
}