부트캠프(Java)

자바/스프링 개발 부트캠프 6일차(클래스)

동곤일상 2025. 2. 7. 17:39
반응형

6장-클래스.pdf
0.53MB

 

클래스

 

 

package ex1_field;


public class Car {
	String color;
	int num;//인스턴스변수
	
	static int width = 200; //클래스변수
	static int height = 120;
	
	
	//toString 오버라이딩
	//객체를 문자열로 표현하기위한 메서드
	//참조변수명만 출력하면 자동으로호출 됨
	//구현하지않는다면 참조값이 출력될 것.
	@Override
	public String toString() {
		return color+":"+num+"("+width+","+height+")";}
	
	
}

 

Car class 사용해보자

package ex1_field;

public class Main1 {

	public static void main(String[] args) {
		System.out.println("자동차의크기 : "+Car.width+","+Car.height);
//		System.out.println("자동차의 색상 : "+Car.color);
		//color는 인스턴스변수이므로 객체화 필요
		
		//car1,car2 : main메서드에서 선언됨 (지역변수)
		Car car1 = new Car();
		car1.color = "blue";
		car1.num = 4245;		
		System.out.println(car1);
		
		Car car2 = new Car();
		car2.color = "White";
		car2.num = 3242;		
		System.out.println(car2);
		
		car1.width = 80; 
		//클래스변수를 바꾸면 참조에상관없이 클래스 정보가바뀜
		//car1 , car2 의 모든 클래스 변수가 바뀜
		//car1 객체가 static 변수를 가지고 있지 않기때문!
		//static변수는 힙영역(객체인스턴스의 위치)
		//           이 아닌 static 영역에서 따로 관리
		car1.height = 50;
		
		Car.height = 100;Car.width=60;
		//이렇게 클래스에 직접접근하는걸 권장
		
		System.out.println(car1);
		System.out.println(car2);
		
		//객체의 주소값
		System.out.println(Integer.toHexString(car1.hashCode()));
		System.out.println(Integer.toHexString(car2.hashCode()));

	}
}


자동차의크기 : 200,120
blue:4245(200,120)
White:3242(200,120)
blue:4245(60,100)
White:3242(60,100)
7cca494b
7ba4f24f

 


지역변수 관련 코드

package ex1_field;

/*
 * 지역변수는 반드시 초기화되어야함
 * 매개변수는 지역변수임
 */
public class Main2 {
	public static void main(String[] args) {
		int num;
		//		System.out.println(num);//지역변수num은 초기화해야함

		boolean b = true;
		if(b) {num=100;}
		//		System.out.println(num);초기화 되지 않을 가능성 있으므로 오류


		if(b) { num=100; }
		else {num=20;}
		System.out.println("num : "+num);

		String grade=null;
		int score=80;

		if(score>=90) {
			grade = "A";
		}
		else if(score >=80) {
			grade = "B";
		}
		else if(score >=70) {
			grade = "C";}
		System.out.println(grade+"학점");

		/* 해결법 1) grade를 초기화한다(null)
		 *   	2) else문을 추가한다
		 */

		switch(score/10) {
		case 9-> grade="A";
		case 8-> grade="B";
		case 7-> grade="C";
		default-> grade="F";
		}System.out.println(grade+"학점");
	}
}

static변수 (클래스변수) 에 대해

 

클래스변수 와 인스턴스변수는 초기화를 하지않아도

자동으로 기본값으로 초기화 

package ex1_field;
/*
 * 클래스변수사용 예제
 */
public class Car2 {
	String color; //색상 , 인스턴스변수 .null로 초기화
	int num;  // 번호 , 인스턴스변수  ,  0으로초기화
	int sno;  // 생성번호 , 인스턴스변수 ,  0으로초기화 
	static int cnt; // 생산 수 , 클래스변수 ,  0으로초기화
	
	
	public String toString() {
		return "자동차번호 :"+sno+"=>"+color+" , "+num+
				", 자동차 생산갯수 : "+cnt;	
	}
}

 

static int cnt 는 객체화와는 아무런관련이없고
오직 클래스에만 관련. 
객체를 10개를 만들어 서로 다른 필드(인스턴스변수)값을 할당받아도

클래스 변수값은 모든 객체가 동일

package ex1_field;


public class Main3_StaticVal {
	public static void main(String[] args) {
		

		                       //Car2.cnt : 0 
		System.out.println("Car2.cnt : "+Car2.cnt);
		Car2 car1 = new Car2();
		car1.color="White";
		car1.num = 1234;
		car1.sno = ++Car2.cnt; //Car2.cnt : 1
		//cae1.sno = 1
		System.out.println("++Car2.cnt");
		System.out.println(car1);
		
		Car2 car2 = new Car2();
		car2.color="Black";
		car2.num = 5678;
		car2.sno = ++Car2.cnt; //Car2.cnt :2  (클래스변수)
		//car2.sno = 2;
		System.out.println("++Car2.cnt");
		System.out.println(car1);
		System.out.println(car2);
	}
}

Car2.cnt : 0

++Car2.cnt

자동차번호 :1=>White , 1234, 자동차 생산갯수 : 1

++Car2.cnt

자동차번호 :1=>White , 1234, 자동차 생산갯수 : 2

자동차번호 :2=>Black , 5678, 자동차 생산갯수 : 2

 

 


응용 예제

package ex1_field.exam;

class Rectangle {

	public int width;
	int height;
	int sno;
	static int cnt;
	
	public String toString() {
		return sno+"번 사각형 : 가로("+width+"), 세로("+height+"),"
				+ "현재까지 생성된 사각형 ("+cnt+")";
	}
}

public class Exam1 {
	public static void main(String[] args) {
		System.out.println("Rectangle.cnt : "+Rectangle.cnt);
		Rectangle r1 = new Rectangle();
		r1.width = 10;
		r1.height = 20;
		
		r1.sno = ++Rectangle.cnt;
		System.out.println("++Rectangle.cnt : "+Rectangle.cnt);
		System.out.println(r1);
		
		Rectangle r2 = new Rectangle();
		r2.width = 10;
		r2.height = 20;
		
		r2.sno = ++Rectangle.cnt;
		System.out.println("++Rectangle.cnt : "+Rectangle.cnt);
		System.out.println(r2);
	}
}

Rectangle.cnt : 0

++Rectangle.cnt : 1

1번 사각형 : 가로(10), 세로(20),현재까지 생성된 사각형 (1)

++Rectangle.cnt : 2

2번 사각형 : 가로(10), 세로(20),현재까지 생성된 사각형 (2)


멤버 메서드(함수)

구성요소                                                         

선언부 [접근제어자][제어자] 리턴타입 메서드이름 (매개변수)
ex) public static int Adder(int a , int b) 
구현부
(알고리즘 구성)
{ ... return 값; }  : 

 

* 리턴타입 : 메서드 종료 후 전달되는 값의 자료형 

                    void : 리턴값X(전달값X)

 

* 메서드이름 : 식별자

 

* 매개변수목록 : 메서드호출 시 메서드에 전달될 값의

자료형과 변수명 설정  .전달값이 없는경우 ( ) 표현

 

 

* return : 메서드종료

return값
void return값 생략  메서드의마지막블록이 끝나면
메서드종료인식
void  X return값 생략 X
(return 리턴값 ; )
 return값의 자료형은 리턴타입과 같거나
자동형변환 되어야함

 


메서드 예

 

package ex2_Method;
public class Adder {
	// int값 2개 입력받아 int값 return하는메서드
	int add1(int a, int b) {
		return a+b; //리턴값과 리턴타입의 자료형동일
	}
	
	// int값 2개 입력받아 long값 return하는메서드
	long add2(int a, int b) {
		return a+b; //리턴값을 리턴타입으로 자동형변환 가능
	}

	// int값 2개 입력받아 화면에출력하는 메서드(리턴없이)
	void add3(int a, int b) {
		System.out.println("a+b : "+a+b);//return 생략
		return; // 사용해도 무관
	}
}

 

사용 예

package ex2_Method;

public class AdderMain1 {
	public static void main(String[] args) {
		Adder a1 = new Adder();
		
		int add1 = a1.add1(1, 2);
		//선언부에 맞는 변수로반환
		//(자동형변환이 가능한 변수는 사용가능) byte short
		
		float add2 = a1.add2(44, 23);
		//선언부 타입에 맞지않는 변수 넣기도 금지
		//float , double 등으로  반환 가능(자동형변환가능)
	
		System.out.println(add1);
		System.out.println(add2);
		a1.add3(78, 424);
	}
  }

3

67.0

a+b : 78424


메서드를 이용한 예제

다음코드로

1번사각형(30,20) 생성된 사각형갯수 : 1 =>
//면적600 , 둘레 100, 직사각형 와 같은 출력이 나오게 하시오

public class Exam1 {
	public static void main(String[] args) {
		Rectangle r1 = new Rectangle();
		r1.width = 30;
		r1.height = 20;
		r1.serialNo = ++Rectangle.cnt;
		System.out.println(r1);
		
	}
}

 

만든 Rectancle

class Rectangle{

	public static int cnt;
	public int width;
	public int height;
	public int serialNo;
	
	int Area() {
		return width*height;
	}
	int length() {
		return 2*(width+height);
	}
	boolean isSquare() {
		return (width==height);
	}
	
	public String toString() {
		return serialNo+"번 사각형("+width+","+height+")"
				+ " 생성 사각형 갯수 : "+cnt+"==>"+
				"\n면적 : "+Area()+" 둘레 : "+length()+
				(isSquare()?" 정사각형":" 직사각형");
	}
}

마지막 isSquare() 는 boolean형 메서드이므로

true면 정사각형 , false면 직사각형을 출력하게

삼항연산자 사용

 

출력

1번 사각형(30,20) 생성 사각형 갯수 : 1==>

면적 : 600 둘레 : 100 직사각형

 


클래스를 배열로 사용해보기

Rectangle[] a = new Rectangle[5];

 

생성자를 이용한다면 배열말고 List 등을 사용할 수 있긴 함

package ex2_Method.exam;

import java.util.ArrayList;
import java.util.Arrays;

/*
 * Rectangle클래스이용해 20~50 사이의 임의의 가로 세로 길이를 가진 사각형5개생성
 * 사각형정보출력
 * 전체사각형의면적의합과 둘레의합 출력
 */
public class Exam2 {
	public static void main(String[] args) {

		Rectangle[] a = new Rectangle[5];
		//Rectangle의 참조값만 생성하는것임.
		//a[0] : Rectangle 형의 참조변수 (Rectangle객체 아님)
		//쉽게말해서 Rectangle이 들어갈 자리를 만들어주는거 
		
		
		System.out.println("모두 null값이 들어가 있다.");
		for (Rectangle rectangle : a) {
			System.out.print(rectangle+",");
		}System.out.println();
		
		
		
		int areaSum = 0;
		int lengthSum = 0;
		for (int i = 0; i < a.length; i++) {
			
			a[i] = new Rectangle();//객체생성
			a[i].serialNo = ++Rectangle.cnt; 
			//총 사각형갯수를 올려주고 그 번호를 no에 할당
			
			a[i].width= (int)(Math.random()*31)+20;//20~50사이랜덤
			a[i].height = (int)(Math.random()*31)+20;
			
			areaSum+=a[i].Area();//면적 저장
			lengthSum+=a[i].length();//둘레 저장
			
			System.out.println(a[i]); //사각형정보
			System.out.println();
		}
		System.out.println(" 면적 : "+areaSum);
		System.out.println("면적(평균) : "+(double)areaSum/a.length);
		System.out.println(" 둘레 : "+lengthSum);
		System.out.println("둘레(평균) : "+(double)lengthSum/a.length);
		
		System.out.println("참조값");
		for (Rectangle r : a) {
			System.out.print(Integer.toHexString(r.hashCode())+" ,");
		}
	}
} 

모두 null값이 들어가 있다.

null,null,null,null,null,

 

1번 사각형(36,20) 생성 사각형 갯수 : 1==>

면적 : 720 둘레 : 112 직사각형

 

2번 사각형(36,41) 생성 사각형 갯수 : 2==>

면적 : 1476 둘레 : 154 직사각형

 

3번 사각형(31,35) 생성 사각형 갯수 : 3==>

면적 : 1085 둘레 : 132 직사각형

 

4번 사각형(38,46) 생성 사각형 갯수 : 4==>

면적 : 1748 둘레 : 168 직사각형

 

5번 사각형(22,43) 생성 사각형 갯수 : 5==>

면적 : 946 둘레 : 130 직사각형

 

면적 : 5975

면적(평균) : 1195.0

둘레 : 696

둘레(평균) : 139.2

참조값

15aeb7ab ,7b23ec81 ,6acbcfc0 ,5f184fc6 ,3feba861 ,

 

 


매개변수 예제

package ex3_method;
/*
 * 매개변수 예제
 */
class Value{
	int val;
}

public class ParameterEx1 {
	public static void main(String[] args) {
		Value v = new Value();
		v.val = 100;
		System.out.println("원본 : "+v.val+"\n");
		change1(v.val);
		System.out.println("change1 이후 : "+v.val);
		System.out.println();
		change2(v);
		System.out.println("change2 이후 : "+v.val);
		
	}
    //기본형매개변수
	private static void change1(int val) {
		val +=100;
		System.out.println("change1() : "+val);
	}
    //호출 후 사라짐 단순히 값만 받으므로
	//종료와동시에 사라지는메서드
	
    
    //참조형 매개변수
	private static void change2(Value v) {
		v.val +=200;
		System.out.println("change2() : "+v.val);
	}
    //이 메서드는 참조값을 받으므로
	//v 인스턴스를 참조하고있음.
	//여기서의 값 변경은 인스턴스값 자체를 바꾸는것임

}

원본 : 100

 

change1() : 200

change1 이후 : 100  // 값이 왜 똑같은지 생각해보자

 

change2() : 300

change2 이후 : 300


 

클래스 변수 클래스변수(static) 클래스변수 , 클래스메서드 : 
클래스멤버 (클래스명.멤버명)         static
--> 클래스 정보 로드
                       x
                       
(호출 가능)    ↓(호출불가능(객체화 시 가능))
↑                         
                       x
인스턴스변수 , 인스턴스메서드 :
인스턴스멤버(참조변수.멤버명)
--> 객체화 시
인스턴스변수
메서드 클래스 메서드(static)
인스턴스메서드

호출 예시

package ex3_method;

public class MemberCallEx1 {
	static int cv1 = 10;
	static int cv2 = cv1; //클래스멤버간 호출
	
	int iv1 = 100;
	int iv2 = iv1;
	int iv3 = cv1; //인스턴스멤버에서 클래스(static)멤버 값 호출한것.(가능)
	
	static int cv3 = new MemberCallEx1().iv1;
	void method1() {
		System.out.println("method1(instanceMember)");
		System.out.println("cv1 +cv2 : "+(cv1+cv2));//클래스멤버
		System.out.println("iv1 +iv2 : "+(iv1+iv2));//클래스멤버
	}
	
	static void method2() {
		System.out.println("method2(classMember)");
		MemberCallEx1 a = new MemberCallEx1();//객체화
		System.out.println("cv1 +cv2 : "+(cv1+cv2));//클래스멤버간 호출
		System.out.println("iv1 +iv2 : "+(a.iv1+a.iv2));
//		System.out.println("iv1 +iv2 : "+(iv1+iv2)); 객체화가 되어야 호출가능
	}
	
	void method3() { 
		System.out.println("@@method3(InstanceMember@@)");
		method1();method2();
	}
	
	static void method4() {
		System.out.println("@@method4(ClassMemeber@@)");
		new MemberCallEx1().method1(); //객체화
		method2();
	}
	
	public static void main(String[] args) {
		MemberCallEx1 m = new MemberCallEx1();
		m.method1();
		/* MemberCallEx1. */method2(); 
		//main함수와 같은 멤버(static)이므로 생략가능
		m.method3();
		MemberCallEx1.method4();
	}
}

method1(instanceMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

method2(classMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

@@method3(InstanceMember@@)

method1(instanceMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

method2(classMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

@@method4(ClassMemeber@@)

method1(instanceMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

method2(classMember)

cv1 +cv2 : 20

iv1 +iv2 : 200

 

 

클래스멤버(static)호출법 : 

MemberCallEx1.method2();

클래스명.클래스멤버명 

/* MemberCallEx1. */method2();

//main함수와 같은 멤버(static)이므로 생략가능

 

 

인스턴스멤버호출법 

MemberCallEx1 m = new MemberCallEx1();

m.method1();

참조변수.메서드명

 


메서드 오버로딩 ( 메서드의 다형성 ) 

같은이름을 사용해 메서드를 정의 하는 것

 

조건

1) 매개변수의 타입 or 갯수 or 순서가 달라야함

2)메서드의 이름이 같아야함

3) 리턴타입 , 접근제어자는 조건에 포함X

 

 


예시코드

 

package ex4_Overloading;


class Adder{
	int a = 100;
	int add(int b) {
		System.out.print("1:");
		return a+b;
	}
	double add(double b) { //위에 메서드 오버로딩
						//매개변수 만 다름
		System.out.print("2:");
		return a+b;
	}
	String add(String b) {
		System.out.print("3: ");
		return a+b;
	}
}
public class OverloadingEx1 {
	public static void main(String[] args) {
		Adder a = new Adder();
		System.out.println(a.add(10));
		System.out.println(a.add('A'));  //(double)a.add('A')도 가능
		//char은 int로 자동형변환가능
        
		System.out.println(a.add(8.5));
		System.out.println(a.add("!!!!"));
		System.out.println(a.add(100L));
		
		//double add 에 들어감
		//long은 double로 자동형변환 가능!
	}
}

1:110

1:165

2:108.5

3: 100!!!!

2:200.0


오버로딩메서드의 선택기준

1.호출되는 인자값의 자료형 == 메서드에선언된 매개변수의 자료형

 

 2.

1의조건이없는경우

* 최소갯수로 자동형변환이 가능한 메서드 선택.

* (주의사항)=> 동일조건 메서드가 여러개인경우는 오류발생

 

package ex4_Overloading;
class Adder2{
	int add(int a, int b) {
		System.out.print("1 : ");
		return a+b;
	}
	long add(long a, int b) {
		System.out.print("2 : ");
		return a+b;
	}
	long add(int a, long b) {
		System.out.print("3 : ");
		return a+b;
	}
	
	long add(long a, long b) {
		System.out.print("4 : ");
		return a+b;
	}
}
public class OverloadingEx2 {
	public static void main(String[] args) {
		Adder2 adder2 = new Adder2();
		
		System.out.println(adder2.add(10, 10));
		//int int (1) 만약에int int매개변수를 가진 메서드가없다면
		//만들거나 자동형변환이 되더라도 앞에 타입을 붙여주자
		
		System.out.println(adder2.add(10, 10L));
		//int long (2)
		System.out.println(adder2.add(10L, 10));
		//long int (3)
		System.out.println(adder2.add(10L, 10L));
		// long long (4)
		System.out.println(adder2.add('A', '0'));
		//int가 가장 가까움
		
	}

}

1 : 20

3 : 20

2 : 20

4 : 20

1 : 113

 


test (1).zip
0.00MB

 

오늘의 예제

 

 

살짝 헤맸던거만 풀이해보겠음

 

 

 


3. 동전을 표현하는 Coin 클래스 구현하기
      멤버변수 :  동전의 면(side)
      멤버메서드 : flip() 
           기능 : 동전을 던져 동전의 면을 변경한다. Math.random() 메서드 이용. 
                 앞면,뒷면 출력함. 

package test;

import java.util.Random;

class Coin{
	int side;
	
	void flip() {
		side = (int)(Math.random()*2); 
		//  0<= Matn.random() < 1
		//  0<= Math.random()*2 < 2  -----> int로 바꾸면 0 or 1 라는 뜻
		
//		new Random().nextInt(1);이거와 같은 뜻
	}
	boolean isSquare() {
		return side==0?true : false; //side가 0이면 true
	}
	String getSide() {
		return side==0?"앞":"뒤"; //앞 뒤 반환
	}
	
}
public class Test3 {
	public static void main(String[] args) {
		Coin coin = new Coin();
		System.out.println(coin.side==0?"앞면":"뒷면");
		coin.flip();
		System.out.println(coin.side==0?"앞면":"뒷면");
	}
}

 

 

isSquare 과 getSide() 는 Test6번에서 사용할려고 만들었다

 

 


 

Test6

 

 


 Test3의 Coin 클래스를 이용하기 
 두개의 Coin 객체를 생성하기 myCoin, youCoin 객체 생성하기
 앞면이 연속해서 3번 나오면 승리가 출력되도록 구동 클래스 구현하기   

 [결과예시] => 결과는 다를 수 있습니다.
 myCoin youCoin
  앞면 뒷면
  뒷면 앞면
  앞면 앞면
  앞면 앞면
 youCoin 승리

class Coin{
	int side;
	
	void flip() {
		side = (int)(Math.random()*2); 
		//  0<= Matn.random() < 1
		//  0<= Math.random()*2 < 2  -----> int로 바꾸면 0 or 1 라는 뜻
		
//		new Random().nextInt(1);이거와 같은 뜻
	}
	boolean isSquare() {
		return side==0?true : false; //side가 0이면 true
	}
	String getSide() {
		return side==0?"앞":"뒤"; //앞 뒤 반환
	}
}

 

package test;

public class Test6 {
	public static void main(String[] args) {
		Coin myCoin = new Coin();
		Coin youCoin = new Coin();
		
		int myCount =0;
		int youCount =0;
		
		System.out.println("myCoin  youCoin");
		while(myCount<3 && youCount<3) {
			myCoin.flip();
			youCoin.flip();
			
			System.out.println(myCoin.getSide()+"\t "+youCoin.getSide());
			
			myCount = myCoin.isSquare()? myCount+1 : 0;
			youCount = youCoin.isSquare()? youCount+1 : 0;
			
			if(myCount==3) {
				System.out.println("myCoin 승리");
				break;
			}
			else if(myCount==3 && youCount==3){
				System.out.println("동점");
			}
			else if(youCount==3) {
				System.out.println("youCoin 승리");
			}
			
		}
	}
}

 

앞면 연속 3번을  배열로 통해 만들다가 도저히 안될 것같아서

구글링좀해서 찾았더니

boolean 함수를 이용해서 하면 깔끔하게 나올 수 있을 것 같았다/

 

일단 두 객체를 만들고

 

count 변수를 2개만든다 (myCount , youCount)

 

 

count가 두개 모두 3보다 작은 동안  while문 설정

그리고 flip으로 두 객체 모두 동전을 던져준다

 

getside 메서드를 통해 숫자 0 1 을 앞면 뒷면으로 출력을 해주고

 

boolean isSquare 함수를 이용해  참(앞면)이면 count = count+1

                                                       거짓(뒷면)이면 count=0

으로 만드는 삼항연산자를 만들고

 

누구하나라도 count가 3이되면 break;