Language

언어 수업자료/자바

JAVA 25-02 방특

초코렛맛 2025. 2. 14. 13:03

수업자료실

 

 

 

■ 2월 14일 - 1일차

file -> New Java Project
Project name 작성
New module-info = Don't Create

Java Main Class 작성
New Java Class
package 확인
Name에 작성 첫자는 대문자를 추천
public static void main(String[] args) 확인

크기변경 Ctrl + +,-(숫자옆의 +-)
한줄복제 Ctrl + Alt + 방향키

 


프로그램 기본 구조및 주석과 실행문

프로그램 기본구조

  • JDK (Java Development Kit) : 자바 개발도구

자바언어를 활용하여 작성할 수 있도록 넣어주는 형태

 

  • JVM (Java Virture Machine) : 자바가상 머신

운영체제마다 따로 코드를 작성할 필요없이
자바가 플랫폼에 독립적으로 사용할수 있도록 도와준다.

 

자바 프로그램의 기본구조

  • 소스파일

패키지 안에서 클래스를 담는 그릇 같은 형태 .java

 

  • 클래스

프로그램을 개발하는 단위
하나이상의 클래스가 있어야 하며
소스파일의 이름이 클래스 대표 이름과 동일해야함

 

  • 매서드

수행할 작업을 나열한 코드의 모임
Main() 메서드는 자바프로그램의 시작위치로
반드시 필요함

 

  • 실행문

작업을 지시하는 것으로 변수나 상수의 선언
값 저장, 메서드 호출 등 다양한 명령어와 연산자로 구성됨

 

  • 주석

코드에 설명이나 필요한 정보를 기록한 것
컴파일되지 않아 프로그램 실행에는 아무 영향없음
복잡한 코드를 이해하기 쉽고
다른개발자가 코드를 해석하는 데 도움이 됨

기호구분설명

// 행주석 //부터 그줄의 끝까지 주석처리 주석내용이 1줄일때사용
/* * / 범위주석 사이의 내용 모두를 주석처리함
	/*오늘수업
	 * 프로그램 구조설명
	 * 변수와 자료형
	 * 연산자
	 */
	
	// 여기 다음부터 시행



실행문

실행문 끝에는 반드시 세미콜론(;)을 넣어주어야
실행문의 종료를 알려줄수 있다.

한줄에 여러개의 실행문 작성

a = 1; b = 2;

 

한줄에 하나의 실행문작성

a = 1;
b = 2;

 

하나의 실행문을 여러줄로 작성

a =
1;
b =
2;

 

예제1. 본인의 이름 출력 및 범위 주석으로 작성자와 날짜 추가




변수와 자료형

데이터

 

출력문

데이터를 화면에 출력할때 사용하는 실행문

System.out.print() : 괄호안에 내용을 출력 (문자열로 인식)
System.out.println() : 괄호안에 내용을 출력하고 행을 변경 (문자열로 인식)
System.out.printf() : 문자열을 서식 문자를 이용하여 형식화된 내용으로 출력

syso Ctrl + Space로 입력가능 println()이 기본

 

Print() 출력문

한줄에 Welcomejava가 출력됨

	public static void main(String[] args) {
		System.out.print("Welcome"); //
		System.out.print("java");
	}

 

Println() 출력문

한줄 띄어서 출력됨

	public static void main(String[] args) {
		System.out.println("Welcome"); //
		System.out.println("java");
	}

 

Printf() 출력문

서식문자를 이용하여 출력한다.

서식문자출력형태

%d 정수(10진수)
%o 정수(8진수)
%x 정수(16진수)
%f 실수
%e 지수(e표기 기반)
%g %e또는 %f형태로 출력(대상에 맞게)
%s 문자열
%c 문자

\n = 한줄띄기

 

서식 문자를 이용한 출력 1

	public static void main(String[] args) {
		System.out.printf("저는 대학교 %d학년 입니다\n",2);
		System.out.printf("저는 %s%c 학생 입니다.\n","서울",'대'); //문자열 " ", 문자 ' '
		System.out.printf("정수 %d와 실수 %f와 문자열 %s\n",2,3.14,"100");
		

	}

// 출력 //

저는 대학교 2학년 입니다
저는 서울대 학생 입니다.
정수 2와 실수 3.140000와 문자열 100

 

 

간단한 출력

단축키 syso Ctrl + space

int a = 10;
System.out.println(a);


주요단축키

Ctrl + Z : 전으로 돌리기
Ctrl + Y : 후로 돌리기
Ctrl + S : 저장

Alt + 방향키 : 줄 바꾸기
Ctrl + D : 줄 지우기
Ctrl + / : 주석처리
Alt + Ctrl + 방향키 : 줄 복사

상수 선언

final 데이터타입 상수명 = 값;

final int a = 10;
a = 11; // 에러발생 상수는 변경 불가능
System.out.println(a);


변수 및 상수의 초기화 에러

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		final int abc;
		// System.out.println(abc); // 에러발생 초기화(initialize) 에러
		abc = 120;
		System.out.println(abc);

	}
	
}

// 출력 //

120


2,8,16진수, long, float 표현

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 010; // 8진수
		System.out.println(a);
		
		int b = 0x10; //16진수 대소문자 같이 써도됨
		System.out.println(b);
		
		int c = 0b10; //2진수 대소문자 같이 써도됨
		System.out.println(c);
		
		// long d = 3000000000; // 표현 에러
		long d = 3000000000l; // 대소문자 상관없음 숫자1과 혼동될수 있으니 대문자 추천
		System.out.println(d);
		long d2 = 4_000_000_000l; // _로 회계형식으로 사용가능
		System.out.println(d2);
		int d3 = 1_000_000; // int형도 가능
		// int d4 = 10l; //에러 long 리터럴을 int에 저장불가
		// int d4 = (int)10l; // 사용가능
		System.out.println(d3);
		
		// float e = 1.1; //double 리터럴은 자신보다 작은 float에 저장불가
		// float e = (float)1.1; // 사용가능
		float e = 1.1f;
		// e = 1.2; // 에러 double 리터럴을 사용하는 것으로 넣을수 없음
		System.out.println(e);
		
		double f = 3.14d; // d를 사용안해도 상관없음
		f = 3.16;
		System.out.println(f);

	}
	
}

// 출력 //

8
16
2
3000000000
4000000000
1000000
1.1
3.16


10. 과 .10 1e3의 의미

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		System.out.println(10.);
		System.out.println(.10);
		System.out.println(1e1);
		System.out.println(1e3);
		
		float a = 1e3f;
		System.out.println(a);
		

	}
	
}

// 출력 //

10.0
0.1
10.0
1000.0
1000.0


변수의 값 교환

두개의 변수의 값이 a = 1, b = 20 일때 두값을 변환시키는 방법

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 1;
		int b = 20;
		System.out.println("a="+a);
		System.out.println("b="+b);
		System.out.println();
		
		a = b; //변수a에 변수 b의 값을 넣어라
		System.out.println("a="+a);
		System.out.println("b="+b);
		System.out.println();
		// 파이썬의 변수 값 교환 a,b = b,a
		
		a = 1;
		int temp = a;
		a = b;
		b = temp;
		System.out.println("a="+a);
		System.out.println("b="+b);
		

	}
	
}

// 출력 //

a=1
b=20

a=20
b=20

a=20
b=1

문자 작성

char c1 = 'a';
System.out.println(c1);
// char c2 = "a"; // 문자는 작은따옴표('')만 작성가능
// char c3 = 'hello'; //문자열은 사용할 수 없음
char c4 = '박';
System.out.println(c4);
// String s1 = 'g'; //문자열은 큰따옴표만("") 작성가능
// string s2 = "안녕"; // 문자열의 string에서 s는 대문자
String s3 = "안녕하세요";
System.out.println(s3);
String s4 = "김"; // 문자열에 1자 사용가능
System.out.println(s4);
// 출력 //

a
박
안녕하세요
김


다양한 출력방법1

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 1000;
		System.out.println("a의 값은 : " + a);
		int c = 10;
		int d = 11;
		System.out.println("cd : " + c + d);
		System.out.println("cd : " + (int)c + (int)d);
		System.out.println("c+d : " + (int)(c+d));
		System.out.println("c+d : " + (c+d));
		float f1 = 1.23f;
		float f2 = 1.4f;
		System.out.println("f1+f2 : " + f1 + f2);
		System.out.println("f1+f2 : " + (f1 + f2));

	}
	
}

// 출력 //

a의 값은 : 1000
cd : 1011
cd : 1011
c+d : 21
c+d : 21
f1+f2 : 1.231.4
f1+f2 : 2.63


다양한 출력방법2

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 1000;
		System.out.print(a); // 한줄 안띄고 작성됨
		float b = 1.2f; // float일때는 무조건 f를 작성
		double c = 1.2;
		System.out.println(b);
		System.out.println(c);
		System.out.printf("%d, %f, %.1f \n",a,b,c);
		// printf에서는 %d 정수 %f 실수
		// %.1f 소수점1자리
		// %,d 회계식 천의자리 마다 콤마
		// \n을 해줘야 1줄을 띄어 준다
		char d = 'a';
		String e = "안녕";
		System.out.printf("%s, %s, %c, %s, %s \n",a,b,d,d,e);
		// %c는 문자 %s는 문자열
		// %s는 정수, 실수, 문자를 따지지 않고 출력
		int f = 65;
		System.out.printf("%c",f);
		// 65는 유니코드 문자 A를 뜻함 값을 벗어나면 문제 너무 크면 에러

	}
	
}

// 출력 //

10001.2
1.2
1000, 1.200000, 1.2 
1000, 1.2, a, a, 안녕 
A

다양한 출력방법3

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 123456;
		System.out.printf("[%5d]\n",a);
		System.out.printf("[%5d]%n", 10);
		System.out.printf("[%-5d]%n", 10);
		System.out.printf("[%,d]%n", 1000);
		
		System.out.printf("[%3s]%n",10000);
		System.out.printf("\"10\"\n");
		System.out.printf("%% %n");
		System.out.printf("(%d)",10);
		
		

	}
	
}

// 출력 //

[123456]
[   10]
[10   ]
[1,000]
[10000]
"10"
% 
(10)


다양한 출력방법4

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		System.out.printf("[%2.2f]%n",101.2345);
		System.out.printf("[%2.5f]%n",101.2345);
		System.out.printf("[%10.2f]%n",101.2345);
		
		System.out.printf("[%c] %n", 'a');
		// System.out.printf("[%c]",'www.wiken.io/ken'); //에러
		System.out.printf("[%s] %n","www.wiken.io/ken");
		System.out.printf("[%3s] %n","www.wiken.io/ken");
		System.out.printf("[%30s] %n","www.wiken.io/ken");
		System.out.printf("[%-30s] %n","www.wiken.io/ken");
		System.out.printf("[%.5s] %n","www.wiken.io/ken");

	}
	
}

// 출력 //

[101.23]
[101.23450]
[    101.23]
[a] 
[www.wiken.io/ken] 
[www.wiken.io/ken] 
[              www.wiken.io/ken] 
[www.wiken.io/ken              ] 
[www.w]

boolean은 인트 타입 안됨

boolean a = true;
		
System.out.printf("%b",a);


입력

Scanner 변수 = new Scanner(System.in);
변수는 Scanner를 불러올때 사용할 이름
package 다음줄에
import java.util.Scanner;
또는 import java.util.* ;

  • 기본 세팅
package javapj;

import java.util.*;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		
	}
	
}

데이터형별 입력방법들

package javapj;

import java.util.*;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		int a = sc.nextInt();
		// int형으로 입력해서 int a에 저장
		double b = sc.nextDouble();
		// double형으로 입력해서 double b에 저장		
		char c = sc.next().charAt(0);
		// string으로 입력해서 index 0 번째 문자 char저장
		String d1 = sc.next(); // string으로 띄어 쓰기 전까지 저장
		String d2 = sc.nextLine(); // string으로 엔터까지 저장
		
		
	}
	
}

정수형 입력 방식

package javapj;

import java.util.*;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		int a1, a2;
		System.out.print("1번 정수를 입력하세요 >> ");
		// 입력시 띄어쓰기를 하면 두번째 것이 자동으로 저장됨
		a1 = sc.nextInt();
		System.out.print("2번 정수를 입력하세요 >> ");
		a2 = sc.nextInt();
		
		System.out.println(a1);
		System.out.println(a2);
		
	}
	
}

// 출력 // 한칸 띄어 써서 입력

1번 정수를 입력하세요 >> 5 10
2번 정수를 입력하세요 >> 5
10

// 출력 // 각각 엔터로 입력
1번 정수를 입력하세요 >> 5
2번 정수를 입력하세요 >> 10
5
10

띄어쓸때 문제

다음것에 입력했던 내용이 자동적으로 저장 되어서
문제가 발생될 수 있음

package javapj;

import java.util.*;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		String a1;
		System.out.print("1번 입력하세요 >> ");
		// 입력시 띄어쓰기를 하면 두번째 것이 자동으로 저장됨
		a1 = sc.next();
		
		int a2;
		System.out.print("2번 정수를 입력하세요 >> ");
		a2 = sc.nextInt();
		
		System.out.println(a1);
		System.out.println(a2);
		System.out.println(a1+a2);
		
	}
	
}

// 출력 //

1번 입력하세요 >> asd as
2번 정수를 입력하세요 >> Exception in thread "main" java.util.InputMismatchException
	at java.base/java.util.Scanner.throwFor(Scanner.java:943)
	at java.base/java.util.Scanner.next(Scanner.java:1598)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2263)
	at java.base/java.util.Scanner.nextInt(Scanner.java:2217)
	at javapj.K1.main(K1.java:18)

데이터형에 맞게 입력

package javapj;

import java.util.*;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		int a1 = sc.nextShort();
		int a2 = sc.nextByte();
		// int a3 = sc.nextLong(); // 문제 long에는 못넣음
		// long a4 = sc.nextFloat(); // long이 더 크지만 소수형이 넣을수 있는 범위가 커서 에러
		float f1 = sc.nextInt(); // 가능 인트형으로 입력해야 오류 없음.
		System.out.println(f1); // 인트1입력시 1.0으로 float형으로 저장

		
	}
	
}

 

연산자

특정한 연산을 수행하기 위해 사용하는 기호
연산 : 식이 나타낸 일정한 규칙에 따라 계산함

연산자의 종류 : 산술(사칙연산등), 단항(부호,부정,증감),
비교(양변 비교), 논리(참,거짓), 쉬프트, 기타

연산자 순위 1.최우선 2.단항 3.산술 4.쉬프트 5.비교 6.논리 7.삼항 8대입

산술 연산자

연산자의미사용방법

+ 더하기 c = a+b
- 빼기 c = a-b
* 곱하기 c = a * b
/ 나누기 c = a/b
% 나머지 c = a%b
  • 예시1
package javapj;

public class K2 {

	public static void main(String[] args) {
		
		int a = 10;
		int b = 3;
		
		System.out.println(a+b);
		System.out.println(a-b);
		System.out.println(a*b);
		System.out.println(a/b); // 정수만 표현
		System.out.println(a%b);  // 나머지만 표현
		System.out.println((float)a/b); // 나누기의 값을 표현시 실수형으로
        
	}

}

// 출력 //

13
7
30
3
1
3.3333333

  • 예시2
package javapj;

public class K2 {

	public static void main(String[] args) {
		
		int a = 10;
		int b = 3;
		int c1,c2,c3,c4,c5;
		c1 = a+b;
		c2 = a-b;
		c3 = a*b;
		c4 = a/b;
		c5 = a%b;
        System.out.println(c1);
		System.out.println(c2);
		System.out.println(c3);
		System.out.println(c4);
		System.out.println(c5);
        
	}

}

// 출력 //

13
7
30
3
1

  • 예시3
package javapj;

public class K2 {

	public static void main(String[] args) {
		
		int a = 10;
		int b = 3;
		float f1, f2;
		f1 = a/b;
		f2 = (float)a/(int)b;
		double d1, d2;
		d1 = (float)a/b;
		d2 = (double)a/b;
		
		System.out.println(f1);
		System.out.println(f2);
		System.out.println(d1);
		System.out.println(d2);
		

	}

}

// 출력 //

3.0
3.3333333
3.3333332538604736
3.3333333333333335


단항 연산자

연산자의미사용법설명

+,- 부호 연산자 -a 변수의 부호를 바꿈
! 부정 연산자 !a 논리의 부정
++ 증가 연산자 ++a, a++ 변수a에 1을 더하여 a에 저장
-- 감소 연산자 --a, a-- 변수a에 1을 빼서 a에 저장

부호연산자

int a = -1;
int b = 2;
System.out.println(a); // -1
System.out.println(-b); // -2

논리부정연산자

boolean a = true;
boolean b = false;
System.out.println(!a); // false
System.out.println(!b); // true

증감연산자

전위 ++a(변수가 사용되기 전에 증가), 후위 a++(변수가 사용한 후에 값이 증가)
a++ == a = a+1

package javapj;

public class K2 {

	public static void main(String[] args) {
		
		int a = 1;
		System.out.println(a);
		a++;
		System.out.println(a);
		++a;
		System.out.println(a);
		
		System.out.println();
		
		System.out.println(a++);
		System.out.println(++a);
		
		System.out.println();
		
		System.out.println(a--);
		System.out.println(--a);

	}

}

// 출력 //

1
2
3

3
5

5
3

 


대입 연산자

연산자예설명풀어쓴 형식

= a=1 a에 1을 저장 a=1
+= a+=2 a에 a더하기 2를 저장 a = a + 2
-= a-=3 a에 a빼기 3을 저장 a = a - 3
* = a*=4 a에 a 곱하기 4를 저장 a = a * 4
/= a/=5 a에 a 나누기 5의 몫을 저장 a = a / 5
%= a%=6 a에 a 나누기 6의 나머지 a = a % 6
package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 3;
		int b = 6;
		
		a+=1; // 3+1 = 4
		System.out.println("a : "+a);
		
		a/=2; // 4/2 = 2
		System.out.println("a : "+a);
		
		b*=a; // 6*2 = 12
		System.out.println("a : "+a+", b : "+b);
		
		a*=++a; // 2 * ++2 ->  2*3=6  // a++는 2*2 = 4
		System.out.println("a : "+a);

	}
	
}

// 출력 //

a : 4
a : 2
a : 2, b : 12
a : 6

 

 

비교 연산자

둘을 비교하여 맞으면(true) 틀리면(false)

종류연산자사용법설명

같다 == a==b a와 b가 같다.
작다 < a<b a가 b보다 작다
작거나 같다 <= a<=b a가 b보다 작거나 같다.
크다 > a>b a가 b보다 크다
크거나 같다 >= a>=b a가 b보다 크거나 같다
같지 않다 != a!= a와 b가 같지 않다.
  • 예시1
package javapj;

public class K1 {

	public static void main(String[] args) {
		
		System.out.println(10>11);
		int a = 1;
		int b = 2;
		System.out.println("a<b = "+(a<b));
		System.out.println(a+"<"+b+" = "+(a<b));
		
		System.out.println("a<=b = "+(a<=b));
		System.out.println(10>=10);
		
	}
	
}

// 출력 //

false
a<b = true
1<2 = true
a<=b = true
true
  • 예시 2
package javapj;

public class K1 {

	public static void main(String[] args) {
		
		double a = 1.23;
		double b = 1.23f;
		
		System.out.println(a==b);
		System.out.println("a = " + a);
		System.out.println("b = " +b);
		
		b = 2.25;
		
		System.out.println(a!=b);
		System.out.println((a!=b)+"\n"); //%n은 printf에서 사용
		
		char c = 'A';
		int d = 65; // A가 유니코드 65번이기때문에 같음
		
		System.out.println(c==d);
		System.out.println(c=='a'); 
		System.out.println(97=='a'); 
		
	}
	
}

// 출력 //

false
a = 1.23
b = 1.2300000190734863
true
true

true
false
true
  • 예시 3
package javapj;

public class K1 {

	public static void main(String[] args) {
		
		String a = "hello java"; // string은 원시자료형이 아님 하나의 객체임
		String a1 = "hello java";
		String a2 = new String("hello java");
		
		System.out.println(a==a1); // 객체가 같은지 확인
		System.out.println(a==a2); // 새로운 객체로서 내용은 같지만 객체가 다름 차후교육
		
		System.out.println();
		
		System.out.println(a.equals("Hello java"));
		System.out.println(a.equals("hello java"));
		System.out.println(a.equals(a2)); // 내용이 같기 때문에 true
		
		char b = 'c';
		// System.out.println(b.equals('c')); // 에러 string개열에서 사용
		
	}
	
}

// 출력 //

true
false

false
true
true



논리연산자

종류연산자사용예설명

AND && a&&b a 그리고 b가 참이면 참
OR ll allb a 또는 b가 참이면 참
NOT ! !a a가 거짓이면 참, 참이면 거짓

aballba&&b

거짓 거짓
거짓 거짓
거짓 거짓 거짓 거짓
  • 예시 1
package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int a = 10;
		
		System.out.println((a>5)&&(a<15)); // 5 < a < 20 (6~19사이)
		System.out.println((a>5)||(a<15)); // 5보다 크다 또는 15보다 작다 모든수
		System.out.println();
		
		System.out.println((a>5)&&(a>15)); // 15보다 큰수
		System.out.println((a>5)||(a>15)); // 5보다 큰수
		System.out.println();
		
		System.out.println((a<5)&&(a<15)); // 5보다 작은수
		System.out.println((a<5)||(a<15)); // 15보다 작은수
		System.out.println();
		
		System.out.println((a<5)&&(a>15)); // 5보다 작거나 15보다 크다 (없음)
		System.out.println((a<5)||(a>15)); // 5보다 작다 또는 15보다 크다(6~19)를 제외한 숫자
		
		
	}
	
}

// 출력 //

true
true

false
true

false
true

false
false


기타연산자

삼항연산자

조건 ? 항목1:항목2
조건이 참이면 항목1, 거짓이면 항목2

package javapj;

public class K1 {

	public static void main(String[] args) {
		
		int age = 17;
		String a = "성인 입니다.";
		String b = "청소년 입니다.";
		
		System.out.println(age>19? "성인 입니다.":"청소년 입니다.");
		System.out.println(age>19? a:b); // 변수를 사용해도 됨

		
	}
	
}

// 출력 //

청소년 입니다.
청소년 입니다.


 

제어문

if문

if(조건식){
실행부분(조건이 참이면 실행)
}

if문 기본

		int a = 5;
		if(a>3) {
			System.out.println("a는 3보다 큼니다.");
		}
		System.out.println("검사가 끝났습니다.");

// 출력 //

a는 3보다 큼니다.
검사가 끝났습니다.


if문 실행부분이 한줄일 경우

실행부분이 한줄일 경우는 {} 안해도 됨

		int a = 5;
		if(a<3)
		System.out.println("a는 3보다 큼니다.");
		System.out.println("검사가 끝났습니다.");

// 출력 //

검사가 끝났습니다.

if문 입력받은 수의 음수 확인

scanner를 저장할때 계열에 맞게 사용

		Scanner sc = new Scanner(System.in);
		System.out.print("정수를 입력하세요 >> ");
		int a = sc.nextInt();
		
		if(a<0) {
			System.out.println("a는 음수입니다.");
		}
		System.out.println("종료");

// 출력 //

정수를 입력하세요 >> -5
a는 음수입니다.
종료


if - else

if(조건식){
실행부분(if의 조건이 참이면 실행)
}
else{
실행부분(if의 조건이 거짓이면 실행)
}

		Scanner sc = new Scanner(System.in);
		
		System.out.print("나이 입력 : ");
		int a = sc.nextInt();
		
		if (a>19) {
			System.out.println("성인입니다.");
		}
		else {
			System.out.println("청소년입니다.");
		}
		System.out.println("if문 종료");

// 출력 //

15
청소년입니다.
if문 종료

 

연령에 맞는 구분
120보다 크거나 0보다 작으면 오류
19보다 크면 성인
13보다 크면 청소년 (18~14)
6보다 크면 어린이 (13~7)
나머지는 유아

public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.print("입력 >> ");
		int a = sc.nextInt();
		
		String b = "";
		
		if(a>120 || a<0) { // a>19
			
			if(a>0) { //121 ~
				b = "양수 오류";
			}
			else {// 음수 
				b = "음수 오류";
			}
		}
		else if(a>19) { //20~ 120
			b = "성인";
		}
		else if(a>13) { // 14 ~ 19
			b = "청소년";
		}
		else if(a>6) {// 7 ~ 13
			b = "어린이";
		}
		else { // 6 ~ -
			b = "유아";
		}
		
		System.out.println("당신의 나이는 "+a+ "이고 "+b+"입니다.");
		
	}

// 출력 //

 

 

연습문제 1

입력한 값이
0보다 크거나 같으면 "양수"
0보다 작으면 "음수"를 출력

		Scanner sc = new Scanner(System.in);
		
		System.out.print("정수 입력 : ");
		int a = sc.nextInt();
		
		if (a>=0) {
			System.out.println("양수");
		}
		else {
			System.out.println("음수");
		}
		

// 출력 //

정수 입력 : 0
양수

연습문제 2

10보다 큰수이면 본인에 2를 나눈 나머지를 출력
10보다 작은수 이면 본인에 2를 곱한수 출력

		Scanner sc = new Scanner(System.in);
		
		System.out.print("정수 입력 : ");
		int a = sc.nextInt();
		
		if (a>10) {
			System.out.println(a%2);
		}
		else {
			System.out.println(a*2);
		}

// 출력 //
정수 입력 : 11
1
정수 입력 : 12
0

연습문제 3

0을 포함 짝수 이면 "짝수"
홀수 이면 "홀수" 출력
짝수의 정의 n = 2k 홀수의 정의 n = 2k+-1

		Scanner sc = new Scanner(System.in);
		
		System.out.print("정수 입력 : ");
		int a = sc.nextInt();
		
		if (a%2==0) {
			System.out.println("짝수");
		}
		else {
			System.out.println("홀수");
		}

// 출력 //

정수 입력 : -6
짝수

연습문제 4

if문 쓰고 밖에서 다시 if문 작성하기
m또는M을 입력하면 "남자" 출력
f또는F를 입력하면 "여자" 출력

char 이나 string 사용

문제풀기전 하나의 경우 확인

		Scanner sc = new Scanner(System.in);
		
		System.out.print("단어 입력 : ");
		String a = sc.next();
		String b = "a";
		System.out.println(b==a);
		System.out.println(b=="a");
		System.out.println(a.equals(b));

// 출력 //

단어 입력 : a
false
true
true

char

		System.out.print("단어 입력 : ");
		char a = sc.next().charAt(0);
		
		if (a=='m'||a=='M') {
			System.out.println("남자");
		}
		if (a=='f'||a=='F') {
			System.out.println("여자");
		}

// 출력 //

단어 입력 : fa
여자

String

a.equals()사용

		Scanner sc = new Scanner(System.in);
		
		System.out.print("단어 입력 : ");
		String a = sc.next();
		
		if (a.equals("m")||a.equals("M")) {
			System.out.println("남자");
		}
		if (a.equals("f")||a.equals("F")) {
			System.out.println("여자");
		}

// 출력 //

단어 입력 : m
남자

 

 

연습문제

printf 설명

		int a1= 10, a2 = 11;
		
		System.out.printf("%d + %d = %d", a1, a2, a1+a2);
        
// 출력 //

10 + 11 = 21  

입력한 정수가 99초과하면
"입력초과"
10이상이면
예) 13
"일의자리수 : 3, 십의자리수 : 1" 출력
10미만 0초과
예) 9
"일의자리수 : 9" 출력
0이면
"0" 출력
-1~-9이면
"-10초과 음수" 출력
아니면
"-10이하 음수" 출력

		Scanner sc = new Scanner(System.in);
		
		System.out.print("정수 입력 : ");
		int a = sc.nextInt();
		
		if (a>99) {
			System.out.println("입력초과");
		}
		else if (a>=10) {
			System.out.printf("일의자리수 : %d, 십의자리수: %d",a%10,a/10);
		}
		else if (a>0) {
			System.out.printf("일의자리수 : %d", a);
		}
		else if (a==0) {
			System.out.println("0");
		}
		else if (a>-10) {
			System.out.println("-10초과 음수");
		}
		else {
			System.out.println("-10이하 음수");
		}

// 출력 //

정수 입력 : 58
일의자리수 : 8, 십의자리수: 5
정수 입력 : 0
0
정수 입력 : 100
입력초과

 

 

연습문제

초를 입력받아 시간 분 초 로 넣어주기
3600 미만은 분 초로만 넣어주기

 

public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.print("입력 >> ");
		int a = sc.nextInt();	
		
		if (a>=3600) {
			System.out.println(a/3600+"시 "+a%3600/60+"분 "+a%60+"초");
		}
		else {
			System.out.println(a/60+"분 "+a%60+"초");
		}

	}

 

 

연습문제

세가지 수를 입력 받아서 가장 큰수 나오게 하기

 

public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.print("입력 >> ");
		int a = sc.nextInt();	
		int b = sc.nextInt();
		int c = sc.nextInt();
		
		
		if (a<b) {
			a = b;
		}
		if (a<c) {
			a = c;
		}
		System.out.println("가장 큰수는 " + a);

	}

 

 

연습문제 

점수를 입력받아
90 이상 A
80 이상 B
70 이상 C
60 이상 D
그 외 F
점수 : 85점 학점 : B입니다.

package javapj;

import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		System.out.print("점수 입력 >> ");
		int a = sc.nextInt();
		String g = "F";
		
		if (a>100) {
			a = 100; g = "A";
		}
		else if (a>=90) g = "A";
		else if (a>=80) g = "B";
		else if (a>=70) g = "C";
		else if (a>=60) g = "D";
		else if (a<=0) a = 0;
		
		System.out.printf("점수 : %d점 학점 : %s 입니다.",a,g);
		
	}

}


// 출력 //

점수 입력 >> 105
점수 : 100점 학점 : A 입니다.

 

연습문제

대전 일반 도시형 버스요금
만 19세 이상 카드 1,250원 현금 1,400원 (성인)
만 13 ~ 18세 카드 750원 현금 900원 (청소년)
만 6세 ~ 12세 카드 350원 현금 400원 (어린이)

나이를 입력 받고, 카드 유무 있으면 1, 없으면 0으로 받아서
버스 요금은 : 성인 카드 1,250원 입니다. 출력

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		System.out.print("카드 1, 현금 2 >> ");
		int a = sc.nextInt();
		System.out.print("나이 >> ");
		int b = sc.nextInt();
		
		String c = "";
		int m1 = 0;
		int m2 = 0;
		
		if(b>=19) {
			m1 = 1250;
			m2 = 1400;
			c = "성인";
		}
		else if(b>=13) {
			m1 = 750;
			m2 = 900;
			c = "청소년";
		}
		else if(b>=6) {
			m1 = 350;
			m2 = 400;
			c = "어린이";
		}
		
		if(a==1) {
			System.out.println(c+" 카드 "+m1+"원");
		}
		if(a==2) {
			System.out.println(c+"  현금 "+m2+"원");
		}
	}

 

 

 

 

switch문

switch(조건식){
case 값1:
실행문1
break;
case 값2:
실행문2
break;
default:
위의 값과 일치하는 것이 없을 경우 실행
}

default가 필요없으면 안써도됨

조건식에 == 안붙임

조건식의 값이 값1이면 실행문1, 값2면 실행문2 실행
break; 를 사용하지 않으면 값1이면 실행문1과 실행문2를 실행

  • break; 미사용시 문제
package javapj;

import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		System.out.println("1.넷플릭스, 2.유튜브, 3.디즈니 플러스");
		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
        
		switch(a) {
		case 1:
			System.out.println("넷플릭스");
		case 2:
			System.out.println("유튜브");
		case 3:
			System.out.println("디즈니 플러스");
		default:
			System.out.println("잘못입력");				
		}
			
	}

}


// 출력 //

1.넷플릭스, 2.유튜브, 3.디즈니 플러스
숫자를 입력하세요 >> 2
유튜브
디즈니 플러스
잘못입력
  • break; 사용
		switch(a) {
		case 1:
			System.out.println("넷플릭스");
			break;
		case 2:
			System.out.println("유튜브");
			break;
		case 3:
			System.out.println("디즈니 플러스");
			break;
		default:
			System.out.println("잘못입력");
		}

// 출력 //

1.넷플릭스, 2.유튜브, 3.디즈니 플러스
숫자를 입력하세요 >> 3
디즈니 플러스

연습문제 1

숫자를 입력받아
숫자가 홀짝을 판단하여 홀짝 출력
예시)
숫자를 입력하세요 >> 11
홀수

		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
		switch(a%2) {
		case 0:
			System.out.println("짝수");
			break;
		default:
			System.out.println("홀수");
			break;
		}

연습문제 2

숫자를 입력받아
3의 배수를 찾기
예시)
숫자를 입력하세요 >> 3
3의 배수
예시2)
숫자를 입력하세요 >> 4
3의 배수 아님

		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
        
		switch(a%3) {
		case 0:
			System.out.println("3의 배수");
			break;
		default:
			System.out.println("3의 배수 아님");
		}

 

 

연습문제 3

1년동안 읽은 책권수를 입력받아
10권 미만 - "조금더 노력하세요"
20권 미만 - "책 읽는 것을 즐기시네요"
30권 미만 - "책을 사랑하시는 분이시네요"
그외 - "당신은 다독왕입니다."
마이너스로 입력한 것은 생각 안하기

예시)
1년동안 읽은 책권수 >> 10
책 읽는 것을 즐기시네요

		System.out.print("1년동안 읽은 책권수 >> ");
		
		int a = sc.nextInt();
        
		switch(a/10) {
		case 0:
			System.out.println("조금더 노력하세요");
			break;
		case 1:
			System.out.println("책 읽는 것을 즐기시네요");
			break;
		case 2:
			System.out.println("책을 사랑하시는 분이시네요");
			break;
		default:
			System.out.println("당신은 다독왕 입니다.");
		}

 

 

switch문

switch(조건식){
case 값1:
실행문1
break;
case 값2:
실행문2
break;
default:
위의 값과 일치하는 것이 없을 경우 실행
}

default가 필요없으면 안써도됨

조건식에 == 안붙임

조건식의 값이 값1이면 실행문1, 값2면 실행문2 실행
break; 를 사용하지 않으면 값1이면 실행문1과 실행문2를 실행

  • break; 미사용시 문제
package javapj;

import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		System.out.println("1.넷플릭스, 2.유튜브, 3.디즈니 플러스");
		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
        
		switch(a) {
		case 1:
			System.out.println("넷플릭스");
		case 2:
			System.out.println("유튜브");
		case 3:
			System.out.println("디즈니 플러스");
		default:
			System.out.println("잘못입력");				
		}
			
	}

}


// 출력 //

1.넷플릭스, 2.유튜브, 3.디즈니 플러스
숫자를 입력하세요 >> 2
유튜브
디즈니 플러스
잘못입력
  • break; 사용
		switch(a) {
		case 1:
			System.out.println("넷플릭스");
			break;
		case 2:
			System.out.println("유튜브");
			break;
		case 3:
			System.out.println("디즈니 플러스");
			break;
		default:
			System.out.println("잘못입력");
		}

// 출력 //

1.넷플릭스, 2.유튜브, 3.디즈니 플러스
숫자를 입력하세요 >> 3
디즈니 플러스

연습문제 1

숫자를 입력받아
숫자가 홀짝을 판단하여 홀짝 출력
예시)
숫자를 입력하세요 >> 11
홀수

		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
		switch(a%2) {
		case 0:
			System.out.println("짝수");
			break;
		default:
			System.out.println("홀수");
			break;
		}

연습문제 2

숫자를 입력받아
3의 배수를 찾기
예시)
숫자를 입력하세요 >> 3
3의 배수
예시2)
숫자를 입력하세요 >> 4
3의 배수 아님

		System.out.print("숫자를 입력하세요 >> ");
		
		int a = sc.nextInt();
        
		switch(a%3) {
		case 0:
			System.out.println("3의 배수");
			break;
		default:
			System.out.println("3의 배수 아님");
		}

 

 

연습문제 3

1년동안 읽은 책권수를 입력받아
10권 미만 - "조금더 노력하세요"
20권 미만 - "책 읽는 것을 즐기시네요"
30권 미만 - "책을 사랑하시는 분이시네요"
그외 - "당신은 다독왕입니다."
마이너스로 입력한 것은 생각 안하기

예시)
1년동안 읽은 책권수 >> 10
책 읽는 것을 즐기시네요

		System.out.print("1년동안 읽은 책권수 >> ");
		
		int a = sc.nextInt();
        
		switch(a/10) {
		case 0:
			System.out.println("조금더 노력하세요");
			break;
		case 1:
			System.out.println("책 읽는 것을 즐기시네요");
			break;
		case 2:
			System.out.println("책을 사랑하시는 분이시네요");
			break;
		default:
			System.out.println("당신은 다독왕 입니다.");
		}

반복문

for문

for(초기화;조건식;증감식){
조건이 참일 경우 실행문
}

		for (int a=1;a<=5;a++) {
			System.out.println(a+" 자바");
		}

// 출력 //

1 자바
2 자바
3 자바
4 자바
5 자바

for문 안에서 선언한 변수는 그안에서만 사용가능

		for (int a=1;a<=5;a++) {
			System.out.println(a+" 자바");
		}
		System.out.println(a); // 에러

초기화에서 선언은 밖에서 해도됨

		int a;
		for (a=1;a<=5;a++) {
			System.out.println(a+" 자바");
		}

초기화 부분을 밖에서 해도 됨

		int a=1;
		for (;a<=5;a++) {
			System.out.println(a+" 자바");
		}

증감식은 안에서 해도 됨

		int a=1;
		for (;a<=5;) {
			System.out.println(a+" 자바");
			a++;
		}

연습문제 1

0 ~ 4까지 출력하시오

		for (int a=0;a<5;a++) {
			System.out.println(a);
		}
// 출력 //

0
1
2
3
4

연습문제 2

4 ~ 0까지 출력하시오

		for (int a=4;a>=0;a--) {
			System.out.println(a);
		}

// 출력 //

4
3
2
1
0

 

연습문제 3

1~10까지 합을 구하시오
예시)
1까지의 합 = 1
2까지의 합 = 3
3까지의 합 = 6

		int b = 0;
		for (int a=1;a<=10;a++) {
			b+=a;
			System.out.printf("%d까지의 합 = %d %n",a,b);
		}
		int b = 0;
		for (int a=1;a<=10;a++) {
			System.out.printf("%d까지의 합 = %d %n",a,b+=a);
		}

// 출력 //

1까지의 합 = 1
2까지의 합 = 3
3까지의 합 = 6
4까지의 합 = 10
5까지의 합 = 15
6까지의 합 = 21
7까지의 합 = 28
8까지의 합 = 36
9까지의 합 = 45
10까지의 합 = 55

 

연습문제 4

1~10까지의 곱을 구하시오
예시)
1까지의 곱 1
2까지의 곱 2
3까지의 곱 6
4까지의 곱 24

		int b = 1;
		for (int a=1;a<=10;a++) {
			System.out.printf("%d까지의 곱 = %d %n",a,b*=a);
		}

// 출력 //

1까지의 곱 = 1 
2까지의 곱 = 2 
3까지의 곱 = 6 
4까지의 곱 = 24 
5까지의 곱 = 120 
6까지의 곱 = 720 
7까지의 곱 = 5040 
8까지의 곱 = 40320 
9까지의 곱 = 362880 
10까지의 곱 = 3628800 

 

연습문제 5

1~10까지의 합인데 2의 배수의 숫자만 합계
예시
2까지의 합 = 2
4까지의 합 = 6
6까지의 합 = 12
8까지의 합 = 20
10까지의 합 = 30

		int b = 0;
		for (int a=1;a<=10;a++) {
			if (a%2==0){
				b+=a;
			}
			System.out.printf("%d까지의 합 = %d %n",a,b);				
		}

// 출력 //

1까지의 합 = 0 
2까지의 합 = 2 
3까지의 합 = 2 
4까지의 합 = 6 
5까지의 합 = 6 
6까지의 합 = 12 
7까지의 합 = 12 
8까지의 합 = 20 
9까지의 합 = 20 
10까지의 합 = 30 

2만 빼는 방법

		int b = 0;
		for (int a=1;a<=10;a++) {
			if (a%2==0){
				b+=a;
				System.out.printf("%d까지의 합 = %d %n",a,b);				
			}
		}
        
// 출력 //

2까지의 합 = 2 
4까지의 합 = 6 
6까지의 합 = 12 
8까지의 합 = 20 
10까지의 합 = 30 
  • 변형
		int b = 0;
		for (int a=2;a<=10;a+=2) {
        	b+=a;
			System.out.printf("%d까지의 합 = %d %n",a,b);
		}

 

 

 

while문

while(조건식){
실행되는 부분
}

 

조건식에는 조건부분만 들어가야함

		int a = 1;
		while(a<=5) {
			System.out.println(a);
			a++;
		}

// 출력 //

1
2
3
4
5

무한 반복
자바는 true로 명확하게 알려줘야함

		int a = 0;
		while(true) {
			System.out.println(a);
			a++;
		}

 

 


음악재생 관련 예제

		String a = "y";
		int c = 0;
		
		while(a.equals("y")) {
			System.out.print("음악을 재생하시겠습니까? >> ");
			a = sc.next();
			if (a.equals("y")) {
				c++;
				System.out.printf("음악을 %d번 재생했습니다. \n",c);
				System.out.println();				
			}
		}
		System.out.println("재생종료");

 

 

1~입력 숫자까지의 합구하기

 

	public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		System.out.print("~까지 : ");
		int a = sc.nextInt();
		System.out.print("배수 : ");
		int b = sc.nextInt();
		
		int i = b;
		int s = 0;
		while(i<=a) {
			s+=i;
			i+=b;
		}
		System.out.println(a+"까지의 "+b+"배수의 합 = "+s);
		
		

	}

 

 

 

정수를 입력받아 합계를 구하는 식을 만드시오
0을 입력하면 종료

 

예시
정수를 입력 >> 2
현재까지의 합 = 2
정수를 입력 >> 3
현재까지의 합 = 5
정수를 입력 >> 2
현재까지의 합 = 7
정수를 입력 >> 0
현재까지의 합 = 7
종료

		int a, b = 0;
		do {
			System.out.print("정수를 입력 >> ");
			a = sc.nextInt();
			b += a;
			System.out.printf("현재까지의 합 = %d\n",b);
			System.out.println();
		}while(a!=0);
		System.out.println("종료");

// 출력 //

정수를 입력 >> 2
현재까지의 합 = 2

정수를 입력 >> 3
현재까지의 합 = 5

정수를 입력 >> 2
현재까지의 합 = 7

정수를 입력 >> 0
현재까지의 합 = 7

종료

 

 

기본예시
입력한 범위 내에서만 작성

		int a ;
		while(true) {
			System.out.print("정수를 입력하세요 >> ");
			a = sc.nextInt();
			if (a>0 && a<=10) { //1~10까지 정수만 받음
				System.out.printf("입력된 숫자 : %d",a);
				break;
			}
			else {
				System.out.println("입력오류");
			}

// 출력 //

정수를 입력하세요 >> 0
입력오류
정수를 입력하세요 >> 11
입력오류
정수를 입력하세요 >> 5
입력된 숫자 : 5


continue문

continue는 반복문의 처음으로 돌아감
1 ~ 10을 출력하는데 2의 배수는 제외하고 출력

		for (int a=1;a<=10;a++) {
			if (a%2==0) {
				continue;
			}
			System.out.println(a);
		}

// 출력 //

1
3
5
7
9

중첩 반복문

1일차 1교시 ~ 3교시
2일차 1교시 ~ 3교시

 

		for (int i=1;i<=2;i++) {
			for(int j=1;j<=3;j++) {
				
				System.out.printf("%d일차 %d교시\n",i,j);
			}
			System.out.println();
		}

// 출력 //

1일차 1교시
1일차 2교시
1일차 3교시

2일차 1교시
2일차 2교시
2일차 3교시

연습문제 일차는 1 ~ 10, 교시는 1~10

		for (int i=1;i<=10;i++) {
			for(int j=1;j<=10;j++) {
				
				System.out.printf("%d일차 %d교시\t",i,j);
			}
			System.out.println();
		}

// 출력 //

1일차 1교시	1일차 2교시	1일차 3교시	1일차 4교시	1일차 5교시	1일차 6교시	1일차 7교시	1일차 8교시	1일차 9교시	1일차 10교시	
2일차 1교시	2일차 2교시	2일차 3교시	2일차 4교시	2일차 5교시	2일차 6교시	2일차 7교시	2일차 8교시	2일차 9교시	2일차 10교시	
3일차 1교시	3일차 2교시	3일차 3교시	3일차 4교시	3일차 5교시	3일차 6교시	3일차 7교시	3일차 8교시	3일차 9교시	3일차 10교시	
4일차 1교시	4일차 2교시	4일차 3교시	4일차 4교시	4일차 5교시	4일차 6교시	4일차 7교시	4일차 8교시	4일차 9교시	4일차 10교시	
5일차 1교시	5일차 2교시	5일차 3교시	5일차 4교시	5일차 5교시	5일차 6교시	5일차 7교시	5일차 8교시	5일차 9교시	5일차 10교시	
6일차 1교시	6일차 2교시	6일차 3교시	6일차 4교시	6일차 5교시	6일차 6교시	6일차 7교시	6일차 8교시	6일차 9교시	6일차 10교시	
7일차 1교시	7일차 2교시	7일차 3교시	7일차 4교시	7일차 5교시	7일차 6교시	7일차 7교시	7일차 8교시	7일차 9교시	7일차 10교시	
8일차 1교시	8일차 2교시	8일차 3교시	8일차 4교시	8일차 5교시	8일차 6교시	8일차 7교시	8일차 8교시	8일차 9교시	8일차 10교시	
9일차 1교시	9일차 2교시	9일차 3교시	9일차 4교시	9일차 5교시	9일차 6교시	9일차 7교시	9일차 8교시	9일차 9교시	9일차 10교시	
10일차 1교시	10일차 2교시	10일차 3교시	10일차 4교시	10일차 5교시	10일차 6교시	10일차 7교시	10일차 8교시	10일차 9교시	10일차 10교시	

3교시까지만 출력하고 싶음

		for (int i=1;i<=10;i++) {
			for(int j=1;j<=10;j++) {
				if (j>3) {
					break;
				}
				System.out.printf("%d일차 %d교시\t",i,j);
			}
			System.out.println();
		}

// 출력 //

1일차 1교시	1일차 2교시	1일차 3교시	
2일차 1교시	2일차 2교시	2일차 3교시	
3일차 1교시	3일차 2교시	3일차 3교시	
4일차 1교시	4일차 2교시	4일차 3교시	
5일차 1교시	5일차 2교시	5일차 3교시	
6일차 1교시	6일차 2교시	6일차 3교시	
7일차 1교시	7일차 2교시	7일차 3교시	
8일차 1교시	8일차 2교시	8일차 3교시	
9일차 1교시	9일차 2교시	9일차 3교시	
10일차 1교시	10일차 2교시	10일차 3교시	

반목문 이름 넣기

for 앞에 이름 : for하면 됨
while도 동일

		for1 : for (int i=1;i<=10;i++) {
			for(int j=1;j<=10;j++) {
				if (j>3) {
					break for1;
				}
				System.out.printf("%d일차 %d교시\t",i,j);
			}
			System.out.println();
		}

// 출력 //

1일차 1교시	1일차 2교시	1일차 3교시



연습문제 1

구구단

		for (int i=2;i<=9;i++) {
			for(int j=1;j<=9;j++) {
				
				System.out.printf("%d * %d = %d\n",i,j,i*j);
			}
		}

// 출력 //

2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
3 * 1 = 3

구구단 변형

		for (int i=2;i<=9;i++) {
			for(int j=1;j<=9;j++) {
				
				System.out.printf("%d * %d = %d\t",i,j,i*j);
			}
			System.out.println();
		}

// 출력 //

2 * 1 = 2	2 * 2 = 4	2 * 3 = 6	2 * 4 = 8	2 * 5 = 10	2 * 6 = 12	2 * 7 = 14	2 * 8 = 16	2 * 9 = 18	
3 * 1 = 3	3 * 2 = 6	3 * 3 = 9	3 * 4 = 12	3 * 5 = 15	3 * 6 = 18	3 * 7 = 21	3 * 8 = 24	3 * 9 = 27	
4 * 1 = 4	4 * 2 = 8	4 * 3 = 12	4 * 4 = 16	4 * 5 = 20	4 * 6 = 24	4 * 7 = 28	4 * 8 = 32	4 * 9 = 36	
5 * 1 = 5	5 * 2 = 10	5 * 3 = 15	5 * 4 = 20	5 * 5 = 25	5 * 6 = 30	5 * 7 = 35	5 * 8 = 40	5 * 9 = 45	
6 * 1 = 6	6 * 2 = 12	6 * 3 = 18	6 * 4 = 24	6 * 5 = 30	6 * 6 = 36	6 * 7 = 42	6 * 8 = 48	6 * 9 = 54	
7 * 1 = 7	7 * 2 = 14	7 * 3 = 21	7 * 4 = 28	7 * 5 = 35	7 * 6 = 42	7 * 7 = 49	7 * 8 = 56	7 * 9 = 63	
8 * 1 = 8	8 * 2 = 16	8 * 3 = 24	8 * 4 = 32	8 * 5 = 40	8 * 6 = 48	8 * 7 = 56	8 * 8 = 64	8 * 9 = 72	
9 * 1 = 9	9 * 2 = 18	9 * 3 = 27	9 * 4 = 36	9 * 5 = 45	9 * 6 = 54	9 * 7 = 63	9 * 8 = 72	9 * 9 = 81	

구구단 변형2

		for (int i=1;i<=9;i++) {
			for(int j=2;j<=9;j++) {
				
				System.out.printf("%d * %d = %d\t",j,i,i*j);
			}
			System.out.println();
		}

// 출력 //
2 * 1 = 2	3 * 1 = 3	4 * 1 = 4	5 * 1 = 5	6 * 1 = 6	7 * 1 = 7	8 * 1 = 8	9 * 1 = 9	
2 * 2 = 4	3 * 2 = 6	4 * 2 = 8	5 * 2 = 10	6 * 2 = 12	7 * 2 = 14	8 * 2 = 16	9 * 2 = 18	
2 * 3 = 6	3 * 3 = 9	4 * 3 = 12	5 * 3 = 15	6 * 3 = 18	7 * 3 = 21	8 * 3 = 24	9 * 3 = 27	
2 * 4 = 8	3 * 4 = 12	4 * 4 = 16	5 * 4 = 20	6 * 4 = 24	7 * 4 = 28	8 * 4 = 32	9 * 4 = 36	
2 * 5 = 10	3 * 5 = 15	4 * 5 = 20	5 * 5 = 25	6 * 5 = 30	7 * 5 = 35	8 * 5 = 40	9 * 5 = 45	
2 * 6 = 12	3 * 6 = 18	4 * 6 = 24	5 * 6 = 30	6 * 6 = 36	7 * 6 = 42	8 * 6 = 48	9 * 6 = 54	
2 * 7 = 14	3 * 7 = 21	4 * 7 = 28	5 * 7 = 35	6 * 7 = 42	7 * 7 = 49	8 * 7 = 56	9 * 7 = 63	
2 * 8 = 16	3 * 8 = 24	4 * 8 = 32	5 * 8 = 40	6 * 8 = 48	7 * 8 = 56	8 * 8 = 64	9 * 8 = 72	
2 * 9 = 18	3 * 9 = 27	4 * 9 = 36	5 * 9 = 45	6 * 9 = 54	7 * 9 = 63	8 * 9 = 72	9 * 9 = 81	

 

 

 

 

 

 

 

 

■ 2월 17일 - 2일차

배열

같은 타입의 변수를 하나의 묶음으로 관리.
변수가 하나의 데이터만 저장할 수 있다면 배열은
여러개의 데이터를 저장하고 효율적으로 관리함.

배열을 생성하면 인덱스 값이 붙어서 데이터를 관리.

인덱스 값 - 각 요소(저장공간)에 자동으로 붙는 번호
0부터 시작함

배열의 선언과 생성

배열의 선언 - 배열을 다루기 위한 참조변수의 선언
변수는 선언을 하는 순간 저장공간을 만들어줌

선언방법
데이터 타입[] 배열 변수의 이름;
데이터 타입 배열변수의 이름[];

		int[] a; //java스타일 배열의 기호를 타입의 일부로 봄
		int b[]; //c언어스타일

배열의 생성 - 실제 저장공간을 생성
배열 변수이름 = new 데이터타입[공간크기]

		a = new int[5];
        // 5개 공간을 나타냄
        // 인덱스 값은 0 ~ 4
        // a에 주소값이 저장

배열의 생성과 선언

		int[] b = new int[5];

 

배열관련 정리

public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		
		int a; // int형태로(4byte) 공간을 가지고 이름은 a로 한다.
		int[] b; //int형태로 데이터들을 저장하는 배열 이름을 b로 한다. (선언)
		b = new int[5]; // 5개짜리 int형태로 공간을 만들어주어라 (20byte)
		int[] c = new int[5]; //생성과 선언
		int[] d = {1,2,3,4,5}; // 생성과 선언, 초기화 선언과 동시에 초기화
		int[] e; // 선언
		e = new int[] {1,2,3}; //공간을 만들어주고 초기화까지 하는 방식
		int[] f;
		// f = {1,2,4,5}; //에러 공간을 만들어 주지 않고 초기화
		
		
		for(int i = 0; i<5; i++) {
			System.out.println(d[i]);
		}
		
		
		
	}


배열의 데이터 저장 및 관리

주소값 확인

		int[] a = new int[5];
		int[] b = new int[5];
		
		System.out.printf("%s, %s",a, b); //%d하면 안됨

// 출력 //

[I@63961c42, [I@65b54208

기본값 확인 for문이용

		int[] a = new int[5];
		for(int i=0;i<5;i++) {
			System.out.println(a[i]);
		}

// 출력 //

0
0
0
0
0

배열에 데이터 저장하기

		int[] a = new int[5];
		
		a[1] = 100; // 두번째에 저장됨
		
		int c = a[1];
		
		System.out.println(a[1]);
		System.out.println(c);

// 출력 //

100
100

 

 


배열의 길이

배열은 한번 생성하면 실행되는 동안 그 길이를 바꿀 수 없다.
배열은 상수임

왜?
메모리 공간이 있는데 int형 5자리라고 하면
5*4 = 20byte가 드는데
배열은 주소를 연속되게 갖고 있어야함
20byte의 공간에 맞는 메모리를 찾아서
그곳에 저장됨 그렇기 때문에 자동으로 변경되면은
메모리 공간을 다시 찾아야 함

공간이 부족하다면
새로운 큰 배열을 만들어서
작은 배열에 있는 것을 옮겨야 함

		int[] a = new int[5];
		
		int len = a.length;
		
		System.out.println(len);

// 출력 //

5

 

배열의 length가 있는 이유

기본적으로 배열은 내가 처음에 크기를 지정을 해줌
그러나 프로그래밍을 하면서 배열의 길이를 바꿀 수도 있음
ex) int[5] 에서 int[20] 이런식으로는 가능하니까
그런데 이 배열과 연동되어 출력하는 for문들이나
길이에 대해 연동되는 함수, 변수 등이 있을 수 있음
그래서 배열길이와 연동되는 내용에 length를 씀

		int[] a = new int[5]; //변경하면 길이에 따라 출력
		
		for (int i=0; i<a.length;i++) {
			System.out.println(a[i]);
		}

// 출력 //

0
0
0
0
0

for문으로 배열에 반복적인 숫자 저장법1

		int[] a = new int[5];
		
		for (int i=0; i<a.length;i++) {
			a[i] = i+1;
			System.out.println(a[i]);
		}

// 출력 //

1
2
3
4
5

2의 배수 저장

		int[] a = new int[5];
		int b = 2;
		for (int i=0; i<a.length;i++) {

			a[i] = b;
			System.out.println(a[i]);
			b+=2;
		}

// 출력 //

2
4
6
8
10

2의 제곱 저장

		int[] a = new int[11];
		int b = 1;
		for (int i=0; i<a.length;i++) {

			a[i] = b;
			System.out.printf("2의 %d 제곱은 = %d\n",i,a[i]);
			b*=2;
		
// 출력 //

2의 0 제곱은 = 1
2의 1 제곱은 = 2
2의 2 제곱은 = 4
2의 3 제곱은 = 8
2의 4 제곱은 = 16
2의 5 제곱은 = 32
2의 6 제곱은 = 64
2의 7 제곱은 = 128
2의 8 제곱은 = 256
2의 9 제곱은 = 512
2의 10 제곱은 = 1024

 

배열의 초기화

배열의 각 요소에 처음으로 값을 저장하는 것
기본적으로 자동 초기화 됨, int 0

int[] a = new int[5];
a[0] = 10;
a[1] = 20;
a[2] = 30;
a[3] = 40;
a[4] = 50;

간단한 방법
int[] a = new int[] {10,20,30,40,50} (자동으로 사이즈를 넣음)
int[] a = {10,20,30,40,50} (자동으로 사이즈를 넣음)

오류1
int[] a = new int[5] {10,20,30,40,50} // 오류

오류2
int[] a; //선언 및 생성을 따로 할때 문제
a = {10,20,30,40,50} 에러
a = new int[] {10,20,30,40,50}

		int[] a = {10,20,30,40,50};
		
		for (int i=0; i<a.length;i++) {

			System.out.println(a[i]);

		}

// 출력 //

10
20
30
40
50

 

 

예제 6-5

public static void main(String[] args) {
		
		char[] c = {'1','L','O','2','V','1','E'};
		// 1개의 문자가 저장 되어 있다. '1' 문자 1
		// 배열에서 영문 대문자만 뽑아서 넣어주는 
		String m ="";  
		// char a = 'A';  65    90 =  Z   //아스키코드로 '1' = 숫자 49
		for(int i=0; i<c.length;i++) { // i = 0 ~ c배열의 크기보다 1작은
			if(c[i]>=65 && c[i]<=90) { //A~Z 65~90
				m+=c[i];
			}
		}
		System.out.println(m);		
	}

// 출력 //

LOVE

 

 

package pj;

import java.util.Scanner;

public class J1 {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		System.out.print("입력 >> ");
		String a = sc.next();
		
		int c1 = 0, c2 = 0;
		for(int i = 0; i<a.length(); i++) {
			if(a.charAt(i)>='0' && a.charAt(i)<=57) {
				c1++;
			}
			if(a.charAt(i)>=97 && a.charAt(i)<=122) {
				c2++;
			}
		}		
		
		System.out.println("문자는 "+c2+"개   숫자는 "+c1+"개 입력");


	}

}

 

 

배열형식으로 출력

Arrays 함수 사용
import java.util.Arrays
Arrays.toString(배열이름)

 

package javapj;

import java.util.Arrays;

public class K1 {

	public static void main(String[] args) {
		
		int[] a = {10,20,30,40,50};
		
		System.out.println(Arrays.toString(a));
		
		
	}

}

// 출력 //

[10, 20, 30, 40, 50]

 

배열의 복사

얕은 복사
원본 배열이 변경될때 서로간의 값이 함께 변경

깊은 복사
원본 배열이 변경되도
서로간 값은 변경안됨

public static void main(String[] args) {
		
		int[] a = {1,2,7,6,5};
		int[] b = new int[a.length];
		int[] c = a; //얇은 복사
		for(int i = 0; i<a.length;i++) { //깊은 복사
			b[i] = a[i];
		}
		a[0] = 100;
				
		System.out.println(Arrays.toString(a));
		System.out.println(Arrays.toString(b));
		System.out.println(Arrays.toString(c));

		
	}

// 출력 //

[100,2,7,6,5]
[1,2,7,6,5]
[100,2,7,6,5]

 

다른 데이터 타입의 배열확인


package javapj;

import java.util.Arrays;

public class K1 {

	public static void main(String[] args) {
		
		int[] a = {1,2,3,4};
		float[] b = {0.1f,0.2f,0.3f};
		char[] c = {'a','c','김','박'};
		String[] d = {"홍길동","유성룡","이순신"};
		boolean[] e = {true,false,true};
		
		System.out.println(a);
		System.out.println(b);
		System.out.println(c);
		System.out.printf("%s\n",c);
		System.out.println(d);
		System.out.println(e);
		System.out.println();
		
		System.out.println(Arrays.toString(a));
		System.out.println(Arrays.toString(b));
		System.out.println(Arrays.toString(c));
		System.out.println(Arrays.toString(d));
		System.out.println(Arrays.toString(e));
		
		
	}

}


// 출력 //

[I@36baf30c
[F@7a81197d
ac김박
[C@1be6f5c3
[Ljava.lang.String;@6b884d57
[Z@38af3868

[1, 2, 3, 4]
[0.1, 0.2, 0.3]
[a, c, 김, 박]
[홍길동, 유성룡, 이순신]
[true, false, true]


 

배열 개수 설정 및 추가

참고로 처음에 배열을 만들때 개수를
정해주지 않고 추가 할 수는 없다. 배열은 상수임
메모리 지정 문제가 발생하여 추가가 불가능
그러나 또 다른 배열을 만들어서 해결할 수 있다.

배열 개수 설정하는 법

import java.util.Arrays;
import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		
		System.out.print("배열을 몇개 만들까요? >> ");
		
		int idx = sc.nextInt();
		
		int[] arr = new int[idx];
		
		System.out.println(Arrays.toString(arr));
		
		for (int i = 0; i<arr.length;i++) {
			arr[i] = i+1;
		}
		
		System.out.println(Arrays.toString(arr));
		sc.close();

	}

}

// 출력 //

배열을 몇개 만들까요? 추가할까요? >> 10
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

 

배열에 내가 입력해서 만들기

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		
		System.out.print("배열을 몇개 만들까요? >> ");
		
		int idx = sc.nextInt();
		
		int[] arr = new int[idx];
		
		System.out.println(Arrays.toString(arr));

		for (int i = 0; i<arr.length;i++) {

			System.out.printf("총 %d개중 %d번째 입력 >> ",arr.length,i+1);
			arr[i] = sc.nextInt();
		}
		
		System.out.println(Arrays.toString(arr));
		sc.close();

	}

// 출력 //

배열을 몇개 만들까요? >> 3
[0, 0, 0]
총 3개중 1번째 입력 >> 2
총 3개중 2번째 입력 >> 30
총 3개중 3번째 입력 >> 50
[2, 30, 50]

 

배열을 추가해서 추가 입력

package javapj;

import java.util.Arrays;
import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		
		System.out.print("배열을 몇개 만들까요? >> ");
		
		int idx = sc.nextInt();
		
		int[] arr = new int[idx];
		
		System.out.println(Arrays.toString(arr));

		for (int i = 0; i<arr.length;i++) {

			System.out.printf("총 %d개중 %d번째 입력 >> ",arr.length,i+1);
			arr[i] = sc.nextInt();
		}
		
		System.out.println(Arrays.toString(arr));

		System.out.print("몇개를 추가 하시겠습니까? >> ");
		int idx2 = (arr.length)+(sc.nextInt()); // 최초 크기에 입력받은 값을 더함
		int[] arr2 = new int[idx2]; //새로운 배열 만들기
		
		for(int i = 0; i<arr2.length;i++) {
			if (i<arr.length) { // 미리 입력되어 있는것은 예전배열에서 받음
				arr2[i] = arr[i]; 
			}
			else { // 추가하는 부분은 여기서부터 시행
				System.out.printf("총 %d개중 %d번째 입력 >> ",arr2.length,i+1);
				arr2[i] = sc.nextInt();
			}
		}
		
		System.out.println("최초 배열 "+Arrays.toString(arr));
		System.out.println("두번째 배열 "+Arrays.toString(arr2));
		
		
		sc.close();

	}

}

// 출력 //

배열을 몇개 만들까요? >> 3
[0, 0, 0]
총 3개중 1번째 입력 >> 25
총 3개중 2번째 입력 >> 38
총 3개중 3번째 입력 >> 49
[25, 38, 49]
몇개를 추가 하시겠습니까? >> 2
총 5개중 4번째 입력 >> 32
총 5개중 5번째 입력 >> 64
최초배열[25, 38, 49]
두번째 배열[25, 38, 49, 32, 64]

 

 

배열활용 3.

랜덤한 수로 돌리기

Math.random() = double
Math.random()*9 : 0~9로 돌려라

소수점으로 출력

		for (int i = 0; i<=10; i++) {
			System.out.println(Math.random());
			
		}

// 출력 //

0.6996439764255871
0.8873434713281453
0.2440939925656831
0.84906511371554
0.2733967606744314
0.6121523068605648
0.17662707871225247
0.03208798962816317
0.10197646915899483
0.4816061294809014
0.0713202120741766

 

(int)로 변화시키면 0이 출력
곱하기 5를 해주면
0~4까지 출력됨

		for (int i = 0; i<=20; i++) {
			System.out.println((int)(Math.random()*5));
			
		}

// 출력 //

4
2
1
2
0
1
3
3
2
2
4

 

배열 안에서 랜덤 돌리기 1

package javapj;

import java.util.Arrays;

public class K1 {

	public static void main(String[] args) {

		int[] a = {1,2,3,4,5,6,7,8,9};
		System.out.println(Arrays.toString(a));
		for (int i = 0; i <5; i++) {
			int ri = (int)(Math.random()*9);
			int tmp = a[0];
			a[0] = a[ri];
			a[ri] = tmp;
			System.out.println(Arrays.toString(a));
		}		

	}

}

// 출력 //

[1, 2, 3, 4, 5, 6, 7, 8, 9]
[8, 2, 3, 4, 5, 6, 7, 1, 9]
[3, 2, 8, 4, 5, 6, 7, 1, 9]
[2, 3, 8, 4, 5, 6, 7, 1, 9]
[4, 3, 8, 2, 5, 6, 7, 1, 9]
[6, 3, 8, 2, 5, 4, 7, 1, 9]

 

 

 

 

 

 

 

 

■ 2월 18일 - 3일차

랜덤한 수 찾는 게임 만들기

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int r = (int)(Math.random()*100)+1;
    for(int i=0; i<5;i++){
        System.out.print((i+1)+"번 입력 >> ");
        int a = sc.nextInt();
        if(r>a) System.out.println(a+" 보다 크다 ");
        else if(r<a) System.out.println(a + " 보다 작다");
        else {
            System.out.println("맞습니다. 정답은 : "+r);
            break;
        }
        if(i==4) System.out.println("입력 초과 정답은 : "+r);
    }


}

 

 

배열 안에서 랜덤 돌리기 2

int[] a = {10,22,38,47,59,63,75,82,96};
System.out.println(Arrays.toString(a));
for (int i = 0; i <100; i++) {
    int ri = (int)(Math.random()*9);
    int tmp = a[0];
    a[0] = a[ri];
    a[ri] = tmp;
}		
System.out.println(Arrays.toString(a));

// 출력 //

[10, 22, 38, 47, 59, 63, 75, 82, 96]
[96, 22, 75, 82, 47, 38, 59, 63, 10]

 

다른방식

public static void main(String[] args) {
		
    Scanner sc = new Scanner(System.in);

    int[] a = new int[10];

    for(int i = 0; i<10; i++) {
        a[i] = (int)(Math.random()*10);
        for(int j = 0;j<i;j++) {
            if(a[i]==a[j]) {
                i--;
                break;
            }
        }
    }
    System.out.println(Arrays.toString(a));


    sc.close();		
}

 

연습문제 1. 로또 번호 만들기

로또번호는 45숫자중 6개가
동일한 숫자를 제외하고 출력되어야 함

이러면 동일한 값이 나올수 있음

int[] lotto = new int[6];
for(int i = 0; i<lotto.length;i++) {
    lotto[i] = (int)(Math.random()*45)+1;
}


System.out.println(Arrays.toString(lotto));

// 출력 //

[8, 3, 17, 4, 4, 3]

완성

int[] li = new int[45];
for(int i = 0; i<li.length;i++) {
    li[i] = i+1; // 1 ~ 45까지 저장
}

for(int i = 0; i<6; i++) { //index 0~5
    int r = (int)(Math.random()*45);
    int tmp = li[i];
    li[i] = li[r];
    li[r] = tmp;
}

int[] lotto = new int[6];
for(int i = 0; i<6; i++) {
    lotto[i] = li[i];
}

System.out.println(Arrays.toString(lotto));
System.out.println(Arrays.toString(li));

// 출력 //

[14, 11, 12, 19, 34, 31]
[14, 11, 12, 19, 34, 31, 7, 8, 9, 10, ... ]

 

 

다른방식

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    int[] a = new int[6];
    for(int i = 0; i<6; i++) {
        a[i] = (int)(Math.random()*45)+1;
        for(int j = 0; j<i;j++) {
            if(a[i]==a[j]) {
                i--;
            }
        }
    }
    System.out.println(Arrays.toString(a));

}

 

 

연습문제 2. 총계, 평균 구하기

점수를 5개 입력받아서
국어, 영어, 수학, 사회, 과학
총계 : 000 평균 : 000 출력
국어 : 00, 영어 : 00, 수학 : 00, 사회 : 00, 과학 : 00 출력

Scanner sc = new Scanner(System.in);

String[] sub = {"국어", "영어", "수학", "사회","과학"};

int[] scr = new int[5];
int sum = 0;

for(int i=0; i<scr.length; i++) {
    System.out.printf("%s 점수 입력 >> ",sub[i]);
    scr[i] = sc.nextInt();
    sum += scr[i];
}

System.out.printf("총점 : %d, 평균 : %.2f \n",sum,sum/(float)(scr.length));

for(int i=0; i<scr.length; i++) {
    if (i<scr.length-1)
        System.out.printf("%s : %d, ",sub[i],scr[i]);
    else
        System.out.printf("%s : %d",sub[i],scr[i]);
}

// 출력 //

국어 점수 입력 >> 95
영어 점수 입력 >> 80
수학 점수 입력 >> 97
사회 점수 입력 >> 86
과학 점수 입력 >> 93
총점 : 451, 평균 : 90.20 
국어 : 95, 영어 : 80, 수학 : 97, 사회 : 86, 과학 : 93

 

연습문제 3. 배열 오름차순 정렬

ar = {9,3,6,2,7}로 되어 있음
두개씩 비교하여 크기 확인
이중 for문을 활용하여 정렬

Scanner sc = new Scanner(System.in);

int[] ar = {9,3,6,2,7};
System.out.println(Arrays.toString(ar));

for (int i = 0; i < ar.length-1; i++) {
    for (int j = 0; j < ar.length-1-i;j++){
        if(ar[j]>ar[j+1]) {
            int tmp = ar[j];
            ar[j] = ar[j+1];
            ar[j+1] = tmp;
            System.out.println(Arrays.toString(ar));
        }
    }
}

System.out.println(Arrays.toString(ar));

// 출력 //

[9, 3, 6, 2, 7]
[3, 9, 6, 2, 7]
[3, 6, 9, 2, 7]
[3, 6, 2, 9, 7]
[3, 6, 2, 7, 9]
[3, 2, 6, 7, 9]
[2, 3, 6, 7, 9]
[2, 3, 6, 7, 9]

삽입정렬

int[] arr = {9, 5, 1, 4, 3};

for (int i = 1; i < arr.length; i++) {
    for (int j = i; j > 0 && arr[j - 1] > arr[j]; j--) {
        int temp = arr[j];
        arr[j] = arr[j - 1];
        arr[j - 1] = temp;
    }
}

 

 


배열로 가위바위보 게임 만들기

		
Scanner sc = new Scanner(System.in);

String[] sarr = {"가위", "바위", "보"};
System.out.println(Arrays.toString(sarr));

while(true) {
    System.out.print("가위, 바위 보를 입력하세요(0은종료) >> ");
    String a = sc.next();
    if (a.equals(sarr[0]) || a.equals(sarr[1]) || a.equals(sarr[2])) {
        int r = (int)(Math.random()*3);
        String b = sarr[r];
        System.out.printf("컴퓨터가 낸 값은 %s \n",b);

        int a1=0;
        for(int i = 0; i<sarr.length;i++) {
            if(sarr[i].equals(a)) {
                a1 = i;
            }		
        }

        if (a1==r) {
            System.out.println("비겼습니다.");
        }
        else if(a1==(r+1)%3) {
            System.out.println("승리했습니다.");
        }
        else if(a1==(r+2)%3){
            System.out.println("졌습니다.");
        }
        System.out.println();
    }
    else if (a.equals("0")) {
        System.out.println("종료합니다.");
        break;
    }
    else {
        System.out.println("입력이 잘못 되었습니다.");
        System.out.println();
    }
}


// 출력 //

[가위, 바위, 보]
가위, 바위 보를 입력하세요(0은종료) >> 가
입력이 잘못 되었습니다.

가위, 바위 보를 입력하세요(0은종료) >> 바위
컴퓨터가 낸 값은 바위 
비겼습니다.

가위, 바위 보를 입력하세요(0은종료) >> 0
종료합니다.

 

다차원 배열

배열은 여러가지 구조로 사용가능하는데
차원을 넓히면 차원에 맞게 증가한다.

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    int[][] arr = new int[2][];
    arr[0] = new int[3];
    arr[1] = new int[2];
    int[][] arr2 = {{1,2,3},{2},{2,4,6,7}}; //3개짜리를 보유

}

 

 

다차원배열 숫자 저장 및 출력

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    int[][] arr = new int[5][5];
    System.out.println("arr : "+arr.length);
    System.out.println("arr[1] : "+arr[1].length);
    int c = 1;
    for(int i = 0; i<arr.length; i++) {
        for(int j = 0; j<arr[0].length; j++) {
            arr[i][j] = c++;
            System.out.print(arr[i][j]);
        }
        System.out.println();
    }


}

// 출력 //

arr : 5
arr[1] : 5
12345
678910
1112131415
1617181920
2122232425

다차원 배열 (2차원 이상)

구분국어영어수학

1 100 95 92
2 95 70 88
3 89 91 87
4 92 86 94

선언
int[][] 배열이름 = new int[4][3]
저장 arr[0][0] = 100

		int[][] arr = new int[4][3];
		

index

   
[0][0] [0][1] [0][2]
[1][0] [1][1] [1][2]
[2][0] [2][1] [2][2]
[3][0] [3][1] [3][2]

초기화
int[][] arr = { {1,2,3}, {4,5,6}}
직관적으로 사용
{
{1,2,3},
{4,5,6}
}

 


 

간단히 사용하는 법

int[][] arr = {
        {1,2,3},
        {4,5,6},
        {7,8,9}
};

System.out.println(arr);
System.out.println(Arrays.toString(arr));
System.out.println(Arrays.toString(arr[0]));
System.out.println(arr[0][0]);

// 출력 //

[[I@378bf509
[[I@5fd0d5ae, [I@2d98a335, [I@16b98e56]
[1, 2, 3]
1

 

보기 좋게 만들어 보기

int[][] arr = {
        {1,2,3},
        {4,5,6},
        {7,8,9}
};

for(int i = 0; i<arr.length;i++) {
    String s = Arrays.toString(arr[i]);
    if (i==0) {
        System.out.print("[ ");
    }
    System.out.printf("%s",s);
    if(i!=arr.length-1) {
        System.out.print(", ");
    }
    if(i==arr.length-1) {
        System.out.printf(" ]",s);
    }
}

// 출력 //

[ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]

 

배열에 1부터 순서대로 저장하기

int[][] arr = new int[5][4];

int c = 0;
for(int i = 0; i<arr.length;i++) {
    for(int j = 0; j<arr[i].length;j++) {
        c+=1;
        arr[i][j] = c;
    }
    System.out.println(Arrays.toString(arr[i]));
}

// 출력 //

[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]
[17, 18, 19, 20]

 

 

 

 

 

 

 

 

 

 

■ 2월 19일 - 4일차

내용 출력

int[] sum = new int[4];
int[] sum2 = new int[3];
int sum3 = 0;
for(int i = 0; i<arr.length; i++) {
    for(int j =0; j<arr[i].length;j++) {
        sum[i]+=arr[i][j];
        System.out.print(arr[i][j]+"  ");
        sum2[j]+=arr[i][j];
    }
    System.out.print(sum[i]+" "+sum[i]/3+"\n");
}
for(int i=0; i<3;i++) {
    System.out.print(sum2[i]+" ");
    sum3+=sum2[i];
}
System.out.println(sum3+" "+(sum3/3));
for(int i=0; i<3;i++) {
    System.out.print(sum2[i]/4+"  ");
}

 

 

향상된 for문

 

public static void main(String[] args) {
		
		Scanner sc = new Scanner(System.in);
		int[] a = {1,2,3,5};
		int s = 0;
		for(int i : a) {
			System.out.println(i);
			s+=i;
		}
		System.out.println("총점 : "+s);
		
		
		
	}

// 출력 //


String 클래스

char[]과 메서드(기능)(함수)를 결합

String은 내용을 변경할 수 없다
String a = "a";
String b = "b";
a = a+b; (문자열+문자열) = "ab"
주소값자체가 새로운 메모리 공간을 만든다

주요 메서드

charAt(인덱스번호)
문자열의 위치(인덱스)의 문자를 반환

		String a = "abcdef";
		char ch = a.charAt(2);
		System.out.printf("%s",ch);

// 출력 //

c

length()
문자열의 길이를 반환
숫자로 반환 int형

		String a = "abcdef";
		System.out.println(a.length());

// 출력 //

5

substing(인덱스 번호)
인덱스 번호 부터 끝까지 반환
두번째 인덱스 번호가 변수.length()와 동일
substing(인덱스 번호1, 인덱스 번호2)
문자열의 인덱스 번호1 부터 인덱스 번호2 전까지 반환

		String a = "abcdef";
		System.out.println(a.substring(2));
		System.out.println(a.substring(1,4));

// 출력 //

cdef
bcd

charAt()
숫자형태로 저장해서 사용가능
유니코드표 확인

		String a = "0123456";
		int b = (int)(a.charAt(4));
		
		System.out.println(b);
		System.out.println(b-48);

// 출력 //

52
4




Arrays로 배열 다루기

배열 출력 메소드

Arrays.toString()
배열을 출력한다

Arrays.deepToSting()
2차원이상 배열을 출력한다

		int[] arr = {2,5,6,7,9,8,5};
		
		int[][] arr2 = {{12,23},{55,27},{36,27}};
		
		int[][][] arr3 = {{{1,2},{3,4}},{{5,6},{7,8}}};
		
		
		System.out.println(Arrays.toString(arr));
		System.out.println(Arrays.deepToString(arr2));
		System.out.println(Arrays.deepToString(arr3));
		System.out.println(Arrays.deepToString(arr3[0]));

// 출력 //

[2, 5, 6, 7, 9, 8, 5]
[[12, 23], [55, 27], [36, 27]]
[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
[[1, 2], [3, 4]]

 

배열 비교

Arrays.equal(배열1, 배열2)
1차원 배열1, 배열2를 비교

Arrays.deepEquals(배열1, 배열)
2차원이상 배열1, 배열2를 비교

		int[] arr11 = {2,5,6,7,9,8,5};
		int[] arr12 = {2,5,6,7,9,8,5};
		
		int[][] arr21 = {{12,23},{55,27},{36,27}};
		int[][] arr22 = {{12,23},{55,27},{36,27}};
		
		int[][][] arr31 = {{{1,2},{3,4}},{{5,6},{7,8}}};
		int[][][] arr32 = {{{1,2},{3,4}},{{5,6},{7,8}}};
		
		System.out.println("자체 비교 "+(arr11==arr12));
		System.out.println("1차원 equals비교 "+Arrays.equals(arr11, arr12));
		System.out.println("2차원 equals비교 "+Arrays.equals(arr21, arr22));
		// System.out.println("1차원 deep equals비교 "+Arrays.deepEquals(arr11, arr12)); 에러
		System.out.println("2차원 deep equals비교 "+Arrays.deepEquals(arr21, arr22));
		System.out.println("3차원 deep equals비교 "+Arrays.deepEquals(arr31, arr32));

// 출력 //

자체 비교 false
1차원 equals비교 true
2차원 equals비교 false
2차원 deep equals비교 true
3차원 deep equals비교 true

 

배열의 정렬

Arrays.sort(배열이름)
배열을 오름차순정령

내림차순 정렬은 Integer 참조형, String 참조형 배열만됨
Arrays.sort(배열이름, Collections.reverseOrder());

		int[] arr = {5,2,7,8,3,1};
		int[] arr2 = Arrays.copyOf(arr, arr.length);
		Integer[] arr3 = {5,2,7,8,3,1}; // 인티저 메소드로 만들어줘야 내림차순으로 정렬됨
		// 카피는 안됨
		Arrays.sort(arr2);
		Arrays.sort(arr3, Collections.reverseOrder());
		System.out.println(Arrays.toString(arr));
		System.out.println(Arrays.toString(arr2));
		System.out.println(Arrays.toString(arr3));
		System.out.println(arr);
		System.out.println(arr3);
		
		// 스트링은 복사 오름, 내림차순 다 가능함
		String[] sarr = {"백두산","한라산","설악산","지리산"};
		String[] sarr2 = Arrays.copyOf(sarr, sarr.length);
		System.out.println(Arrays.toString(sarr));
		Arrays.sort(sarr);
		Arrays.sort(sarr2, Collections.reverseOrder());
		System.out.println(Arrays.toString(sarr));
		System.out.println(Arrays.toString(sarr2));
		System.out.println(sarr);

// 출력 //

[5, 2, 7, 8, 3, 1]
[1, 2, 3, 5, 7, 8]
[8, 7, 5, 3, 2, 1]
[I@2d98a335
[Ljava.lang.Integer;@16b98e56
[백두산, 한라산, 설악산, 지리산]
[백두산, 설악산, 지리산, 한라산]
[한라산, 지리산, 설악산, 백두산]
[Ljava.lang.String;@27d6c5e0

2차이상 배열에서는 사용안됨

		int[][] arr21 = {{12,23},{55,27},{36,27}};
		Arrays.sort(arr21);

		
		System.out.println(Arrays.deepToString(arr21));

// 출력 //

출력에러 위에서는 문제 없음

객체지향 언어

프로그램이 빠른 변화를 못쫓아감
점점 복잡해지고 난해해 짐에 따라
절차적 언어 : 순서와 순번에 맞게 실행됨

절차적 언어의 장단점
컴퓨터의 처리구조와 유사하여 실행 속도가 빠르다.
구조적인 프로그래밍이 가능하다.
프로그램을 분석하기 어렵다.
유지보수나 코드의 수정이 어렵다.

객체지향언어의 장점
코드의 재사용성과 시스템의 확장이 용이
개발 및 유지보수가 용이하다.
중복 코드 제거
대형 프로그램의 작성이 용이하다.

객체지향 언어 = 기존의 언어에서 객체지향 개념 규칙 추가
object - oriented programing
핵심 4가지 특징
캡슐화 : 변수와 함수를 하나의 단위로 묶는 것을 의미, 정보 은닉
상속 : 이미 정의된 상위의 개념을 물려받아 자식에서 다시 정의할 필요가 없다.
추상화 : 불필요한 부분을 생략, 객체의 속성중 중요한 것에만 중점을 둠
다형성 : 하나의 메시지에 대해 자신이 가지고 있는 고유한 방법으로 응답함

언어를 배우면서 너무 한쪽으로 빠지면 안됨




함수(메서드)

함수의 기본
public static void 함수이름

접근제한자
public(공공의) : 모든 곳에서 접근 가능
protected(보호된) : 같은 패키지의 클래스 안에서 사용가능
상속 클래스에서만 접근가능
private(사적인) : 클래스내에서만 접근가능
default(기본) : 같은 패키지 안에서만 가능
main인 경우는 모든 메서드의 기본이기 때문에 모든 곳에서 접근가능

메모리 할당
static : 프로그램이 실행될 때 저장됨
heap : 연산이 실행될 때 저장됨

void : 반환값이 없음을 의미
return이 없음을 의미




함수, 메서드 기본

독립적이면 함수, 종속되어 있으면 메서드라고 함
크게 차이점은 없어 보이고 큰개념이 함수여서
메서드를 함수라고도 함

함수는 작업들을 묶어 놓고 이름을 붙인 것
그리고 이름을 부여해주는것
코드의 중복을 제거해줌
코드를 간결하게 해줌

	public static void main(String[] args) {
		print(6); //메서드 호출
		print(6);

	}
	//메서드 생성
	public static void print(int a) {		
        System.out.println(a);              
        
	}

// 출력 //

6
6

메서드에 값을 입력 받아서 처리하고
결과를 반환(출력)
작업에 필요한 값을 받아서 처리 결과를 줌
함수 : 상자에 입력을 해주면 결과를 반환

println() 어떻게 반응을 하는지
알고 사용하면됨

메서드의 장점
코드의 중복을 줄임
코드의 관리가 쉽다
코드를 재사용할 수 있다
코드가 간결해서 이해하기 쉬어 진다.

반복적으로 수행되는 여러문장을 메서드로 작성
여러문장으로 구성된 하나의 작업도 메서드로 만들어두면
이해하기 쉬어진다.

되도록이면 하나의 메서드는 한 가지 기능만 수행하도록 작성
나중에 코드 유지보수할때 좋고 재사용성이 높아진다.

메서드는 선언부 구현부
선언부 : 작업결과의 타입 메서드의 이름, 매개변수(입력)
매개변수는 작업에 필요한 값들이며 0~n개 사용가능
구현부 : 메서드 호출시 수행될 코드

출력은 0~1개 그러나 배열, 객체등으로 변경해서
줄수 있다.




함수의 정의

함수의 정의 : 함수를 새로 만듦
인수 : 함수를 만들때 전달할 입력값
매개변수 : 함수를 정의할때 입력해야되는 변수값
중간매개체 역활을 함
반환값 : 함수 자체적인 출력
반환타입 : 반환하는 값의 타입

반환타입은 반환값과 동일해야한다
그러나 int경우 char,byte, short는 자동형변환으로
동일하지 않지만 반환은 된다.
float도 int가 반환됨

함수의 호출
함수를 불러서 작업을 시작함
함수 이름(값1, 값2);
print(); 실행
int result = a(3,5); result변수에 a함수의 반환을 저장
int add(int x, int y);
int 출력, int 2개 입력
void는 출력이 없음 함수의 내용만 실행

1 반환 : x, 매개변수 : x

	public static void main(String[] args) {
		a();
	}
	public static void a() {
		System.out.println("hello");
	}

2 반환 : x, 매개변수 : o

	public static void main(String[] args) {
		b(3,5);
	}
    
	public static void b(int a, int b) {
		System.out.printf("%d + %d = %d\n",a,b,a+b);
	}
// 출력 //

3 + 5 = 8

3 반환 : o, 매개변수 : x

	public static void main(String[] args) {
		System.out.println(c());
	}
	public static int c() {
		return 10;
	}

// 출력 //

10

4 반환 : o, 매개변수 : o

	public static void main(String[] args) {
		System.out.println(d(10,5));
	}
	public static int d(int a, int b) {
		int c = a-b;
		return c;
	}

// 출력 //

5

return은 함수의 종료시에도 사용함

	public static void a() {
		System.out.println("hello");
		return;
		// System.out.println("java"); 에러 함수가 종료되었지만 실행
	}

함수의 실행흐름
1 main 메서드에서 함수를 정의하고
2 함수를 호출하면
3 함수가 실행되면서
4 인수가 매개변수에 대입
5 함수 add의 {}안의 문장이 순서대로 수행
6 모든 문장이 실행되거나 return문을 만나면
7 호출한 함수(main 메서드)로 되돌아와서
이후의 문장을 실행

연습문제 1.

정수를 반환하고 매개변수를 두개받는 함수 big
인자로 받은 두 수 중 더 큰 수를 반환하는 함수

	public static void main(String[] args) {
		System.out.println(big(10,5));

	}
	
	public static int big(int a, int b) {
		int big = a;
		if(big < b) {
			big = b;
		}
		return big;
	}
	
	public static int big2(int a, int b) {
		if(a>b) {
			return a;
		}
		else {
			return b;
		}
	}

// 출력 //

10

연습문제 1-2

3가지의 인수를 받아서 가장 큰것을 반환시키기

public static int m(int a1, int a2, int a3) {
		int max = a1;
		if(max<a2) {
			max = a2;
		}
		if(max<a3) {
			max = a3;
		}
		return max;		
		
	}

 

 

 

연습문제 2.

반환값은 없고 받은 인자를 바꿔주는 함수
함수안에서 실행된 변수에 대한 내용은
메인에서 영향을 주지 않는다.

	public static void main(String[] args) {
		int a = 10, b = 3;
		swap(a,b);
		System.out.printf("a = %d, b = %d",a,b);

	}
	
	public static void swap(int a, int b) {
        int temp = a;
        a = b;
        a = temp;
	}

// 출력 //

a = 10, b = 3

 

 

 

연습문제  *.

배열을 새로 만들어서 반환해주는 메서드
배열을 매개변수로 받아서 출력해주는 매서드
배열을 매개변수로 받고 int형태를 매개변수로 받아
int의 배수가 배열에 저장하는 메서드 제작

public class K1 {

	public static void main(String[] args) {
		int[] a = arr_new(5);
		arr_r(a,3);
		arr_pr(a);
		

	}
	
	public static int[] arr_new(int a1) { //배열을 int 만큼 만들어주는 메서드
		int[] arr = new int[a1];
		return arr;	
	}
	public static void arr_pr(int[] a1) { //배열 매개변수로 받아서 출력해주는 메서드
		System.out.println(Arrays.toString(a1));
	}
	public static void arr_r(int[] a1, int a2) {
		
		for(int i = 0; i<a1.length;i++) {
			a1[i] = (i+1)*a2;
			// a1[0] = (0+1)*3
			// a1[1] = (1+1)*3
			// a1[2] = (2+1)*3
			// ~~~~ a1의 길이 전 인덱스 까지
		}		
	}
	
}

 

 

연습문제  배열 변경.

배열을 전체 변경해주는 메서드
배열을 x개 변경해주는 메서드
배열을 x번째 부터 y번째까지 변경해주는 메서드

public class K1 {

	public static void main(String[] args) {
		
		int[] a = {1,2,3,4,5,6};
		int[] b = {10,20,30,40,50,60};
		m3(a,b,2,4);
		System.out.println(Arrays.toString(a));
		System.out.println(Arrays.toString(b));
	
	}
	
	public static void m(int[]a1, int[]a2) { //전체 변경
		for(int i =0; i<a1.length; i++) {
			int t = a1[i];
			a1[i] = a2[i];
			a2[i] = t;
		}
	}
	
	public static void m2(int[]a1, int[]a2, int a3) { //a3에 값만큼 배열변경
		for(int i = 0; i<a3; i++) {
			int t = a1[i];
			a1[i] = a2[i];
			a2[i] = t;
		}
	}
	
	public static void m3(int[]a1, int[]a2, int a3, int a4) { //a3에 값만큼 배열변경
		for(int i = a3-1; i<a4; i++) {
			int t = a1[i];
			a1[i] = a2[i];
			a2[i] = t;
		}
	}
	
	
}

 

 

연습문제 3.

정수로 반환하고 인자는 없는 함수
정수를 입력했을때 1부터 그 숫자까지 더해주는 함수

	public static void main(String[] args) {
		System.out.println(lsum());

	}
	
	public static int lsum() {
		Scanner sc = new Scanner(System.in);
        int sum = 0;
        System.out.print("정수를 입력하세요 >> ");
        int a = sc.nextInt();
        for (int i = 1; i<=a;i++) {
        	sum+=i;
        }
        return sum;       
        
	}

// 출력 //

정수를 입력하세요 >> 10
55

연습문제 4-1.

인수를 인트로 넣으면 매개변수가 받아
새로운 배열을 인수만큼의 크기로 만들고
배열의 값을 1~인수로 대입하여
프린트 해주는 반환없는 함수 생성

	public static void main(String[] args) {
		ar(2);
		ar(12);
		ar(15);

	}
	
	public static void ar(int a) {
		int arr[] = new int[a];
		for(int i=0;i<a;i++) {
			arr[i] = i+1;
		}
		System.out.println(Arrays.toString(arr));
        
	}

// 출력 //

[1, 2]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]

연습문제 4-2.

숫자에서 ~ 1까지 배열에 저장하는 함수
프린트 해주는 반환없는 함수 생성

public class K1 {
	public static void main(String[] args) {
		ar(2);
		ar(12);
		ar(15);

	}
	
	public static void ar(int a) {
		int arr[] = new int[a];
		int c=a;
		for(int i=0;i<a;i++) {
			arr[i] = c--;
		}
		System.out.println(Arrays.toString(arr));
        
	}
}

// 출력 //

[2, 1]
[12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

연습문제 4-3.

2의 인덱스 제곱식

public class K1 {
	public static void main(String[] args) {
		ar(2);
		ar(12);
		ar(15);

	}
	
	public static void ar(int a) {
		int arr[] = new int[a];
		int c=1;
		for(int i=0;i<a;i++) {
			arr[i] = c;
			c *= 2;
		}
		System.out.println(Arrays.toString(arr));
        
	}
}

// 출력 //

[1, 2]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048]
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384]

연습문제 4-4.

2의 배수 또는 3의 배수 저장

public class K1 {
	public static void main(String[] args) {
		ar(2);
		ar(12);
		ar(15);

	}
	
	public static void ar(int a) {
		int arr[] = new int[a];
		int c=0;
		for(int i=0;i<a;i++) {
			while(true) {
				c++;
				if(c%2==0 || c%3==0) {
					arr[i] = c;
					break;
				}
			}
		}
		System.out.println(Arrays.toString(arr));
        
	}
}

// 출력 //

[2, 3]
[2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18]
[2, 3, 4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22]

연습문제 4-5.

2의배수 또는 3의 배수 저장
그러나 5의 배수는 제외

public class K1 {
	public static void main(String[] args) {
		ar(2);
		ar(12);
		ar(15);

	}
	
	public static void ar(int a) {
		int arr[] = new int[a];
		int c=0;
		for(int i=0;i<a;i++) {
			while(true) {
				c++;
				if(c%2==0 || c%3==0) {
					if(c%5!=0) {
						arr[i] = c;		
						break;
					}
				}
			}
		}
		System.out.println(Arrays.toString(arr));        
	}
}

// 출력 //

[2, 3]
[2, 3, 4, 6, 8, 9, 12, 14, 16, 18, 21, 22]
[2, 3, 4, 6, 8, 9, 12, 14, 16, 18, 21, 22, 24, 26, 27]

 

 

연습문제 5-1.

2~9단까지 출력하는 함수
반환없고 매개변수 없음

public class K1 {
	public static void main(String[] args) {
		gugu();
	}
	
	public static void gugu() {
		for(int i = 2; i<10;i++) {
			for(int j = 1; j<10; j++) {
				System.out.printf("%dx%d=%d\t",i,j,i*j);
			}
			System.out.println();
		}
	}
}

// 출력 //

2x1=2	2x2=4	2x3=6	2x4=8	2x5=10	2x6=12	2x7=14	2x8=16	2x9=18	
3x1=3	3x2=6	3x3=9	3x4=12	3x5=15	3x6=18	3x7=21	3x8=24	3x9=27	
4x1=4	4x2=8	4x3=12	4x4=16	4x5=20	4x6=24	4x7=28	4x8=32	4x9=36	
5x1=5	5x2=10	5x3=15	5x4=20	5x5=25	5x6=30	5x7=35	5x8=40	5x9=45	
6x1=6	6x2=12	6x3=18	6x4=24	6x5=30	6x6=36	6x7=42	6x8=48	6x9=54	
7x1=7	7x2=14	7x3=21	7x4=28	7x5=35	7x6=42	7x7=49	7x8=56	7x9=63	
8x1=8	8x2=16	8x3=24	8x4=32	8x5=40	8x6=48	8x7=56	8x8=64	8x9=72	
9x1=9	9x2=18	9x3=27	9x4=36	9x5=45	9x6=54	9x7=63	9x8=72	9x9=81

연습문제 5-2.

gugu(5)하면 2~5단까지
출력하는 함수
반환없고 매개변수 없음

public class K1 {
	public static void main(String[] args) {
		gugu(5);
	}
	
	public static void gugu(int a) {
		for(int i = 2; i<a+1;i++) {
			for(int j = 1; j<10; j++) {
				System.out.printf("%dx%d=%d\t",i,j,i*j);
			}
			System.out.println();
		}
	}
}

// 출력 //

2x1=2	2x2=4	2x3=6	2x4=8	2x5=10	2x6=12	2x7=14	2x8=16	2x9=18	
3x1=3	3x2=6	3x3=9	3x4=12	3x5=15	3x6=18	3x7=21	3x8=24	3x9=27	
4x1=4	4x2=8	4x3=12	4x4=16	4x5=20	4x6=24	4x7=28	4x8=32	4x9=36	
5x1=5	5x2=10	5x3=15	5x4=20	5x5=25	5x6=30	5x7=35	5x8=40	5x9=45

 

 

 

 

 

 

 

 

 

 

 

 

 

■ 2월 20일 - 5일차

클래스

클래스 정의 : 객체를 정의해 놓은 것 (설계도)
클래스의 용도 : 클래스는 객체를 생성하는데 사용
객체의 정의 : 실제 존재하는 것 사물또는 개념
객체의 용도 : 객체가 가지고 있는 기능과 속성에 따름

 

자동차 비유
속성 : 크기, 길이, 높이, 색상, 차종
기능 : 시동켜기, 속도높이기, 기어변속 등

객체와 인스턴스
객체 : 모든 인스턴스를 대표하는 일반적인 용어
인스턴스 : 특정 클래스로부터 생성된 객체
인스턴스화 : 클래스를 가지고 객체를 생성하는것
또는 설계도를 가지고 제품을 만드는것

클래스가 필요한 이유
객체를 생성하기 위해
객체가 필요한 이유
객체를 사용하기 위해
객체를 사용한다는 것
객체가 가진 속성과 기능을 사용하려고


 

클래스 작성하기

하나의 소스파일에 여러 클래스 작성

public class K1{} 대표 클래스며 소스파일과 동일
class K2{}
두개의 public은 사용할 수 없다.

class K1{}
class K2{}
public이 없는경우 소스파일은 둘다 가능

잘못작성예시
public class가 두개
소스파일과 public class 이름이 불일치
대소문자를 구분하여 잘못 작성될 경우


 

클래스 이름변경

run configuation에서 main class 변경
Search에서는 만들어져있는 클래스 검색해줌




객체의 생성

클래스명 변수명;
변수명 = new 클래스명();

K1 c;
c라는 클래스의 객체를 참조하기 위한 참조변수선언

c = new K1();
클래스의 객체를 생성 후, 객체의 주소를 참조변수에 저장

K1 c = new K1();
선언 및 생성을 한번에 실시

int a 처럼 K1 c는 K1이라는
클레스 데이터형에 변수를 생성하는 개념
다르면 에러 발생

객체 생성 순서
1 클래스(설계도) 작성
2 객체를 생성
3 객체를 사용(변수, 메서드)

public class K1 {
	public static void main(String[] args) {
		
		Car c = new Car();
		System.out.println(c.fuel);
		c.fuelu();
		System.out.println(c.fuel);
		
	}	
}

class Car{
	int fuel;
	boolean power;
	String color;
	
	void fuelu() {
		fuel++;
	}
	void fueld() {
		fuel--;
	}
	void power() {
		power = !power;
	}
}

// 출력 //

0
1

 

객체의 생성 기본

Car c = new Car();

Car 클래스 타입의 참조변수 c를 선언한 후
새로운 Car 인스턴스를 생성해 생성한 인스턴스의
주소를 c라는 참조변수에 저장

c라는 참조변수는 새로운 인스턴스의
컨트롤러역활을 함

Car클래스에는 변수 3개
함수(메서드)3개
총 맴버는 = 6개

Car c1 = new Car();
Car c2 = new Car();
2개의 새로운 인스턴스 생성

두개의 객체는 각각의 주소를
나타내고 있으며, 그것의 객체는
각각의 변수를 생성함

public class K1 {
	public static void main(String[] args) {
		
		Car c1 = new Car();
		Car c2 = new Car();
		c1.fuel = 10;
		System.out.println("c1 = "+c1.fuel+"  c2 = "+c2.fuel);
		
		
	}	
}

class Car{
	int fuel;
	boolean power;
	String color;
	
	void fuelu() {
		fuel++;
	}
	void fueld() {
		fuel--;
	}
	void power() {
		power = !power;
	}
}

// 출력 //

c1 = 10  c2 = 0

 

참조변수의 통제

Car c1 = new Car();
Car c2 = new Car();
c2 = c1;

c2 = c1
c2의 주소값 즉 컨트롤러를
c1에게 넘겨줌
즉 c1과, c2가 c1에서 만들어놓은
객체를 통제함

c2에서 만들어진 객체를
통제할 수 있는 참조변수가 없음
메모리만 차지하고 있지만
정리해주는 프로그램도 있음

garbage collector
가비지 컬렉터
사용하지 않은 메모리를 스스로 찾아서
지워줌 Java에서만 지원해주고 있음

 

객체 배열

객체 배열 == 참조변수 배열
Car c1, c2, c3
Car[] carr = new Car[3]
3개를 만들경우 일일히 만들어야 하는데
배열형태로 전체를 통제할 수 있도록 만듬

int[] arr = new int[3]
Car[] carr = new Car[3]
일반적인 인트 배열의 개수 생성과 동일하다

Car[] carr = new Car[3]
길이가 3인 Car타입의 참조변수 배열 생성
carr[0] = new Car()
carr[1] = new Car()
carr[2] = new Car()
객체를 생성해서 배열의 각 요소에 저장

Car[] carr = {new Car(), new Car(), new Car()}
int[] arr = {1,2,3,4,5}
일반적인 인트 배열과 생성, 초기화 방식은 동일하다

Car[] carr
carr이라는 참조변수에 배열주소가 저장
배열 주소에 carr[0]의주소
carr[1]의주소, carr[2]의주소가저장되며
그것은 new Car()로 객체의 주소가 저장

Car 타입의 배열 생성

public class K1 {
	public static void main(String[] args) {
		
		Car[] carr = new Car[3];
		carr[0] = new Car();
		carr[1] = new Car();
		carr[2] = new Car();
		
		carr[0].fuel = 1;		
		carr[1].fuel = 5;		
		carr[2].fuel = 15;
		
		System.out.printf("car[0] = %d, car[1] = %d, car[2] = %d"
				,carr[0].fuel,carr[1].fuel,carr[2].fuel );
			
	}	
}

class Car{
	int fuel;
	boolean power;
	String color;
	
	void fuelu() {
		fuel++;
	}
}

// 출력 //

car[0] = 1, car[1] = 5, car[2] = 15

 

Car타입의 for문 형식 1

public class K1 {
	public static void main(String[] args) {
		
		Car[] carr = new Car[3];
		
		for(int i=0; i<carr.length; i++) {
			carr[i] = new Car();
		} // carr에 Car() 객체 주소 저장 for문
		
		System.out.println(Arrays.toString(carr));
		// Arrays.toString으로 어레이 확인
		int[] a = new int[3];
		// System.out.println(Arrays.deepToString(a));
		// 에러 1차 배열로 deep은 2차배열 이상만 불러들임
		System.out.println(Arrays.deepToString(carr));
		//carr[0]는 car()객체 주소를 참조하고 있기때문에
		//deep을 넣어도 이상은 없음
	}	
}

class Car{
	int fuel;
	boolean power;
	String color;
	
	void fuelu() {
		fuel++;
	}
}

// 출력 //

[javapj.Car@7a81197d, javapj.Car@5ca881b5, javapj.Car@24d46ca6]
[javapj.Car@7a81197d, javapj.Car@5ca881b5, javapj.Car@24d46ca6]

 

객체 fuel에 int입력, print에 대한
for문형식

Car타입의 for문 형식 2

public class K1 {
	public static void main(String[] args) {
		
		Car[] carr = new Car[3];
		
		for(int i=0; i<carr.length; i++) {
			carr[i] = new Car();
		} 
		
		int c = 1;
		for(int i=0; i<carr.length; i++) {
			// carr[i] = c; 에러 carr[i] = Car타입 c = int 타입
			carr[i].fuel = c;
			c *= 5;
		}
		
		for(int i =0; i<carr.length; i++) {
			System.out.printf("carr[%d] = %d  ",i,carr[i].fuel);
		}
		
	}	
}

// 출력 //

carr[0] = 1  carr[1] = 5  carr[2] = 25 

 

변수의 종류

선언 위치에 따른 변수의 종류

class K2{
	
	int a = 0; //인스턴스 변수 -- 객체를 만들때 생성된다.
	//객체마다 다른 주소로 가지고 있다.
	//객체가 없어질때 사라진다.
	static int b = 1; //클래스 변수 -- 설계도가 메모리에 올라갈때 생성
	//모든 객체가 공유하고 있다.
	//메모리에 내려올때, 실행 종료시.
	void m(int a) { //매개변수 메서드를 실행할때 생성, 종료할때 사라진다.
		int c = a; //지역변수 메서드를 실행할떄 생성, 종료할때 사라진다.
		System.out.println(c);
	}
	
}

 

 

클래스 영역 = 클래스의 시작과 끝
class Var{
}

메서드 영역 = 메서드의 시작과 끝
void method(){
}

클래스 영역 : 인스턴스 변수, 클래스 변수
메서드 영역 : 지역변수

CPU 에서 저장장치(SSD,HDD)를
바로 읽어들일 수 없다. CPU의 처리 속도가
너무 빠르기 때문에
RAM(메모리)이 중간에서 저장장치를
읽어 CPU에 보내준다.

클래스 변수는 RAM 즉 메모리에
올라가면 바로 사용할 수 있다.

public class K1 {
	public static void main(String[] args) {
		
		System.out.println(Var.cv);
        //에러 System.out.println(Var.iv);
		//에러 System.out.println(Var.lv);
	}
}

class Var{
	int iv;
	static int cv;
	
	void method() {
		int lv;
	}
}

// 출력 //

0

스택(Stack) 밑이 막힌 상자를 위에서부터 쌓고
위에서부터 빼낸다

호출스택(Call Stack)
메서드 수행에 필요한 메모리가 제공되는 공간
메서드가 호출 되면 호출 스택에 메모리 할당
종료되면 해제

 

	public static void main(String[] args) {
		
		System.out.println("hello");
		
	}


 

순서도
1 메인 함수 실행
2 프린트 메서드 실행, 메인함수는 대기
3 프린트 메서드 실행 후 종료
4 메인 함수 실행
5 메인 함수 종료



 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

■ 2월 21일 - 6일차

함수의 매개변수와 지역변수의 혼합

메서드 안에서 매개변수와
동일한 이름의 지역변수를 만들수 없다

if문에서 만든 지역변수를
else if에서 쓸수 없다

초기화 되지 않은 지역변수를
프린터 할수 없다

클래스의 변수는 (클래스변수, 인스턴스변수)
생성되어 지면서 초기화 된다 배열과 동일하게보면됨

public class K1 {
	public static void main(String[] args) {
		
		Var v = new Var();
		v.iv1 =2;
		v.f(1); // 2+1 *10
		v.f(2); // 2-1 *20
		v.f(5); // 0
		
	}
}

class Var{
	int iv1 = 1;
	int iv2 = 1;
	static int cv = 10;
	
	void f(int a) {
		int p;
		if (a==1) {
			// int a;
			//에러 매개변수와 동일한 이름임 
			int a1 = 10;
			p = (iv1 + iv2)*a1;
			//f함수의 지역변수 p를 통제
		}
		else if (a==2) {
			int a1 = 20;
			// if문 에서의 지역변수임 else if는에서는 사용가능
			p = (iv1 - iv2)*a1;
		}
		// System.out.println(p);	//에러 초기화 안됨
		// 인스턴스변수는 자동적으로 초기화 됨 기본값으로
		else { //if문 중간에 다른 식이 있고 else하면 오류
			p=0;
		}
		System.out.println(p);
	}	
}

// 출력 //

30
20
0



변수종류관련 연습문제

연습문제 1-1

다음과 같이 메인함수를 사용했을때
출력될 수 있도록
클래스 변수와 인스턴스 변수를 선언하시오

	public static void main(String[] args) {
		C c1 = new C();
		C c2 = new C();
		c1.a = 1;
		c1.b = 2;
		System.out.println("c1 a = "+c1.a+" b = "+c1.b);
		System.out.println("c2 a = "+c2.a+" b = "+c2.b);
	}

// 출력 //

c1 a = 1 b = 2
c2 a = 0 b = 2

연습문제 1-1 정답

public class K1 {
	public static void main(String[] args) {
		C c1 = new C();
		C c2 = new C();
		c1.a = 1;
		c1.b = 2;
		System.out.println("c1 a = "+c1.a+" b = "+c1.b);
		System.out.println("c2 a = "+c2.a+" b = "+c2.b);
	}
}

class C{
	int a;
	static int b;
}

// 출력 //

c1 a = 1 b = 2
c2 a = 0 b = 2

 

연습문제 1-2

출력을 할 수 있는 pr() 함수를
만들어보기
반환은 없고 스트링으로 받아서
클래스내 함수 출력

	public static void main(String[] args) {
		C c1 = new C();
		C c2 = new C();
		c1.a = 1;
		c1.b = 2;
		c1.pr("c1");
		c2.pr("c2");
		
	}

// 출력 //

c1 a = 1, b = 2
c2 a = 0, b = 2

연습문제 1-2 정답

public class K1 {
	public static void main(String[] args) {
		C c1 = new C();
		C c2 = new C();
		c1.a = 1;
		c1.b = 2;
		c1.pr("c1");
		c2.pr("c2");
		
	}
}

class C{
	int a;
	static int b;
	void pr(String x) {
		System.out.printf("%s a = %d, b = %d%n",x,a,b);
	}
}

// 출력 //

c1 a = 1, b = 2
c2 a = 0, b = 2

 

연습문제 1-3

클래스 배열을 만들고
배열의 매개변수는 c로하고
객체를 5개 생성하시오
for문으로

	public static void main(String[] args) {
		
		C[] c = new C[5];
		
		for (int i = 0; i<c.length;i++) {
			c[i] = new C();
		}
		
	}


 

연습문제 1-4

a라는 인스턴스 변수에
1~5 저장하는 for문만들기

	public static void main(String[] args) {
		
		C[] c = new C[5];
		
		for (int i = 0; i<c.length;i++) {
			c[i] = new C();
		}
		
		for (int i = 0; i<c.length;i++) {
			c[i].a = i+1;
		}
		
	}


 

연습문제 1-5

동일한 for문을 하나로 만들고
pr()을 for문과 연동시켜서
c[0] a = 1, b = 0 반복해서 출력되도록 하기
System.out.println("a"+"b"+1) 여기서
"a"+"b"+1 = ab1로 하나의 스트링임

	public static void main(String[] args) {
		
		C[] c = new C[5];
		
		for (int i = 0; i<c.length;i++) {
			c[i] = new C();
			c[i].a = i+1;
			c[i].pr("c["+i+"]");
		}
	}

// 출력 //

c[0] a = 1, b = 0
c[1] a = 2, b = 0
c[2] a = 3, b = 0
c[3] a = 4, b = 0
c[4] a = 5, b = 0

 

 


 

연습문제 1-6

클래스는 건들지 않은상태로
c[0] a = 1, b =0
에서 b = a*2형태로 출력
예시
a = 1 b = 2
a = 2 b = 4

	public static void main(String[] args) {
		
		C[] c = new C[5];
		
		for (int i = 0; i<c.length;i++) {
			c[i] = new C();
			c[i].a = i+1;
			C.b = c[i].a * 2;
			// c[i].b = c[i].a * 2; 이것도 됨
            c[i].pr("c["+(i)+"]");
		}
	}

// 출력 //

c[0] a = 1, b = 2
c[1] a = 2, b = 4
c[2] a = 3, b = 6
c[3] a = 4, b = 8
c[4] a = 5, b = 10

보여지는 것은 2~10으로 보여지지만
현재 모든 객체의 b 값은 10임


연습문제 2-1

클래스 C생성
클래스 변수로 int 타입
인스턴스 변수로 int[] 선언
배열의 개수는 클래스 변수 int의 값을 받음

public class K1 {
	public static void main(String[] args) {
	
		C c = new C();
		System.out.println(Arrays.toString(c.arr));
		
	}
}

class C{
	static int a;
	int[] arr = new int[a];
}

// 출력 //

[]

 

연습문제 2-2

3개 짜리 배열을 생성하게 끔
메인 함수에 추가하시오

	public static void main(String[] args) {
		C.a = 3;
		C c = new C();
		System.out.println(Arrays.toString(c.arr));
		
	}

// 출력 //

[0, 0, 0]

 

연습문제 2-3

prarr()하면 arr이 출력되게
함수를 작성하시오

public class K1 {
	public static void main(String[] args) {
		C.a = 3;
		C c = new C();
		c.prarr();
		
	}
}

class C{
	static int a;
	int[] arr = new int[a];
	void prarr() {
		System.out.println(Arrays.toString(arr));
	}
}

// 출력 //

[0, 0, 0]

 

연습문제 2-4

두번째 객체는 5개짜리 배열이 생성되도록 하시고
새로운 객체를 만드시오

클래스 변수를 변경하고
새로운 객체를 생성하면
자연스럽게 클래스 변수의 변화에 따라 연동

	public static void main(String[] args) {
		C.a = 3;
		C c1 = new C();
		// c1.a = 5; 동일
		C.a = 5;
		C c2 = new C();
		
		c1.prarr();
		c2.prarr();
		
	}

// 출력 //

[0, 0, 0]
[0, 0, 0, 0, 0]


연습문제 2-5

클래스 배열을 3개 만들고
클래스 배열안의 각 객체 배열은 3,6,9사이즈로 만드시오
배열 출력도 가능하게 for문을 구성

	public static void main(String[] args) {
		
		C[] c = new C[3];
		int size = 3;
		for(int i = 0; i<c.length;i++) {
			C.a = size;
			c[i] = new C();
			size += 3;
			c[i].prarr();
		}
		
	}

// 출력 //

[0, 0, 0]
[0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0]

 

연습문제 2-6

0~9까지의 랜덤한 값이 각각의 배열에 저장되도록하고
프린터해주는 for문은 따로 만드시오

Math.random() 은 0.xxx ~ 1까지의 랜덤
(int)Math.random()은 인트로 변경해줌
(int)Math.random()*9 ??

public class K1 {
	public static void main(String[] args) {
		
		C[] c = new C[3];
		int size = 3;
		for(int i = 0; i<c.length;i++) {
			C.a = size;
			c[i] = new C();
			size += 3;
			for(int j=0; j<c[i].arr.length;j++) {
				c[i].arr[j]=(int)(Math.random()*10);
			}
		}
		
		for(int i = 0; i<c.length;i++) {
			c[i].prarr();
		}
		
	}
}

// 출력 //

[0, 5, 5]
[1, 1, 4, 1, 2, 6]
[5, 8, 2, 3, 1, 2, 8, 5, 9]


 

 

연습문제 2-7

1 ~ 10까지로 랜덤을 변경해 보기

			for(int j=0; j<c[i].arr.length;j++) {
				c[i].arr[j]=(int)(1+Math.random()*10);
			}

// 출력 //

[2, 2, 9]
[4, 2, 6, 9, 7, 4]
[5, 3, 3, 8, 7, 1, 5, 10, 1]

 

연습문제 2-8

평균 출력 새로 for문에 작성
또는 출력 되는 for 문에 작성해도 됨

		for(int i = 0; i<c.length;i++) {
			int s = 0;
			for(int j = 0; j<c[i].arr.length;j++) {
				s += c[i].arr[j];
			}
			System.out.printf("평균 : %.2f%n",(float)s/c[i].arr.length);
			c[i].prarr();
			
		}

// 출력 //

평균 : 5.67
[9, 6, 2]
평균 : 5.83
[2, 4, 9, 7, 10, 3]
평균 : 5.67
[1, 1, 8, 9, 8, 4, 10, 1, 9]

 

연습문제 2 전체

public class K1 {
	public static void main(String[] args) {
		
		C[] c = new C[3];
		int size = 3;
		for(int i = 0; i<c.length;i++) {
			C.a = size;
			c[i] = new C();
			size += 3;
			for(int j=0; j<c[i].arr.length;j++) {
				c[i].arr[j]=(int)(1+Math.random()*10);
									
			}
		}
		for(int i = 0; i<c.length;i++) {
			int s = 0;
			for(int j = 0; j<c[i].arr.length;j++) {
				s += c[i].arr[j];
			}
			System.out.printf("평균 : %.2f%n",(float)s/c[i].arr.length);
			c[i].prarr();
			
		}
		
		
	}
}

class C{
	static int a;
	int[] arr = new int[a];
	void prarr() {
		System.out.println(Arrays.toString(arr));
	}
}



연습문제 3-1

클래스를 3개의 인트형 변수로
제작하였고 다음과 같이 메인을
작성해보니 아래와 같은 결과가 나왔다.
a,b,c는 각각 어떤 형태의 변수 인지 생각해보고
클래스를 작성해 보세요

	public static void main(String[] args) {
		
		C.a = 10;
		C c1 = new C();
		c1.a = 5;
		C c2 = new C();
		c1.b = 5;
		
		System.out.printf("c1 a = %d, b = %d, c = %d%n",c1.a,c1.b,c1.c);
		System.out.printf("c2 a = %d, b = %d, c = %d%n",c2.a,c2.b,c2.c);		
	}

// 출력 //

c1 a = 5, b = 5, c = 10
c2 a = 5, b = 1, c = 5

연습문제 3-1 정답

class C{
	static int a;
	int b=1;
	int c = a;

}

 

연습문제 3-2

	public static void main(String[] args) {
		
		C.a = 10;
		C c1 = new C();
		c1.a = 5;
		C c2 = new C();
		c1.b = 5;
		
		System.out.printf("c1 a = %d, b = %d, c = %d%n",c1.a,c1.b,c1.c);
		System.out.printf("c2 a = %d, b = %d, c = %d%n",c2.a,c2.b,c2.c);		
	}

// 출력 //

c1 a = 5, b = 5, c = 12
c2 a = 5, b = 2, c = 7

연습문제 3-2 정답

class C{
	static int a;
	int b=2;
	int c = a+b;

}

 

매개변수 및 반환타입

 

기본형 매개변수

기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.

class Data{int x;}

public class K1 {
	public static void main(String[] args) {
		Data d = new Data();
		System.out.println("Data클래스 실행 : "+d.x);
		d.x = 10;
		System.out.println("x값 변경 : "+d.x);
		
		// ch함수를 static으로 하지 않았을때 설정해줘야함
		// K1 k = new K1();
		// k.ch(d.x);
		
		ch(d.x);
		System.out.println("ch이후 x값 확인 : "+d.x);
	
	}
	
	static void ch(int x) {
		x = 1000;
		System.out.println("ch함수 실행 x : "+x);
	}
	
}

// 출력 //

Data클래스 실행 : 0
x값 변경 : 10
ch함수 실행 x : 1000
ch이후 x값 확인 : 10

Data d = new Data();
Data타입으로 d라는 매개변수를 만들고
매개변수 d에 Data() 객체를 만들어서 저장

d.x=10;
d에 저장된 Data의 객체의 변수 x값을 변경

ch(d.x);
ch의 함수를 실행 시키는데
인수를 d.x로 지정

static void ch(int x)
ch함수가 실행될데 int x라는 매개변수를 받는데
그 int x가 d.x의 값을 받음

x = 1000;
받은 x라는 변수에 1000을 대입
이때 프린트 되는 것은 매개변수에서 받은 값이
1000으로 바뀌어서 실행되는 것이고
함수 이후에서는 본래 10이 저장된 d.x를 출력

ch(int x) - ch(d.x)
주소를 받는 것이 아니라
d.x의 값을 받는 모습으로
x = 1000;
으로 값을 변경한다고해서
d.x는 변경되는 것이 아님


 

참조형 매개변수

변수의 값을 읽고 변경할 수 있다.

class Data{int x;}

public class K1 {
	public static void main(String[] args) {
		Data d = new Data();
		System.out.println("Data클래스 실행 : "+d.x);
		d.x = 10;
		System.out.println("x값 변경 : "+d.x);
		
		ch(d);
		System.out.println("ch이후 x값 확인 : "+d.x);
	
	}
	
	static void ch(Data x) {
		x.x = 1000;
		System.out.println("ch함수 실행 x : "+x.x);
	}
	
}

// 출력 //

Data클래스 실행 : 0
x값 변경 : 10
ch함수 실행 x : 1000
ch이후 x값 확인 : 1000

Data d = new Data();
Data타입으로 d라는 매개변수를 만들고
매개변수 d에 Data() 객체를 만들어서 저장

d.x=10;
d에 저장된 Data의 객체의 변수 x값을 변경

ch(d);
ch의 함수를 실행 시키는데
인수를 d로 지정

static void ch(Data x)
Data 타입의 x라는 매개변수를 받음
int a는 int타입의 a라는 매개변수를 받음
ch함수가 실행될데 Data x라는 매개변수를 받는데
그 Data x가 d의 값을 받음 즉 주소값을 받음

x.x = 1000;
받은 x에서 자신이 가르키는 x 변수에 1000을 대입
이때 프린트 되는 것은 x라는 주소가 가르키는
x의 값을 1000으로 변경해서 그것을 프린트
이후 프린트는 d라는 참조변수가 가르키는 x를 프린트

 

연습문제 1-1

int a, String b로 클래스 C 만들고
메인에 C클래스 타입으로 5개짜리 배열 만들기
K1클래스에 함수 ist_m만들기
인스턴스 만드는 함수 제작

package javapj;

import java.util.*;

class C{
	int a;
	String b;
	
}
public class K1{

	public static void main(String[] args) {
			C[] c = new C[5];		
	}
	
	static void ist_m(C[] x) {
		for (int i = 0; i<x.length;i++) {
			x[i] = new C();
		}
	}	
}

 

연습문제 1-2

a,b를 출력하는 함수 제작
ist_pr
1번째 데이터 a, 과일이름

	static void ist_pr(C[] x) {
		for (int i = 0; i<x.length;i++) {
			System.out.printf("%d번째 데이터 %d, 과일이름 : %s\n",i+1,x[i].a,x[i].b);
		}
	}

 

연습문제 1-3

데이터를 입력하는 함수 제작
a에 4의 배수이면서 6의 배수의 수를
입력

	static void ist_d(C[] x) {
		int c=0;
		for (int i=0; i<x.length;i++) {
			while(true) {
				c++;
				if (c%4==0 && c%6==0) {
					x[i].a = c;
					break;
				}
			}				
		}
	}

 

연습문제 1-4

과일이름을 입력받아서 저장
5글자 이상은 범위를 벗어났습니다. 출력
1번째 과일이름 작성 : 사과딸기기타
범위를 벗어났습니다.
1번째 과일이름 작성 : 사과가좋아죽게다
범위를 벗어났습니다.
1번째 과일이름 작성 : 사과
2번째 과일이름 작성 : 바나나
3번째 과일이름 작성 : 파인에플
4번째 과일이름 작성 : 배
5번째 과일이름 작성 : 수박
1번째 데이터 12, 과일이름 : 사과
2번째 데이터 24, 과일이름 : 바나나
3번째 데이터 36, 과일이름 : 파인에플
4번째 데이터 48, 과일이름 : 배
5번째 데이터 60, 과일이름 : 수박

총계

package javapj;

import java.util.*;

class C{
	int a;
	String b;
	
}
public class K1{

	public static void main(String[] args) {
			C[] c = new C[5];
			ist_m(c);
			ist_d(c);
			ist_f(c);
			ist_pr(c);
	}
	
	static void ist_m(C[] x) {
		for (int i = 0; i<x.length;i++) {
			x[i] = new C();
		}
	}
	
	static void ist_d(C[] x) {
		int c=0;
		for (int i=0; i<x.length;i++) {
			while(true) {
				c++;
				if (c%4==0 && c%6==0) {
					x[i].a = c;
					break;
				}
			}				
		}
	}
	
	static void ist_f(C[] x) {
		Scanner sc = new Scanner(System.in);
		String a;
		for (int i=0; i<x.length;i++) {
			while(true) {
				System.out.printf("%d번째 과일이름 작성 : ",i+1);		
				a = sc.next();
				if (a.length()<5) {
					x[i].b = a;
					break;
				}
				else {
					System.out.println("범위를 벗어났습니다.");
				}
			}
		}
	}
	
	static void ist_pr(C[] x) {
		for (int i = 0; i<x.length;i++) {
			System.out.printf("%d번째 데이터 %d, 과일이름 : %s\n",i+1,x[i].a,x[i].b);
		}
	}
}

 

 

 

클래스 추가 삭제 등 다른형태의 클래스 구조

 

 

package pj;

import java.util.Arrays;
import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {
		A[] ca = new A[3];
		cli(ca);
		inp2(ca,"사과",20,0);
		inp2(ca,"배",30,1);
		inp2(ca,"감",40,2);
		pm(ca,"감",-20);
		ca = addc(ca,"자두",20);
		ca = delc(ca,"배");
		pr(ca);		
	}
	static A[] delc(A[] x1, String x2) {
		A[] na = new A[x1.length-1];
		int c = 0;
		for(int i = 0; i<x1.length; i++) {
			if(x1[i].s.equals(x2)) {
				continue;
			}
			na[c++] = x1[i];
		}
		return na;
	}
	static A[] addc(A[] x1, String x2, int x3) {
		A[] na = new A[x1.length+1];
		for(int i = 0; i<x1.length; i++) {
			na[i] = x1[i];
		}
		na[x1.length] = new A();
		na[x1.length].s = x2;
		na[x1.length].iv = x3;
		return na;
	}
	static void pm(A[] x1, String x2,int x3) {
		for(int i = 0; i<x1.length;i++) {
			if(x1[i].s.equals(x2)) {
				x1[i].iv+=x3;
			}
		}
	}
	static void cli(A[] x) {
		for(int i = 0; i<x.length;i++) {
			x[i] = new A();
		}
	}
	static void inp(A[] x) {
		Scanner sc = new Scanner(System.in);
		System.out.println("배열의 개수 : "+x.length);
		for(int i = 0; i<x.length; i++) {
			System.out.print("개수 >> ");
			x[i].iv = sc.nextInt();
			System.out.print("과일명 >> ");
			x[i].s = sc.next();
		}
	}
	static void inp2(A[] x1, String x2, int x3, int x4) {
		x1[x4].s = x2;
		x1[x4].iv = x3;
	}
	static void pr(A[] x) {
		for(int i = 0; i<x.length; i++) {
			System.out.print(x[i].s+"("+x[i].iv+")   ");		
		}
		System.out.println();
	}
}
class A{
	int iv;
	String s;
}

 

 

 

 

 


연습문제 2

클래스를 만들어서
메서드로 몇자리인지 상관없는 값을 주면
인스턴스 변수 배열이 개수에 맞게 만들어지고
1자리씩 배열에 저장

다른 클래스 자리수 출력
1의 자리 x
10의 자리 x

 

public class K1 {

	public static void main(String[] args) {
		K2 a = new K2();
		a.m(4158125);
		K3.pr(a);
	}
}

class K2{
	int[] arr;
	void m(int a) {
		int b = 0;
		for(int i = a; i>0; i/=10) { // 자리수를 찾는다.
			b++;
		}
		arr = new int[b]; // 자리에 맞게 배열 만들기
		for(int i = a; i>0; i/=10) { //1의 자리부터 뒤에 넣기
			arr[--b] = i%10;
		}
	}	
}

class K3{
	static void pr(K2 a) {
		String[] c = {"일","십","백","천","만","십만","백만","천만"};
		int b = 0;

		for(int i = a.arr.length-1; i>=0; i--) {
			System.out.println(c[b++]+"의 자리 "+a.arr[i]);
			
		}
	}
}

 

 

 

 

 


배열이 증가되면서 데이터를  추가로  저장하는 클래스

package pj;

import java.util.Arrays;
import java.util.Scanner;

public class K1 {
	
	public static void main(String[] args) {
		
		K2.play();
		
		
	}
}

class K2{
	static Scanner sc = new Scanner(System.in);
	static int[] arr = new int[1];
	static int c = 0;
	static void m(int a) {
		int[] n = new int[c+1];
		
		for(int i = 0; i < c; i++) {
			n[i] = arr[i];
		}
		arr = n;
		
		arr[c++] = a;
	}
	static void ch() {
		while(true) {
			if(c==0) {
				System.out.println("비어 있습니다.");
				break;
			}
			pr();
			System.out.print("어떤것을 변경 할까요 >> ");
			int a = sc.nextInt();
			if(a<0 || a>=c) {
				System.out.println("인덱스를 벗어났습니다.");
			}
			else {
				System.out.print(arr[a]+"을 무엇으로 >> ");
				arr[a] = sc.nextInt();				
			}
			break;				
		}			
	}
		
	static void del() {
		while(true) {
			if(c==0) {
				System.out.println("비어 있습니다.");
				break;
			}
			pr();
			System.out.print("어떤것을 삭제 할까요 >> ");
			int a = sc.nextInt();
			if(a<0 || a>=c) {
				System.out.println("인덱스를 벗어났습니다.");
			}
			else {
				int[] n = new int[c-1];
				int z = 0;
				for(int i = 0; i<c; i++) {
					if(i==a) {
						System.out.println(arr[i]+"을 삭제합니다.");
						continue;
					}
					n[z++] = arr[i];
				}
				arr = n;
				c--;
				break;
				
			}
			
		}
		
	}
	static void pr() {
		System.out.println(Arrays.toString(arr));
	}
	static void play() {
		System.out.println("프로그램을 시작합니다.");
		for(;;) {
			System.out.println();
			System.out.println("메뉴 1.입력 2.출력 3.삭제 4.변경 5.종료");
			System.out.print("선택 >> ");
			int mu = sc.nextInt();
			switch(mu) {
			case 1:
				System.out.print("입력 해주세요 >> ");
				m(sc.nextInt());
				break;
			case 2:
				pr();
				break;
			case 3:
				del();
				break;
			case 4:
				ch();
				break;
			case 5:
				return;
			}
		}
	}
}

 

 

오버로딩(overloading)

한 클래스 안에 같은 이름의 메서드 여러개 정의
overloading 과적하다

본래 메서드 : 메서드 이름은 1:1
이름은 같고 매개변수가 다양한것

println의 인수를 보고 거기에 맞게 변경
컴파일이 어떤 인수를 판단해서
매칭시켜줌

void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(String x)

오버로딩이 없었더라면 메서드의 이름이 바뀌었을 것이다.

void println()
void println_bool(boolean x)
void println_ch(char x)
void println_charr(char[] x)
void println_fl(float x)
void println_in(int x)
void println_lg(long x)
void println_st(String x)

 

오버로딩의 성립 조건

1 메서드의 이름이 같아야한다.
2 매개변수의 개수 또는 타입이 달라야한다.
3 반환타입은 영향 없다.

이름은 같고 매개변수 개수도 같다. 타입도 같다
변수이름만 다름
이런경우 오버로딩 아님 / 메서드 중복 정의
컴파일 에러 (이미 정의되어 있다)

int add(int a, int b){return a+b;}
int add(int x, int y){return x+y;}

이름은 같고 반환타입이 다름 / 메서드 중복 정의

int add(int a, int b){return a+b;}
long add(int a, int b){return (long)(a+b);}

이름 같고 매개변수 타입이 다름 성립 / 오버로딩

int add(int a, int b){return a+b;}
int add(long a, int b){return (int)(a+b);} //int없으면 에러 반환타입
// long 반환타입설정하고 int로 반환해도 상관없음

만약 add(2,3)을 불러들이면
어떤건지 컴파일이 판단할 수 없다
add(2,3L)하면 첫번째거 불러들임

long add(int a, long b){return a+b;}
long add(long a, int b){return a+b;}

ambigus(모호한)

public class K1{

	public static void main(String[] args) {
		K1 k = new K1();
		long a = k.add(2,3); //에러 모호한 
	}
	
	long add(int a, long b){return a+b;}
	long add(long a, int b){return a+b;}
	
}

 


생성자, 기본생성자

생성자(constructor) : 건설자

인스턴스가 생성될 때마다 호출 되는
인스턴스 초기화 메서드

객체는 인스턴스 변수 묶음

객체 생성 하고 인스턴스변수 초기화 해주었는데
한번에 즉 생성과 동시에 초기화 혹은 값을 넣어서
객체를 생성하는데 생성자가 쓰인다.

Time t = new Time();
t.h = 12;
t.m = 20;
t.s = 52;
Time t = new Time(12, 20, 52);

생성자 호출
Time();, Time(12, 20, 52);

생성자 : 인스턴스 생성시 수행할 작업에 사용

꼭 초기화만 할 필요는 없다.
일반적으로 생성자가 하는 일은 인스턴스 초기화 지만
원하는 작업들을 넣어서 사용할 수 도 있다. (메서드 니까)

생성자를 만들어주지 않으면 기본적으로
컴파일러가 생성자를 자동으로 세팅 해줘서
인스턴스를 생성함.

생성자는 인스턴스 초기화를 편리하게 하거나
추가적으로 생성될 때 필요한 작업을 하기 위해

 

생성자 작성간 주의사항

1 이름이 클래스 이름과 같아야 한다.
2 리턴값이 없다(void 안붙임) : 대입문이기 때문에 리턴이 없음
3 모든 클래스는 반드시 생성자를 가져야 한다.

클래스 이름(타입 변수명, 타입변수명){
인스턴스 생성시 수행될 코드
}

매개변수가 있는 생성자든, 매개변수가 없는 생성자 차이

오버로딩으로 둘다 생성자를 만들어 줘도 됨

리턴값이 없는 것은
반환값이 없어서 void를 안붙인것 확인
일반적인 규칙임

Time t = new Time();
Time() <- 자체가 생성자를 호출하는 것이다.
컴파일러가 기본생성자를 자동으로 만들어 준것임

 

기본 생성자

매개변수가 없는 생성자
생성자가 하나도 없을 때만 컴파일러가 자동추가
다른 생성자를 만들어 주면 기본생성자를 추가 시키지 않음

생성자가 하나도 없으면 컴파일러가 자동추가

class Cl1{
	int a;	
}
class Cl2{
	int a;
	
	Cl2(int x){
		a = x;
	}
}
public class K1{

	public static void main(String[] args) {
		Cl1 c1 = new Cl1();
		// Cl2 c2 = new Cl2(); // compile error
		// 생성자를 찾을 수 없다.
	}	
}

 

문제 해결

class Cl1{
	int a;	
}
class Cl2{
	int a;
	
	Cl2(){
		a = 0;
	}
	
	Cl2(int x){
		a = x;
	}
}
public class K1{

	public static void main(String[] args) {
		Cl1 c1 = new Cl1();
		Cl2 c2 = new Cl2();
	}	
}



매개변수가 있는 생성자

class Time{
	int h;
	int m;
	int s;
	
	Time(){}
	Time(int a, int b, int c){
		h=a;
		m=b;
		s=c;
	}	
}

public class K1{

	public static void main(String[] args) {
		Time t1 = new Time();
		Time t2 = new Time(3,20,10);
		
		System.out.printf("t1 = %d:%d:%d\n",t1.h,t1.m,t1.s);
		System.out.printf("t2 = %d:%d:%d",t2.h,t2.m,t2.s);

	}	
}

// 출력 //

t1 = 0:0:0
t2 = 3:20:10

 

 

 

도서관리 시스템

package pj;

import java.util.Arrays;
import java.util.Scanner;

public class K1 {

	public static void main(String[] args) {
		Librarymg ls = new Librarymg(10);
		ls.larr[0] = new Library("자바",10,12000);
		ls.larr[1] = new Library("c언어",20,8000); 
		ls.larr[2] = new Library("프로그래밍 기초",6,20000); 
		ls.larr[3] = new Library("파이썬",12,5000);
		ls.play();
	}
		
}
class Library{
	static int ix; // 책정보 몇개 
	int id;
	String title;
	int a;
	int pr;
	Library(String x, int y, int z){
		id = ++ix;
		title = x;
		a = y;
		pr = z;
	}	
}

class Librarymg {
	Library[] larr;
	Scanner a = new Scanner(System.in);
	Librarymg(int x){
		larr = new Library[x];
	}
	void print() {
		for(int i = 0; i<Library.ix;i++) {
			System.out.println(larr[i].id+"번 "+larr[i].title+" "+larr[i].a+"권 "+larr[i].pr+"원");
		}
	}
	void add() {
		
		System.out.print("도서명 >> ");
		String a1 = a.next();
		System.out.print("몇권 >> ");
		int a2 = a.nextInt();
		System.out.print("가격 >> ");
		int a3 = a.nextInt();
		larr[Library.ix] = new Library(a1, a2, a3);		
	}
	int totala() {
		int s = 0;
		for(int i =0; i<Library.ix; i++) {
			s += larr[i].a;
		}
		return s;
	}
	int totalpr() {
		int s = 0; 
		for(int i = 0; i<Library.ix;i++) {
			s+= larr[i].a * larr[i].pr;
		}
		return s;
	}
	void delv() {
		for(int i = 0; i<Library.ix;i++) {
			System.out.print(i + " "+ larr[i].title+"  ");
		}
		System.out.print("몇번 줄이기 >> ");
		int x = a.nextInt();
		System.out.print("총"+larr[x].a+"권 >> ");
		int y = a.nextInt();
		if(y>larr[x].a) {
			larr[x].a = 0;
		}
		else {
			larr[x].a-=y;
		}
	}
	void delc() {
		for(int i = 0; i<Library.ix;i++) {
			System.out.print(i + " "+ larr[i].title+"  ");
		}
		System.out.print("없엘 번호 >> ");
		int x = a.nextInt();
		for(int i = 0; i<Library.ix; i++) {			
			if(i>=x) {
				larr[i] = larr[i+1];
			}
		}
		Library.ix--;
		for(int i = 0; i<Library.ix;i++) {
			larr[i].id = i+1;
		}
	}
	void play() {
		while(true) {
			System.out.println("\n\n1.목록 2.총권 3.총값 4.추가 5.권삭 6.삭제 7종료");
			System.out.print("입력 >> ");
			int x = a.nextInt();
			if(x==1) {
				print();
			}
			else if(x==2) {
				System.out.println("총권 : "+totala());
			}
			else if(x==3) {
				System.out.println("총가격 : "+totalpr());
			}
			else if(x==4) {
				add();
			}
			else if(x==5) {
				delv();
			}
			else if(x==6) {
				delc();
			}
			else if(x==7) {
				break;
			}
		}
	}
}

 

 

 

 

 

 

 

 

 

 

 

■ 2월 24일 - 7일차

 


생성자 this()

생성자에서 다른 생성자 호출 시 사용
코드의 중복을 제거하기 위해서
생성자끼리 서로를 호출함

String = 색, float = 크기, int = 문
Car 클래스 생성
생성자는 기본생성자, 3개의 매개변수가 있는 생성자

class Car{
	String color;
	float size;
	int door;
	
	Car(){
		
	}
	
	Car(String a, float b, int c){
		color = a;
		size = b;
		door = c;
	}
	
}

 

Car(){
color = "파랑";
size = 1.2f;
door = 2;
}
생성자 this() 사용시
this("파랑", 1.2f, 2);

생성자 this 사용법

class Car{
	String color;
	float size;
	int door;
	
	Car(){
		this("검정",15.3f,4); // float에 정수넣어도 됨
	}
	
	Car(int a){
		this("파랑",12.2f,a);
	}
	
	Car(String a, float b, int c){
		color = a;
		size = b;
		door = c;
	}
	
}

this(); 의 의미
내가 가지고 있는 생성자를 호출

this() 는 첫번째 줄에만 생성해야 함

클래스 내부 메서드를 사용하기 위해서는
void a(int a){}
Car(){a(a)}

클래스 내부 생성자 메서드를 가져오기 위해서는
this()로 작성해야함

Car(int a)를 불러오기 위해서는
Car(){this(4);}
작성하면 됨




참조변수 this

인스턴스 자신을 가리키는 참조 변수
인스턴스 메서드(생성자 포함)에서 사용가능
지역변수와 인스턴스 변수를 구별할 때 사용

this() 는 생성자 this는 참조변수
개념 자체가 다름 연관이 없음

class Car{
	String a;
	float b;
	int c;
	
	Car(String a, float b, int c){
		a = a; //인스턴스 변수를 가져와야 하는데, 지역변수만 들어감
		b = b;
		c = c;
	}	
}

가까운 변수이름인 지역변수만 선택하게됨
이때 this.a로 사용하면 인스턴스의 메서드를 가르킴

본래 대로면 참조변수.변수명으로 불러들여야함
this는 생략가능 (같은 클래스)

class Car{
	String a;
	float b;
	int c;
	
	Car(String a, float b, int c){
		this.a = a; 
		this.b = b;
		this.c = c;
	}	
}

 

객체가 생성되지 않았기 때문에 참조변수를 사용할 수 없음
물론 인스턴스 변수는 참조할 수 없음
그것을 this로 사용한다고 판단하면 됨

다른 클래스에서도 인스턴스 변수를 참조할 수 없음

class Car{
	String a;
	float b;
	int c;
	
	Car(String a, float b, int c){
		Car.a = a; // 에러 인스턴스는 생성되지 않았음
		this.b = b;
		this.c = c;
	}	
}

클래스 변수는 참조가능

class Car{
	static String a1;
	String a;
	float b;
	int c;
	
	Car(String a, float b, int c){
		Car.a1 = a; // 문제 없음
        // this.a1 = a; 가능 그러나 Car.a1으로 사용하는게 맞는개념
		this.b = b;
		this.c = c;
	}	
}

 

this 인스턴스(객체) 자신을 가리키는 참조변수, 인스턴스의 주소가 저장
모든 인스턴스 메서드에 숨겨진 채로 존재한다.
따로 선언을 하지 않았는데 사용가능

int a, int b; // this.a, this.b 인스턴스 변수의 진짜이름

this() 생성자, 같은 클래스의 다른 생성자를 호출 시 사용
클래스 이름 대신

class C{
	int a; // this.a 가 진짜 이름
	int b;
	
	void a(int a, int b) {
		int c = a+b; // 지역변수
		this.a = a; //인스턴스 a에 지역 a 대입
		b=c; // 지역변수
	}
	void b() {
		a = 10; // 인스턴스 변수 this 생략됨
		b = 11; // 생략가능
	}
	static void c(int a, int b) {
		//this.a = a; //에러
		//클래스 메서드는 객체 생성 이전에 사용할 수 있기에
		//인스턴스 변수 사용 불가
	}
}

 

 


변수의 초기화

지역변수는 수동 초기화 해야됨

class C{
	int a; 
	int b=a; // 인스턴스 변수는 초기화 됨
	
	void af() {
		int i;
		int j = i; //에러 지역변수 초기화 안됨
		i = a; 
	}
}

호출스택은 재사용이 빈번하다
일일히 자동으로 초기화 해주게 되면
메모리 성능이 떨어짐
인스턴스변수는 그래도 유지기간이 길기 때문에 초기화됨
배열은 자동초기화됨

타입에 따른 기본값 초기화
boolean false
참조형 null

참조형 변수 - null 또는 객체 주소



멤버변수의 초기화

멤버 변수 = 인스턴스 변수, 클래스 변수

명시적 초기화
int a = 4;
Car c = new Car(); 객체를 만들어서 주소를 참조형변수 c에 넣어줌

초기화 블럭
복잡한 초기화 할때 사용함
인스턴스 초기화 블럭 {}
클래스 초기화 블럭 static{}

생성자
iv초기화할때 사용함

 

멤버변수의 초기화
1 자동 초기화
2 간단 초기화 =
3 복잡 초기화 {}, 생성자

class C{
	int a=b*3+1; // 에러 b가 생성되지 않음
	int b=a*3+1;
	int c = a-1;	
}
class C{
	int a+=1;
	// 에러 선언과 초기화 같이하면 자신을 불러들일 수없다
	int b=(b+10)*2;
	int c;
}
class C{
	int a;
	int b;
	int c;
	a+=10; // 에러
}

해결방안
생성자로 작성하면됨
또는 {} 인스턴스 변수 초기화 블록 사용하면됨
인스턴스 변수 초기화 블록은 잘 사용하지 않는다.

class C{
	int a;
	int b;
	int c;
	{
		a = b+c; // a = 0
		a+=10; // a = 10
		b+=1; // b = 1
		c+=3; // c = 3
	}
}

public class K1{

	public static void main(String[] args) {
		C c1 = new C();
		System.out.printf("a = %d, b = %d, c = %d",c1.a,c1.b,c1.c);

	}	
}

// 출력 //

a = 10, b = 1, c = 3

 

클래스 변수를 배열로 만들어서 랜덤넣기

class C{
	static int[] a = new int[10];

	static{
		for (int i = 0; i<a.length;i++) {
			a[i] = (int)(Math.random()*10)+1; //1~10
		}
	}
}

public class K1{

	public static void main(String[] args) {
		System.out.println(Arrays.toString(C.a));

	}	
}

// 출력 //

[10, 1, 9, 8, 6, 5, 2, 4, 9, 7]



멤버변수의 초기화 시점

클래스 변수 : 클래스가 처음 로딩 될 때 한번 (메모리에 올라갈때)
인스턴스 변수 : 인스턴스가 생성될 때 마다

초기화 순서
1 클래스 -> 인스턴스
2 자동 -> 간단 -> 복잡

class C{
	static int cv = 1; // 1. 자동초기화 0, 2. 간단초기화 1
	int iv = 1; // 객체생성시 4. 자동초기화 0, 5. 자동초기화 1
	static {cv =2;} // 3. 복잡초기화 2
	{iv =2;} // 6. 복잡초기화 2
	C(){ // 7. 생성자 초기화 3
		iv = 3;
	}
	// 또 객체 생성시 인스턴스 초기화 반복
    // 순서를 바꿔도 동일

}

public class K1{

	public static void main(String[] args) {
		C c1 = new C();
		System.out.println(c1.cv + " " + c1.iv);

	}	
}

// 출력 //

2 3




상속

상속(Inheritance) : 계승
기존 클래스로 새로운 클래스를 작성하는 것(코드의 재사용)
두 클래스를 부모와 자식으로 관계를 맺어준다.

class 자식클래스 extends 부모클래스

자손은 조상의 모든 멤버를 상속 받는다.
(생성자, 초기화 블럭은 제외)
인스턴스 변수, 클래스 변수, 인스턴스 메서드, 클래스 메서드

자손의 멤버 개수는 조상보다 적을 수 없다. (같거나 많다)

 

class Cp{
	int a = 1;
	int b = 5;
}

class Cc extends Cp{
	int c = 10;
}

public class K1{

	public static void main(String[] args) {
		Cc c1 = new Cc();
        Cp c2 = new Cp();
		c2.a = 100; // c1에 영향 주지 않음
		System.out.printf("a = %d, b= %d, c= %d\n",
				c1.a,c1.b,c1.c);

	}	
}

// 출력 //

a = 1, b= 5, c= 10

 

클래스 변수는 당연히 영향을 받는다

class Cp{
	static int a = 1;
	static int b = 5;
}

class Cc extends Cp{
	static int c = 10;
}

public class K1{

	public static void main(String[] args) {
		Cc c1 = new Cc();
		Cp c2 = new Cp();
		System.out.printf("a = %d, b= %d, c= %d\n",
				c1.a,c1.b,c1.c);
		c2.a = 100;
		System.out.printf("a = %d, b= %d, c= %d",
				c1.a,c1.b,c1.c);

	}	
}

// 출력 //

a = 1, b= 5, c= 10
a = 100, b= 5, c= 10

 

상속을 받던 받지 않던 동일한 주소형태를 갖는다.
자식 클래스 Cc에 int 3개를 넣은것이나
Cc에 부모(int 2개)를 상속 받는 자식(int 1개)은
객체가 멤버변수 3개짜리로 만들어짐


 

포함

클래스 관계 1. 상속, 2. 포함

포함(composite) : 합성
클래스의 멤버로 참조변수를 선언하는 것

class C1{
	int a = 1;
	int b = 5;
}

class C2{
	C1 c1 = new C1();
	int c = 10;
}

c2를 멤버 3개로 만든것과
c2 멤버1과 c1(멤버2)을 포함시켜서 작성하면
c2는 int와 c1이라는 객체로 멤버가 2개
c1변수는 주소를 참조받아 int a,b의 멤버를 갖음
즉 구조적인 차이가 있다.

불러올때는
a.c1.a

class C1{
	int a = 1;
	int b = 5;
}

class C2{
	C1 c1 = new C1();
	int c = 10;
}

class C3{
	int a = 1;
	int b = 5;
	int c = 10;
}

public class K1{

	public static void main(String[] args) {
		
		C2 a = new C2();
		C3 b = new C3();
		
		System.out.printf("C2 a = %d",a.c1.a);
        // 불러 들이는게 다름
		System.out.printf("C3 a = %d",b.a);
		
	}	
}

// 출력 //

C2 a = 1
C3 a = 1

 

상속에서 불러들일때
자식클래스.부모클래스.클래스 변수 안됨

 

클래스 간의 관계 결정
간단한 개념임
상속관계 : a는 b이다
포함관계 : a는 b를 가지고 있다.

 

프로그래밍
= 설계(90%) + 코딩(10%)
설계 : 내가 하고자 하는 것을 구성




단일상속

자바는 단일 상속만을 허용 (C++,Python은 다중상속 허용)

다중상속은 장점이 많다
그러나 단점이 있다.

하나의 자식 클래스가 두개의 부모클래스를
받을 경우 1번 부모, 2번부모 둘다
동일한 명의 다른 처리를 하는 함수가 있으면
충돌이 생겨서 문제가 발생될 수 있다.

인터페이스를 이용하면 충돌 문제를 해결하면서
다중상속을 받을 수 있도록 도와준다.

비중이 높은 클래스 하나만 상속관계, 나머지는 포함

class Tv{
	boolean pw;
	int ch;
	void pw() {pw = !pw;}
	void chu() {++ch;}
	void chd() {--ch;}
}

class dvd{
	boolean pw;
	void pl() {}
	void st() {}	
}

class Tvdvd extends Tv{
	dvd d = new dvd();
	void pl() {
		d.pl();
	}
	void chuu(int a) {
		for(int i=0;i<a;i++) {
			chu();
		}
	}
}




object 클래스

조상이 없는 클래스는 자동적으로 object 를 상속받는다
모든 클래스는 object의 11개의 매서드를 상속받음

class C {
}
이렇게 작성하면 자동적으로 컴파일된다
class C extends Object{
}

public class K1{

	public static void main(String[] args) {
		Tvdvd t = new Tvdvd();
		System.out.println(t);
		System.out.println(t.toString());
	}	
}

// 출력 //

javapj.Tvdvd@24d46ca6
javapj.Tvdvd@24d46ca6

 

 

 

오버라이딩

오버라이딩(overriding) 덮다
상속 받은 조상의 메서드를 자신에 맞게 변경하는 것

class P{
	int a;
	int b;
	
	void pr() {
		System.out.printf("a = %d, b = %d\n",a,b);
	}
}

class Ch extends P{
	int c;
	
	void pr() { //오버라이딩 되었음
		System.out.printf("a = %d, b = %d, C = %d\n",a,b,c);
	}
}

public class K1{

	public static void main(String[] args) {
		P a = new P();
		a.pr();
		
		Ch b = new Ch();
		b.pr();
		
	}	
}

// 출력 //

a = 0, b = 0
a = 0, b = 0, C = 0

 

선언부는 변경 불가 내용만 변경가능
그러나 오버로딩 형태로 사용하면 즉 매개변수가 다르게
작성하면 불러들이는게 다름

오버로딩

class P{
	int a;
	int b;
	
	void pr() {
		System.out.printf("a = %d, b = %d\n",a,b);
	}
}

class Ch extends P{
	int c;
	
	void pr(int x) {
		System.out.printf("a = %d, b = %d, C = %d\n",a,b,c);
	}
}

public class K1{

	public static void main(String[] args) {

		Ch b = new Ch();
		b.pr(1);
		b.pr();
		
	}	
}

// 출력 //

a = 0, b = 0, C = 0
a = 0, b = 0

 

오버라이딩 조건

선언부가 조상 클래스의 메서드와 일치
선언부 (반환타입, 메서드 이름, 매개변수 목록)

접근 제어자를 조상클래스의 메서드보다 좁은 범위로 변경할 수 없다.
public protected private defalt

예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.
조상이 2개, 자식은 같거나 적어야함
예외는 어떠한 에러가 발생할 지에 예상해서
예외를 처리하는 것을 말함




오버로딩, 오버라이딩 차이

근본적으로 다른것이 없다

오버로딩 : 기존에 없는 새로운 메서드를 정의
이름이 같은 것

오버라이딩 : 상속받은 메서드의 내용을 변경

class P{
	void a() {}
}

class Ch extends P{
	void a() {} // 오버라이딩
	void a(int i) {} // 오버라이딩을 한것을 오버로딩
	
	void b() {} // 새로운 메소드 생성
	void b(int i) {} // 메소드 오버로딩
	// void b() {} // 에러 // 중복 
}


 

 

 

 



참조변수 super

객체 자신을 가리키는 참조변수
인스턴스 메서드 및 생성자 내에서만 존재
조상의 멤버와 자신의 멤버를 구별할 때 사용

this는 지역변수와 인스턴스 변수를 구별
super는 조상 멤버와 자신의 멤버 구별

class P{
	int a = 1; //super
}

class Ch extends P{
	int a = 10; // this
	void pr() {
		System.out.println("a= "+a); //가까운쪽
		System.out.println("this.a= "+this.a);
		System.out.println("super.a= "+super.a);
	}
}

public class K1{

	public static void main(String[] args) {

		Ch b = new Ch();
		b.pr();
		
	}	
}

// 출력 //

a= 10
this.a= 10
super.a= 1

 

자신의 변수가 없으면
동일하게 나옴

class P{
	int a = 1; //super
}

class Ch extends P{
	int a = 10; // this
	void pr() {
		System.out.println("a= "+a); //가까운쪽
		System.out.println("this.a= "+this.a);
		System.out.println("super.a= "+super.a);
	}
}

public class K1{

	public static void main(String[] args) {

		Ch b = new Ch();
		b.pr();
		
	}	
}

// 출력 //

a= 1
this.a= 1
super.a= 1

 

값을 변경해서 변동되는 것 확인

class P{
	int a = 1; //super
}

class Ch extends P{
	int a = 10; // this
	void a1() {
		a = 100;
	}
	void a2() {
		super.a = 5;
	}
	void pr() {
		System.out.println("a= "+a); //가까운쪽
		System.out.println("this.a= "+this.a);
		System.out.println("super.a= "+super.a);
	}
}

public class K1{

	public static void main(String[] args) {

		Ch b = new Ch();
		b.pr();
		b.a1();
		b.pr();
		b.a2();
		b.pr();
		
	}	
}

// 출력 //

a= 10
this.a= 10
super.a= 1

a= 100
this.a= 100
super.a= 1

a= 100
this.a= 100
super.a= 5

 

super() - 조상의 생성자

조상의 생성자를 호출 할 때 사용
조상의 멤버는 조상의 생성자를 호출해서 초기화

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
}

class Ch extends P{ //에러
	int z;
}

 

class Ch에 에러발생
Ch를 생성하면 기본으로 P를 받는데
P를 생성하기 위해서는 (int x, int y)로만생성
해결1

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
	
	P(){
		
	}
}

class Ch extends P{
	int z;
}

해결2

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
}

class Ch extends P{
	int z;
	Ch() {
		super(0,0);
	}	
}

 

부모는 2개
자식은 3개
생성자 에러

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
	
}

class Ch extends P{
	int z;
	Ch(int x, int y, int z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

해결

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
	P(){}
}

class Ch extends P{
	int z;
	Ch(int x, int y, int z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

위와 같이 작성해도 상관없지만
바람직한 것은

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
}

class Ch extends P{
	int z;
	Ch(int x, int y, int z){
		super(x, y);
		// Ch의 매개변수 x y가 슈퍼 부모의 생성자 인수로 생성
		this.z = z;
	}
}

즉 변수를 초기화할때
조상클래스의 생성자를 호출해서
조상의 변수를 초기화하고
자신의 변수는 자신에서 초기화하는게
개념적으로 맞음

this() 생성자 호출은
첫줄에 반드시 생성자를 호출해야함
그렇지 않으면 컴파일러가 생성자의 첫 줄에 super(); 삽입

class P{
	int x,y;
    
	P() {
    	this(0,0)
    }
    
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
}

// 자동 컴파일 후 변화

class P extends objcet { //object 상속받음
	int x,y;
    
    P() {
    	this(0,0) // 첫줄에 this 생성자 호출됨
    }
	
	P(int x, int y){
    	super(); // object 클래스 생성자 호출됨
		this.x = x;
		this.y = y;
	}
}

 

상속시 생성자 확인

class P{
	int x,y;
	
	P(int x, int y){
		this.x = x;
		this.y = y;
	}
	
}

class Ch extends P{
	int z;
	Ch(int x, int y, int z){
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

//자동 컴파일 후 변화

class P extends Object{ //추가
	int x,y;
	
	P(int x, int y){
    	super(); // Object 생성자 호출
		this.x = x;
		this.y = y;
	}
	
}

class Ch extends P{
	int z;
	Ch(int x, int y, int z){
    	super(); // P 생성자 호출 그러나 기본생성자가 P에는 없음
		this.x = x;
		this.y = y;
		this.z = z;
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

■ 2월 26일 - 9일차

클래스 생성자, 상속, 기타 연습

public class K1 {
	public static void main(String[] args) {
		String[] nar = {"김철수","이하나","유진석","구지혁","김선희","양하윤","최지은","서주혁","오현석"}; 
		K3[] k = k3m(nar);
		k3r(k);
	}
	static void k3r(K3[] a) {
		for(int i =0; i<a.length; i++) {
			System.out.print(a[i].n+" ");
		}
		System.out.print("변경할 인덱스 >> ");
		Scanner sc = new Scanner(System.in);
		int b = sc.nextInt();
		a[b].pr();
		System.out.println("1.나이 2.이름 3.학년 4.반");
		System.out.print("무엇 변경 >> ");
		int c = sc.nextInt();
		switch(c) {
		case 1:
			System.out.print("현재 나이 "+a[b].a+"변경 >> ");
			a[b].a = sc.nextInt();
			break;
		case 2:
			System.out.print("현재 이름 "+a[b].n+"변경 >> ");
			a[b].n = sc.next();
			break;
		case 3:
			System.out.print("현재 학년 "+a[b].g+"변경 >> ");
			a[b].g = sc.nextInt();
			break;
		case 4:
			System.out.print("현재 반 "+a[b].c+"변경 >> ");
			a[b].c = sc.nextInt();
			break;
		default:
			System.out.println("잘못입력");
		}
		a[b].pr();
	}
	
	static void k3pr(K3[] a, String b) { // 객체 배열과 문자열을 받아서 이름이 같은 것 출력 	
		for(int i = 0; i < a.length; i++) {
			if(a[i].n.equals(b)) a[i].pr();
			}		
	}
	static K3[] k3m(String[] n) { // 문자열과 0 1 2 17세 1학년 1 2 3반
								// 3 4 5 18세 2학년 4 5 6반
		K3[] a = new K3[n.length];
		for(int i = 0; i<n.length;i++) {
			a[i] = new K3(n[i],17+(i/3),1+(i/3),i+1);
		}		
		return a;
	}
}

class K2{
	String n;
	int a;
	K2(String n, int a){ // 생성자 이름와 나이
		this.n = n;
		this.a = a;		
	}
	void pr() {
		System.out.println("이름 : "+this.n+" 나이 : "+this.a);
	}
}

class K3 extends K2{
	int g;
	int c;
	K3(int g, int c){ //생성자 1
		super("홍길동",22);
		this.g = g;
		this.c = c;
	}
	K3(String n, int a, int g, int c){ //생성자 2
		super(n,a);
		this.g = g;
		this.c = c;
	}

	void pr() { // 오버라이드
		super.pr();
		System.out.println(this.g+"학년 "+this.c+"반");
	}
}

 

 

 

패키지 (package)

패키지 - 서로관련된 클래스의 묶음

자바 약 4000개의 클래스보유

클래스는 클래스 파일,
패키지는 폴더
하위 패키지는 하위 폴더

패키지는 소스파일의 첫 번째 문장으로 단 한번선언
같은 소스 파일의 클래스는 같은 패키지에 속함
패키지가 없으면 이름없는 패키지에 속함





import문

클래스를 사용할 때 패키지 이름을 생략할 수 있다.
자동 import Ctrl + Shift + O

import java.util.Scanner;

public class K1{

	public static void main(String[] args) {
		
		java.util.Scanner sc1 = new java.util.Scanner(System.in);
		Scanner sc2 = new Scanner(System.in);
		
	}	
}

 

java.lang 패키지의 클래스는 import하지 않고 사용
즉 생략 가능
대표적인 클래스는 String, Object, System, Thread 등

import문선언
import 패키지명.클래스명;
import 패키지명.*; 모든클래스

 

import문은 컴파일 시 처리되어 프로그램 성능에 영향 없음
그러나 컴파일시 오래 걸림
명시해놓으면 어떤것을 프로그램에서 사용하는지 직접적으로 알 수 있음

 

java.*; 한다고하면
java패키지의 클래스만 포함
각각의 하위 패키지의 클래스는 사용 못함

import java.util.*;
import java.text.*;

import java.*;

 

클래스 이름은 같고 패키지 명이 다른 것도 있음
사용할때 패키지명을 작성해줘야함

package javapj;

import java.sql.*; // java.sql.Date
import java.util.*; // java.util.Date

public class K1{

	public static void main(String[] args) {
		
		// Date d1 = new Date(); // 에러
		java.util.Date d2 = new java.util.Date();
		
	}	
}




static import문

static 멤버를 사용할때 클래스 이름을 생략 할 수 있게 해준다.
static 멤버 = static 변수, static 메서드

package javapj;

import static java.lang.System.out;
import static java.lang.Math.random;
import static java.lang.Math.*;

public class K1{

	public static void main(String[] args) {
		
		System.out.println(Math.random());
		out.println(random());
		out.println(PI);
		
	}	
}

// 출력 //

0.5920576021881406
0.2837887502364551
3.141592653589793

System 클래스 안에는 static 변수이면서,
PrintSteam의 객체 out변수가 존재
static 변수이기 때문에 인스턴스 생성없이 바로접근
정리하면 out은 PrintStream클래스의 객체이고
println()은 PrintStream클래스의 메소드임





제어자(modifier)

클래스와 클래스의 멤버(변수, 메서드)에 부가적인 의미부여
접근제어자 public, protected, (default), private
4개중 1개만 붙임
그외 static, final, abstract 등

하나의 대상에 여러 제어자를 같이 사용가능(접근 제어자는 하나만)

public class K1{
	
	public static final int a = 1;
	public static void main(String[] args) {
				
	}	
}

순서도 크게 제한 없다.
그러나 대부분 접근제어자를 앞에 사용(관례적으로)
final 보다 static을 먼저사용(관례적)

public class K1{
	
	public static final int a = 1;
	static public final int b = 10;
	final static public int c = 20;
	public static void main(String[] args) {
				
	}	
}

접근제어자는 하나만 붙일 수 있다.

public class K1{
	
	public static final int a = 1;
	static public final int b = 10;
	final static public int c = 20;
	private public int d = 1; //에러 
	public static void main(String[] args) {
	
	}	
}

 

static - 클래스의, 공통적인

제어자대상의미

static 멤버변수 모든인스턴스에 공통적으로 사용되는 클래스 변수
클래스 변수는 인스턴스를 생성하지 않고도 사용가능
클래스가 메모리에 로드될 때 생성
메서드 인스턴스를 생성하지 않고도 호출이 가능한 static 메서드
static 메서드 내에서는 인스턴스 멤버들을 직접 사용할 수 없다.
public class K1{
	
	static int a =1;
	int iv = 1;
	static void a() {
		a = 10;
		iv = 11; //오류 인스턴스 변수 사용불가
	}
	void b() {
		a = 10;
		iv = 11;
	}    

}

 

클래스 만들기 예시

package pj;

import java.util.Arrays;


public class K2 {	

	public static void main(String[] args) {
		D cl = new D(5, 10);
		
	}
	
}

class C{
	
	C(int a){ // a 배열의 개수에 영향을 줌
		C.a = a;
		this.arr = new int[a]; // 배열을 몇개 인지 만들어줌
		arv(); //배열을 1~ 초기화
	}
	C(int a, int b){
		this(a);
		arv(b);
	}
	
	static int a;
	static float b = 3.14f;
	int[] arr;
	String s = "hello";
	
	static void pl() {
		System.out.println("클래스 메서드");
	}
	void arp() {
		System.out.println(Arrays.toString(this.arr));
	}
	void arv() {
		for(int i = 0; i<this.arr.length;i++) {
			this.arr[i] = i+1;
		}
	}
	void arv(int a) {
		for(int i = 0; i<this.arr.length;i++) {
			this.arr[i] = i+a;
		}
	}

}

class D extends C{

	D(int a, int b){
		super(a,b);
		arp();
	}
	void arp() {
		super.arp();
		int s = 0;
		for(int i = 0; i<this.arr.length;i++) {
			s += this.arr[i];
		}
		System.out.println("총계 : "+s);
		System.out.println("평균 : "+(s/(float)this.arr.length));
	}
	
}

 

 

 

 

 

 

final - 마지막의, 변경될 수 없는

제어자대상의미

final 클래스 변경될 수 없는 클래스, 확장될 수 없는 클래스
final로 지정된 클래스는 다른 클래스의 조상이 될 수 없다.
메서드 변경될 수 없는 메서드
final로 지정된 메서드는 오버라이딩을 통해 재정의 될 수 없다.
멤버변수 변수 앞에 final이붙으면 값을 변경할 수 없는 상수가 된다.
지역변수

final 클래스의 예시 : String, Math
String은 보안으로 인해서 final로 선정함 (문자열로 비밀번호)
Math는 static 메서드 집합으로 굳이 일반 클래스로 만들 필요가 없음

상속불가, 포함가능, 오버로딩은 가능,

final class K2{
	int a = 1;
	final int b = 1; // 값을 변경할 수 없는 멤버변수(상수)
	
	void a1(int a) {
		
	}
	void a1(int a, int b) { 
		
	}
	final void a2() {
		
	}
	void a2(int a) {//오버로딩 가능 
		
	}
	
}

class K2_1 extends K2{  // K2 상속불가
	
}

class K2_2{
	K2 k2 = new K2(); // 포함가능

}


public class K1{
	
	public static void main(String[] args) {
		K2_2 k = new K2_2();
		k.k2.a = 10;
		k.k2.b = 1; //변경불가 final 변수
		k.k2.a2();
		k.k2.a2(1);//오버로딩
	}	
}

오버라이딩 사용불가
오버라이딩 : 조상 메서드를 덮어쓸수 없음

class K2{
	int a = 1;
	final int b = 1;
	
	final void a2() {
		
	}
	
}

class K2_1 extends K2{
	void a2() { //오버라이딩 안됨
		
	}
	final void a2() {
		
	}
}

 

 

 

abstract - 추상의, 미완성의

컴퓨터 과학에서의 추상화는 복잡한 자료, 모듈, 시스템 등으로부터
핵심적인 개념 또는 기능을 간추려 내는 것

객체지향 관점에서의 추상화는 클래스를 정의 할 때
불필요한 부분들을 생략하고 객체의 속성(변수) 중
중요한 것에만 중점을 두어 개략화 하는 것
즉 클래스들의 중요하고 공통된 성질들을 추출하여
슈퍼 클래스를 선정하는 개념

추상화의 이유
중복코드가 현저히 줄어든다. 코드가 간결해져서
생산성 증가, 가독성 증가, 에러감소, 유지보수시 시간 단축
잘 만들어진 슈퍼 클래스 덕분에 코드의 재사용성이 증가

추상화가 잘 되어 있으면 코드는 내부 코드를 전부 이해하지 않아도
가져다가 사용할 수 있는 장점이 있지만
반대로 그렇기 때문에 내부를 파악하거나 수정이 어렵다.

제어자대상의미

abstract 클래스 클래스 내에 추상 메서드가 선언되어 있음을 의미
메서드 선언부만 작성하고 구현부는 작성하지 않은 추상 메서드임을 알림

객체 생성 불가

abstract class K2{
	abstract void a(); 
}
	abstract void b() { //에러 추상메서드로 선언했으므로 작성불가
		
	}

class K3{ //에러 클래스 내에 미완성 추상 메서드가 있음
	abstract void a(); //에러 클래스 자체가 미완성이 아님 
}

public class K1{
	
	public static void main(String[] args) {
		K2 k = new K2(); //에러 미완성 클래스
	}	
}

추상클래스를 상속받아
추상메서드를 구현하여(오버라이딩)으로 완성시켜
상속받은 클래스(구상 클래스) 추상클래스의 반대말
인스턴스생성 후 사용

abstract class K2{
	int a = 1;
	abstract void a1();
}

class K3 extends K2{ //에러 추상메서드를 구현하지 않음
	
}
abstract class K2{
	int a = 1;
	abstract void a1();
}

class K3 extends K2{
	void a1() {
		System.out.printf("%d",this.a);
	}
}



public class K1{
	
	public static void main(String[] args) {
		K3 k = new K3();
		k.a1();
	}	
}

 

 

접근제어자 (access modifier)

접근제어자설명

private 같은 클래스 내에서만 접근이 가능
(default) 같은 패키지 내에서만 접근이 가능
protected 같은 패키지 내, 다른 패키지의 자손클래스에서 접근 가능
public 접근제한이 전혀 없다

제어자같은 클래스같은 패키지자손클래스전체

public O O O O
protected O O O  
(default) O O    
private O      

 

접근제한 없음, 같은패키지+자손, 같은 패키지, 같은 클래스
public > protected > (default) > private

 

클래스에 붙일 수 있는 것
public
(default)

멤버에 붙일 수 있는것
public
protected
(default)
private

 

참고 패키지 내에서 동일한 이름의 클래스 사용못함
K1.java

package javapj;

class K3{
	
}

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

K2.java

package javapj;

public class K2 {

}
class K3{ //에러
	
}

 

설명

class K2{

	public int pub = 3; // 전체
	int def = 1; // 패키지
	protected int pro = 4; // 패키지 + 자식
	private int pri = 5; // 클래스
	
	void a() {
		pri = 10;
	}
}

public class K1{
	
	public static void main(String[] args) {
		K2 k = new K2();
		k.def = 10;
		k.pub = 5;
		k.pro = 2;
		k.pri = 5; //에러 다른 클래스에서 사용
	}
}

 

protected 는 다른 패키지에서 protected 클래스를 상속받아서
사용이 가능하다.
javapj - K1.java

package javapj;

class K2{
	protected int a = 1;
	protected static int b = 1;
}

public class K1{
	protected int a =1;
	protected static int b = 1;
	
	public static void main(String[] args) {
		K2.b = 10; // static 변수여서 인스턴스 생성전 사용
		K2 k = new K2();
		k.a = 10; //같은 패키지여서 사용가능
	}
}

javapj2 - J1.java

package javapj2;

import javapj.K1;

class J2 extends K1{ //javapj.K1라고 쓰고 import 안해도 됨
	void a() {
		this.a = 10; //protected 다른 패키지에서 자식이어서 가능
		this.c = 1; //default 변수로 다른 패키지 사용불가
		this.d = 10; //public 변수 사용가능
	}
	static void b() {
		this.a = 2; //에러 a는 인스턴스 변수
		K1.b = 10; //사용가능 b는 static 변수
		b = 5; // 사용가능 b는 static 변수
	}
}

class J3 extends K2{ // K2는 default 다른 패키지 사용불가
	
}

public class J1{
	J2 j = new J2();
	j.a = 1; //protected 사용불가 다른패키지에서 자식이 아님

	public static void main(String[] args) {
		K1 k = new K1();
		k.a = 1; // protected 사용불가
		J2 j = new J2();
		j.a = 1; //protected 사용불가
	}
	
}



참조형 반환타입에서의 활동

받는 타입 변환 Childc로
또한 주는 타입도 변환 Childc로

그러나 부모타입으로 받아서 줄때는 앞에만 하면 됨

public class K1{
	
	public static void main(String[] args) {
		Childc c = new Childc();
		Parents p = a(c);
		//Childc c2 = a(p); 에러
		//Childc c2 = a((Childc) p); 에러
		Childc c2 = (Childc)a((Childc)p);
		Childc c3 = (Childc)b(p);
		System.out.println("a= "+c.a+", b="+c.b);
				
	}
	
	static Parents a(Childc a) {
		return a;
	}
	static Parents b(Parents b) {
		return b;
	}
}

 

참조형 반환타입복습

public class K1{
	
	public static void main(String[] args) {
		Childc c = new Childc();
		Parents p = a();
		p.a = 100;
		p.b = 1000;
		System.out.println("c.a= "+c.a+", c.b="+c.b);
		System.out.println("p.a= "+p.a+", p.b="+p.b);
				
	}
	
	static Parents a() {
		Childc b = new Childc();
		return b;
	}
	
}

// 출력 //

c.a= 1, c.b=2
p.a= 100, p.b=1000

 

Null 포인트시 에러

컴파일은 문제 안됨

public class K1{
	
	public static void main(String[] args) {
		Childc c = null;
		Parents p = c;
		Childc c2 = (Childc) p;
		c2.e = 10; //경고 
				
	}	
}

// 출력 //

Exception in thread "main" java.lang.NullPointerException




instanceof 연산자

참조변수의 형변환 가능여부 확인에 사용.
가능하면 true반환
조상과 자손은 형변환가능

1확인, 형변환 해도 되는지 (안전한지)
2형변환
형변환 전에 반드시 instanceof로 확인 필요

손자로 만든 객체 점검

public class K1{
	
	public static void main(String[] args) {
		Childc c = new Childc();
		
		System.out.println(c instanceof Child);
		System.out.println(c instanceof Childc);
		System.out.println(c instanceof Parents);
				
	}	
}

// 출력 //

true
true
true

부모로 만든 객체 점검

public class K1{
	
	public static void main(String[] args) {
		Parents c = new Parents();
		
		System.out.println(c instanceof Child);
		System.out.println(c instanceof Childc);
		System.out.println(c instanceof Parents);
				
	}	
}

// 출력 //

false
false
true

부모타입의 참조변수에 자식의 객체

public class K1{
	
	public static void main(String[] args) {
		Parents c = new Child();
		
		System.out.println(c instanceof Child);
		System.out.println(c instanceof Childc);
		System.out.println(c instanceof Parents);
				
	}	
}

// 출력 //

true
false
true

 

정리

참조변수의 형변환을 하는이유
참조변수를 변경함으로써 사용할 수 있는 멤버의 갯수를 조절

instanceof연산자는 참조변수를 형변환하기 전에
형변환 가능여부를 확인할 때 확인한다.




매개변수의 다형성

장점
1 다형적 매개변수
2 하나의 배열로 여러종류 객체 다루기

다형성
1 조상타입의 참조변수로 자손객체 다루기
2 참조변수의 형변환 - 사용할 수 있는 멤버 갯수 조절
3 instanceof 연산자 - 형변환 가능여부 체크

매개변수의 다형성
참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는
자손타입의 인스턴스를 넘겨줄수 있다.

에러

class Parents{
	int a = 0;
	int b = 0;
	int c = 0;
	
}

class Child extends Parents  {
	int d = 0;
}

class Child2 extends Parents{
	int d = 0;
}

class Child3 extends Parents{
	int d = 0;
}

// 출력 //

public class K1{
	
	public static void main(String[] args) {
		Child c1 = new Child();
		Child2 c2 = new Child2();
		Child3 c3 = new Child3();
		d(c1,10);
		d(c2,22);		
				
	}
	
	static void d(Child a,int b) {
		a.b = b;
	}
}

오버로딩

public class K1{
	
	public static void main(String[] args) {
		Child c1 = new Child();
		Child2 c2 = new Child2();
		Child3 c3 = new Child3();
		b(c1,10);
		b(c2,22);
		b(c3,35);
				
	}
	
	static void b(Child a,int b) {
		a.b = b;
	}
	static void b(Child2 a,int b) {
		a.b = b;
	}
	static void b(Child3 a,int b) {
		a.b = b;
	}
}

매개변수의 다형성
당연히 부모의 맴버만 변경가능
각자의 것을 바꾸려면 오버로딩하는게 맞음

public class K1{
	
	public static void main(String[] args) {
		Child c1 = new Child();
		Child2 c2 = new Child2();
		Child3 c3 = new Child3();
		b(c1,10); 
		b(c2,22);
		b(c3,35);
		System.out.printf("c1 = %d, c2 = %d, c3 = %d",c1.b,c2.b,c3.b);
				
	}
	
	static void b(Parents a,int b) {
		a.b = b;
		//에러 a.d = 1;//에러
	}
}

// 출력 //

c1 = 10, c2 = 22, c3 = 35

참고
toString()이 자동으로 실행되어 나옴 오버라이딩

class Child extends Parents  {
	int d = 0;
	public String toString() {
		return "Child";
	}
}

public class K1{
	
	public static void main(String[] args) {
		Child c1 = new Child();
		Child2 c2 = new Child2();
		Child3 c3 = new Child3();
		b(c1,10); 
		b(c2,22);
		b(c3,35);
		System.out.println(c1+" = "+c1.b);
		System.out.println(c2+" = "+c2.b);
						
	}
}

// 출력 //

Child = 10
javapj.Child2@4517d9a3 = 22



다형성을 배열로 다룰수 있다.

public class K1{
	public static void main(String[] args) {
		Parents[] p = {new Child(),new Child2(),new Child3()};					
	}
}
public class K1{
	static Parents[] p = new Parents[10];
	static int count = 1;
	public static void main(String[] args) {
		add(new Child());
		add(new Child2());
		add(new Child3());
		Child c1 = (Child) p[0];
		c1.d = 10;
		Child2 c2 = (Child2) p[1];
		c2.d = 20;
		Child3 c3 = (Child3) p[1];
		c3.d = 30;
	}
	static void add(Parents a) {
		p[count++] = a;
	}
}

 

 

 

 

객체 통제하기

public class K1{
	public static void main(String[] args) {
		K2[] k = new K2[10];
		m(k,2);
		add(k);			
	}
	static void add(K2[] a) {
		for(int i = 0; i<a.length;i++) {
			K3 b = (K3)a[i];
			b.name = "";
			for(int j = 0; j<a[i].arr.length;j++) {
				a[i].arr[j] = i+j;
				b.name += a[i].arr[j];
			}
			System.out.println(b.name);
		}
	}
	
	static void pr(K2[] a) {
		for(int i = 0; i<a.length;i++) {
			a[i].pr();
		}
	}
	static void m(K2[] a, int b) {
		for(int i = 0; i<a.length; i++) {
			if(i<b) {
				a[i] = new K3();
			}
			else {
				a[i] = new K3();
			}
		}
	}
}

class K2{
	int[] arr = new int[3];
	void pr() {
		System.out.println(Arrays.toString(arr));
	}
}

class K3 extends K2{
	String name;
}

 

 

 

 

 

 

■ 2월 27일 - 10일차

추상 클래스 (abstract class)

미완성 설계도,
미완성 메서드를 갖고 있는 클래스

abstract class abc{
	int iv = 1;
	abstract void af(int a); // 미완성 메서드(추상 메서드)
}

미완성 설계도 => 제품생산 불가
다른 클래스 작성에 도움을 주기 위한 것으로
인스턴스 생성 불가

abc c = new abc(); // 에러

상속을 통해 추상 메서드를 완성해야 인스턴스 생성가능

class Child extends abc{ //완성됨 클래스
	void af(int a) { 
		
	}
}

 

추상클래스 타입으로 자손클래스의 객체를 만들어
사용할 수 있음.

abstract class abc{
	int iv = 1;
	abstract void af(int a);
}


class Child extends abc{
	void af(int a) {
		System.out.println(a);
	}
}

public class K1{

	public static void main(String[] args) {
		abc c = new Child();		
		c.af(10);
		
	}

}

// 출력 //

10

 

추상 메서드

미완성 메서드, 구현부 가 없는메서드
abstract 리턴타입 메서드 이름(); // 세미클론을 넣어 주어야 한다

추상메서드 작성 이유
꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우 사용

abstract class abc{ //2개의 추상메서드
	int iv = 1;
	abstract void af(int a);
	abstract void af2();
}


class Child extends abc{
	void af(int a) {
		System.out.println(a);
	}
	void af2() {
		System.out.println("af2");
	}
}

abstract class AChild extends abc{  //1개의 추상메서드만 구현 abstract 미작성시 에러 
	void af(int a) {
		System.out.println("af"+a);
	}
}

public class K1{

	public static void main(String[] args) {
		// abc c = new AChild(); //추상 클래스 생성 에러		
		
	}

}

 

추상메서드 호출가능
메서드는 선언부만 알면 호출이가능하므로
추상메서드도 호출 가능

현재는 구현부는 없지만 상속을 통해
자손이 완성시키기 때문에 당연히 호출 가능

인스턴스 메서드는 객체 생성후 사용할 수 있는데,
추상클래스는 객체생성이 안됨 그렇기 때문에 인스턴스 안됨

abstract class abc{
	int iv = 1;
	abstract void af(int a);
	abstract void af2();
	void af() {
		af(iv);  //iv값에 다른 숫자를 넣으면 
	}
}

class Child extends abc{
	void af(int a) {
		System.out.println(a);
	}
	void af2() {
		System.out.println("af2");
	}
}

public class K1{

	public static void main(String[] args) {
		abc c = new Child(); //추상 클래스 생성 에러		
		c.iv = 22;
		c.af();
	}

}


// 출력 //

22

static void af() {
af(15); //에러 인스턴스 메서드 가르키고 있어서
}

설명
굳이 추상메서드로 만들 필요없고
일반메서드로 만들어서 빈공간을 줘도 된다.
그러나 추상메서드로 만들어 주면 필수적으로
상속받는 클래스에서는 무조건 작성해야 되기 때문에
추상메서드를 만든다.




추상클래스의 작성

추상클래스 : 미완성 설계도(미완성 메서드 포함)

여러 클래스에 공통적으로 사용될 수 있는 추상클래스를
바로 작성하거나 기존 클래스의 공통부분을 뽑아서 추상클래스를
만든다.

선언부는 일치하지만 구현부가 불일치 할 경우
추상메서드로 만들어 준다.

예시 유닛의 좌표, 이동, 공격, 등등 공통된 부분을 추상으로
각각의 마린, 메딕, 파이어벳, 레이스에서 구현
유닛 배열 만들고 각각의 유닛(마린, 메딕 등등)객체을 따로 넣어줌
각각의 유닛에서 동일한 부분에 대해서는 시행가능
유닛 타입은 공통된 것을 넣어 놓았기 때문에

		int a = 3; // 유닛 종류
		int c = 10; // 유닛의 총 개수
		int[] arr = new int[3]; // 유닛
		int[] u = new int[c]; //선택한 유닛
		u[0] = arr[0%a]; // 0, 1, 2 가 for문 반복하면 나옴
        // 0을 i로 넣어서



추상클래스의 장점

추상 클래스 관련
Tv50a, Tv50b, Tv50c
공통된 부분 3개, 다른게 1개라면
공통된 부분은 추상클래스로 (미완성시키기)
바탕으로 자손을 만들면 중복이 제거되고
1개만 만들면 됨

추가적인 설계도를 만들기 쉽다

공통된 부분이 달라지면
추상 클래스만 바꿔도 모든게 변화된다
즉 관리가 용이해진다. (변경)

추상클래스를
조상은 공통 1개, 자손은 2개, 그 밑 자손은 3개로
공통된 부분에 대해서도 단계별로 작성가능 (구체화)
그러면 새로운 클래스에서 공통된 부분자체를 하나의부분만
변경해야 되면 자손 2개짜리 추상클래스에서 바로 상속받아서 사용할 수 있다.

 

사전적 의미

추상(뺄 추, 형상 상)
추상 : 여러 가지 사물이나 개념에서 공통되는 특성이나 속성 따위를 추출하여 파악하는 작용
추상적 : 구체성이 없이 사실이나 현실에서 멀어져 막연하고 일반적인.
구체 : 사물이 직접 경험하거나 지각할 수 있도록 일정한 형태와 성질을 갖춤

구체화 : 구체적으로 만드는것
추상화 : 불명확한것
추상화 <-> 구체화(반대)

추상화된 코드는 구체화된 코드보다 유연하다 변경에 유리

 

 

 

 

 

 

인터페이스(interface)

인터페이스는 Static 메서드, default 메서드도 가지고
있지만 부수적인것임 핵심은 추상 메서드의 집합

인터페이스(상호작용)
인터페이스 = 추상 메서드의 집합 : 프로그래밍 관점
구현된 것이 전혀 없는 설계도, 껍데기(모든 멤버가 public)

인터페이스의 모든 멤버는 public

인터페이스, 추상클래스의 차이
추상클래스 : 일반클래스 인데 추상 메서드를 가지고 있음
인터페이스 : 추상메서드를 가지고 있음
추상클래스는 멤버변수가 있지만 인터페이스는 멤버변수를 가지고 있지 않음

캡슐화에서 (내부 변수를 보호, 메서드를 이용해야만 접근가능)
구현된것의 겉부분이 인터페이스이다.

interface ifa{
	static final int a = 1;  //값이 없어도 에러임 final이기 때문
    // public static final int a
    final int a2 = 2; // public static final int a2
    static int a3 =3; // public static final int a3
	int b = 2; //static final 이 기본 public도 기본
    //public static final int b
    //상수는 항상 public static final임 예외없음
    //그래서 생략가능
    
    
	// private int c=1; //안됨
	// protected int d= 3; //안됨
    
    // void m() {} 기본값이 추상메서드 에러 구현을 했기 때문에
	void m2();
    // public abstract void m2() == public abstract 생략가능
    // 생략가능한 이유는 인터페이스는 항상 public에 abstract이기 때문에
    
    
	abstract void m3();
    public abstract void m4();
}

class cl{
	static final int a = 1;
	int b = 2;
	final int c = 3;
	static int d = 4;
	
}

 

인터페이스의 상속

인터페이스의 조상은 인터페이스만 가능 (object 최고 조상 아님)
다중상속 가능(추상메서드는 충돌해도 문제 없음)

interface ifa{
	int a=1;
	int b=2;
	void m1();
}
interface ifb{
	void m1();
    //선언부가 같은데 구현부가 달라서 문제인것임
    //내용불일치로 충돌을 일으킴
    //구현부가 둘다 없기때문에 아무런 문제가 되지 않는다.
}
interface ifc extends ifa,ifb{
	
}

 

인터페이스의 구현

인터페이스는 추상메서드로만 되어 있어서
인터페이스를 구현한다는 것은
인터페이스에 정의된 추상 메서드를 완성하는 것

class 클래스 이름 implements 인터페이스 이름{
}

interface ifa{
	int a=1;
	int b=2;
	void m1();
}
interface ifb{
	void m1();
}
interface ifc extends ifa,ifb{
	
}


class cifa implements ifc{ //두개 구현할 수 있음 ifa,ifb
	public void m1() { //public 안쓰면 에러
    // 상속하는 것도 오버라이딩하려면 조상의 범위공간보다 작으면 안됨
		
	}
}

 

인터페이스를 구현한 클래스의 인스턴스 생성

class cifa implements ifa,ifb{
	public void m1() {
		System.out.println("생성");
	}
}

public class K1{

	public static void main(String[] args) {
		cifa c = new cifa();
		System.out.println(c.a);
		System.out.println(c.b);
	}
		
}

// 출력 //

1
2
생성

동일 이름의 변수 선언

class cifa implements ifa,ifb{
	public void m1() {
		System.out.println("생성");
	}
	int a = 100;
	
}

// 출력 //

100
2
생성

인터페이스의 변수 불러오기

	public static void main(String[] args) {
		cifa c = new cifa();
		System.out.println(c.a);
		System.out.println(c.b*10);
		System.out.println(ifa.a);
		
		c.m1();
	}

// 출력 //

100
20
1
생성


상속과 인터페이스 구현 둘다 한 클래스에서 사용가능

	class cifa extends cl implements ifa,ifb{
    }



인터페이스가 두개의 추상 메서드를 갖고 있는데
클래스에서 implements 로 인터페이스를 가져오는데
1개만 구현했다면 클래스앞에 abstract넣어야 함



인터페이스를 이용한 다형성

다형성 : 조상참조변수로 자손객체를 가르키는 것

클래스를 상속하는 것과 인터페이스를 구현하는데 문제가 발생
상속받는 부모 클래스의 메서드와 인터페이스 메서드의
이름이 동일할 경우 다중상속문제가 있다.
그러나 인터페이스는 구현부가 없기 때문에 생각안해도 된다.

다중상속의 문제점을 해결하면서 사용할 수 있도록 해줌

class c extends pc implements if{

}
pc a = new c(); //조상클래스에서 자손객체
if i = new c(); // 인터페이스에서 자손객체   사용가능
//인터페이스에서 사용된 맴버 2개만 사용가능

 

매개변수로 인터페이스를 사용한다는 것은
인터페이스를 구현한 클래스의 인스턴스(객체)만 가능
참조형 매개변수 관리와 동일

interface if{
	void m(int x, int y);
    void a(if a);
}

 

인터페이스를 메서드의
리턴타입으로 지정할수 있다.(반환타입)

의미 는 인터페이스를 구현한 클래스의 인스턴스를 반환
일반적으로 기본형 타입을 반환하는 형태와 동일

if method(){
	C c = new C();
    return f;
}

반환타입은 인터페이스이고 반환하는 값은 클래스임
구현을 해 놓았기 때문에 문제가 없음 자동형변환과 유사 개념

abstract class un{
	int x, y;
	abstract void move(int x, int y);
	void stop() {System.out.println("멈춤");}
}

interface fit{
	void move(int x, int y); // public abstract가 생략
	void at(fit f);
}

class f extends un implements fit{
	public void move(int x, int y) { //public 써줘야함
		// 오버라이딩 규칙 조상보다 접근제어자가 좁으면 안됨
		System.out.println(x+""+y+"이동");
	}
	public void at(fit f) {
		System.out.println(f + "공격");
	}
}

public class K1{

	public static void main(String[] args) {
		f a = new f();
		a.move(10, 10);
		a.at(new f());
	}
	
	
}

// 출력 //

1010이동
javapj.f@24d46ca6공격

fit도 사용가능

		fit a = new f();
		a.move(10, 10);
		a.at(new f());

fit에서는 stop() 구현은 불가함

		fit a = new f();
		a.move(10, 10);
		a.at(new f());
		a.stop();//사용할 수 없다. 인터페이스 fit에서 구현안됨

un추상클래스에서는 at() 구현 불가

		un a = new f();
		a.move(10, 10);
		a.at(new f()); //사용할 수 없다. at가 un에 없다.
		a.stop();



f클래스나 fit 인터페이스나 상관이 없다.

class f extends un implements fit{
	public void move(int x, int y) { //public 써줘야함
		// 오버라이딩 규칙 조상보다 접근제어자가 좁으면 안됨
		System.out.println(x+""+y+"이동");
	}
	public void at(fit f) {
		System.out.println(f + "공격");
	}
	fit getf() {
		f cf = new f();
		return cf;
	}
}


	public static void main(String[] args) {
		f a = new f();
		a.move(10, 10);
		a.at(a.getf()); 
		a.stop();
	}

타입만 맞춰주면된다.
반환타입이 인터페이스이라는 것은
인터페이스를 구현하는 것을 반환한다라고 이해해도됨

다형성이면서 추상화 때문에 쓰인다.




인터페이스의 장점 1.

1 두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 중간역할을 한다.
interface = inter(~사이) + face(얼굴, 대상)
inter national airport (국제공항)
어떤 두 대상사이에서 중간 역할을 해줌

어떤 두 대상이 직접소통할 수 있지만
중간에서 소통을 도와주는 역할을 해주는 중개인 역할임

 

1번장점 기계 예시

기계가 있다고 생각을 하면
사람이 직접 기계를 조작할 수도 있지만 기계전반적인
부분에 대해서 알고 있지 않으면 직접 조작하기 어렵다.
기계 껍데기에 버튼등을 장착해서 인터페이스를 구현해 놓으면
버튼으로 기계의 부분부분들을 통제하여 기계를 사용하는 것이 효율적이다.

기계와 사람사이에 인터페이스 즉 중간역할을 만들어 주면
기계와 사람이 소통하기 쉬워 진다.

다른예로 자판기를 보면 자판기의 버튼을 누르면(인터페이스)
기계가 작동하는 역할임

 

1번장점 컴퓨터 예시

또다른 예는 컴퓨터로
컴퓨터의 하드웨어를 직접적으로 사용하기는 어렵다.
그것을 해결하고자 윈도우(OS), Operating System 운영체제
GUI Graphic User Interface로 일종의 인터페이스 중간역할
화면만 클릭하면 컴퓨터에 명령을 줌

안의 하드웨어가 변경된다고 하더라도
사람이 인터페이스에 익숙해지면 명령을 주는 행동에는
변화가 되지 않고 자연스럽게 사용할 수 있음.
즉 변경에 유리하고 연결, 대화, 소통을 도와준다.


2번째 장점



인터페이스의 장점 2

선언(설계)와 구현을 분리시킬 수 있게 한다.
일반적으로 클래스에서 메서드가 선언 및 정의를 해놓는데
메서드만 떼어내서 인터페이스에 선언만 넣어놓을 수 있다.
분리시켜놓을 수 있다.

분리하지 않으면 유연하지 않고 변경에 불리하다.
분리하면 다른클래스에서 구현을 시킬 수 있고
유연해진다. 변경이 쉽다.



인터페이스의 장점 3

인터페이스 덕분에 B가 변경되어도 A는 안바꿀수 있다.(느슨한 결합)
A라는 클래스가 B라는 클래스를 사용하고 즉 의존되어 있을때
B라는 클래스가 더이상 사용되어지지 않고 다른형태로 변경되어야하면
A라는 클래스의 형태도 변화시켜야 하지만

인터페이스로 싸여진 B라는 클래스를 사용하고 있을때
인터페이스(즉 버튼부분만 사용하는 법만 알면)만 알면
인터페이스 내부의 변화에 따라서 바꾸지 않아도 된다.

기계로서 생각해보면 기계 부품과 사용법이 바뀌면 그것을 사용하는
사람이 조작방법이 바뀌지만 껍데기 화면 부분은 일치화 시키면
내부가 바뀌든 말든 아무런 조작방법의 변화없이 사용가능





내부 클래스

클래스 안에 만들어진 다른 클래스로 중첩클래스라고 함
두개의 클래스가 긴밀한 관계가 있을 때 선언한다.

내부 클래스의 장점

두 클래스 멤버들 간에 손쉽게 접근할 수 있다.
불필요한 클래스를 감춰 코드의 복잡성 최소화

 

클래스의 명칭

외부클래스

다른 클래스 내부에 존재하지 않고 독립적으로 정의된 클래스
클래스 파일의 최상위 레벨에 위치

내부 클래스

클래스의 내부에서 선언 및 정의된 클래스
외부클래스와 밀접한 관계를 가지며 멤버로 간주됨
외부클래스의 멤버에 쉽게 접근할수 있음

 

주요특징

  • 외부 클래스의 멤버에 대한 쉬운 접근

외부 클래스의 private 멤버에도 접근이 가능함

  • 외부 클래스와의 강한 연관성

외부 클래스의 인스턴스와 상호작용 및 데이터를 공유 가능

  • 접근 제어 및 용도 제한

내부 클래스를 통해 정근 제어를 조정 및 코드 구조 조정가능
내부 클래스를 private으로 선언하여 외부에서의 직접 접근 제한가능

 

내부클래스 종류

종류설명

인스턴스 내부 클래스
(Instance Inner Class)
- 외부 클래스의 인스턴스 변수와 동일한 생명 주기를 가지는 내부 클래스
- 외부클래스의 멤버변수에 접근하여 사용함
- 외부클래스의 모든 멤버에 접근가능
- 외부클래스의 인스턴스를 생성한 후 해당 인스턴스를 사용하여 내부 클래스의 인스턴스를 생성
정적 내부 클래스
(Static Inner Class)
- 정적 멤버로 선언된 클래스
-외부클래스의 인스턴스에 종속되지 않고 외부클래스의 정적멤버와 유사한 특성을 가짐
- 외부 클래스의 인스턴스를 생성하지 않고도 생성가능
지역 클래스
(Local Inner Class)
- 메소드 내에 선언된 클래스로 해당 메소드 내에서만 유효한 클래스
- 주로 메소드 내부에서 임시적인 기능을 구현하기 위해 사용
- 외부 클래스의 멤버에 접근 가능 메소드 내에서는 제한

 

인스턴스 클래스

인스턴스 클래스의 정의

외부 클래스 내에 멤버를 넣어줄 부분에서 선언한다.

class Out{
	int a = 10;
	class In{
		int b = 1;
	}
}

 

인스턴스 클래스의 객체 생성

외부클래스의 인스턴스를 생성하고
외부클래스명 객체명 = new 클래스명();
외부클래스명.내부클래스명 객체명 = 외부클래스의 객체명.new 내부클래스명();

Out a = new Out();
Out.in b = a.new in();

 

인스턴스 클래스의 활용

  • 인스턴스변수 접근 / 접근제한 private

private로 접근이 제한되어 있는 변수도 접근이 가능하다
클래스 내부에서 사용하는 것이기 때문에
메서드를 사용하는 것과 같다고 보면됨

 

package pj;

class Out{
	private int a = 10; // 정적변수

	class in{
		int b = 1;
		void f() {
			System.out.println(a); //정적 변수 접근
		}
	}
}

public class t1 {

	public static void main(String[] args) {
		Out a = new Out();
		Out.in b = a.new in();
		System.out.println(b.b); // 내부 인스턴스 변수 접근
		b.f();		
	}
}

// 출력 //

1
10

 

  • 정적변수 및 메서드 접근

정적변수 및 메서드도 메모리에 미리 올라온 형태로 인하여 사용간 제한 없다.

package pj;

class Out{
	private int a = 10; // 인스턴스 변수
	static int as = 100;// static 변수
	static void fas(int x) {// static 메서드
		as = x;
		// a = x2; static으로 인스턴스 접근 불가능
	}
	class in{
		int b = 1;
		void f() {
			System.out.println(a); //인스턴스 변수 접근
		}
		void fs() {
			fas(101); //static 메서드 호출
			System.out.println(as); // static 변수 접근
		}
	}
}

public class t1 {

	public static void main(String[] args) {
		Out a = new Out();
		Out.in b = a.new in();
		System.out.println(b.b);
		b.f();
		b.fs();
		
	}
}

// 출력 //

1
10
101

 

  • 변수접근 방법

동일한 명의 변수를 불러들이는 방식
메서드에서 지역변수 불러들이려면 변수명 사용
내부 클래스 내 변수 자신 : this.변수명
외부클래스 내 변수 : 외부클래스명.this.변수명

class Out{
	private int a = 10;

	class in{
		int a = 1;
		void f(int a) {
			System.out.println("함수 내부 = "+a);
			System.out.println("내부 변수 = "+this.a);
			System.out.println("외부 변수 = "+Out.this.a);
		}
	}
}


public class t1 {

	public static void main(String[] args) {
		Out a = new Out();
		Out.in b = a.new in();
		b.f(100);
		
	}
}

// 출력 //

함수 내부 = 100
내부 변수 = 1
외부 변수 = 10

 

  • 다른 외부 클래스 상속

내부 클래스가 자신의 외부 클래스가 아닌
다른 외부 클래스를 상속하여 사용할수 있다.

class Out{
	private int a = 10;

	class in extends Out2{
		int a = 1;
		void f(int a) {
			System.out.println("함수 내부 = "+a);
			System.out.println("내부 변수 = "+this.a);
			System.out.println("외부 변수 = "+Out.this.a);
			System.out.println("부모클래스 변수 = "+super.a);
		}
	}
}
class Out2{
	protected int a = 1000;
}


public class t1 {

	public static void main(String[] args) {
		Out a = new Out();
		Out.in b = a.new in();
		b.f(100);
		
	}
}

// 출력 //

함수 내부 = 100
내부 변수 = 1
외부 변수 = 10
부모클래스 변수 = 1000

 

  • 외부 클래스의 부모클래스 접근
class Out extends Out2{
	private int a = 10;

	class in{
		int a = 1;
		void f(int a) {
			System.out.println("함수 내부 = "+a);
			System.out.println("내부 변수 = "+this.a);
			System.out.println("외부 변수 = "+Out.this.a);
			System.out.println("외부의 부모클래스 변수 = "+Out.super.a);
		}
	}
}
class Out2{
	protected int a = 2000;
}


public class t1 {

	public static void main(String[] args) {
		Out a = new Out();
		Out.in b = a.new in();
		b.f(100);
		
	}
}

// 출력 //

함수 내부 = 100
내부 변수 = 1
외부 변수 = 10
외부의 부모클래스 변수 = 2000



정적 클래스

외부 클래스의 인스턴스 멤버에 접근이 불가능함
외부 클래스를 인스턴스화(객체) 하지 않고 인스턴스 가능

정적 클래스의 정의

외부 클래스 내에 멤버를 넣어줄 부분에서
static으로 선언

class Out{
	static class In{
	}
}

 

정적 클래스의 객체 생성

외부 클래스의 인스턴스를 생성하지 않아도 생성가능
외부클래스명.내부클래스명 객체명 = new 외부클래스명.내부클래스명();

Out.in a = new Out.in();

 

정적 클래스 활용

외부 클래스의 인스턴스 변수에 접근 제한

class Out{
	private int x = 10;
	static private int sx = 30;
	
	static class in{
		int a = 1;
		void f() {
			// System.out.println("외부 인스턴스 변수 = "+x); 외부 클래스의 인스턴스 접근 불가
			System.out.println("내부 인스턴스 변수 = "+a);
			System.out.println("외부 static 변수 = "+sx);
		}
	}
}


public class t1 {

	public static void main(String[] args) {
		Out.in a = new Out.in();
		a.f();
		
		
	}
}


// 출력 //




지역 클래스

메서드 내에서 선언되어 사용
주로 메소드 내부에서 임시적인 기능을 구현하기 위해 사용
외부 클래스의 멤버에 접근 가능 메소드 내에서는 제한

지역 클래스의 정의

메서드 내에서 선언하고 사용함

class Out{
	void a() {
		class In{
			
		}
	}	
}

 

지역 클래스의 객체 생성

메서드 내부에서만 사용가능함.

void a() {
		class In{
			
		}
		In ic = new In();
	}

 

지역 클래스 활용

class Out{
	private int x = 10;
	static private int sx = 30;
	
	void a(String f1) {
		class In{
			int ix = 1;
			String isx = "안녕"; 
		}
		In ic = new In();
		ic.isx = f1;
		ic.ix = this.x;
		System.out.println(ic.isx+" "+ic.ix);
	}	
}


public class t1 {

	public static void main(String[] args) {
		
		Out oc = new Out();
		oc.a("사람");
		
	}
}

// 출력 //

사람 10

지역 클래스 상속

class Out extends Out2{ //외부클래스가 상속
	private int x = 10;
	static private int sx = 30;
	
	void a(String f1) {
		class In{
			int ix = 1;
			String isx = "안녕"; 
		}
		In ic = new In();
		ic.isx = f1;
		ic.ix = super.a;  //외부클래스가 상속받은 클래스변수에 접근
		System.out.println(ic.isx+" "+ic.ix); 
	}	
}
class Out2{
	protected int a = 1000;
	
}

// 출력 //

사람 1000





예외 처리

발생하는 예외에 대해서 처리가하고 넘길수 있음

 

에러와 예외

에러 : 시스템에 비정상적인 상황이 생겼을때 발생함
외부요인 및 구동중에 발생하는 치명적 오류일 가능성 있음
개발자가 예측 및 처리할 수 없는 영역

예외 : 프로그램 구동중에 나타나는 오류
문법적으로 문제없지만 실제 운영중 생기는 문제

예외의 종류
체크 예외 : 컴파일 도중 확인 문법적으로 강제
비체크 예외 : 컴파일 중에 확인 하지 않는 예외



대표적인 예외

NullpointerException

객체가 제대로 생성되지 않은 상태에서 사용할 경우 발생

	public static void main(String[] args) {
		
		int[] a = null;
		
		System.out.println(a[0]);
		
	}

// 출력 //

Exception in thread "main" java.lang.NullPointerException: Cannot load from int array because "a" is null
	at pj.t1.main(t1.java:10)



NumberFormatException

문자열을 숫자로 형변환시 사용되는 예외
10.1 이라는 문자를 정수로 변환시 예외

 

문자를 숫자를 변형하는 법

		String a = "10";
		int i1 = Integer.parseInt(a); //정수로 변환
		String b = "11.1";
		float f1 = Float.parseFloat(b); //실수로 변환

 

잘못된 작성으로 예외 발생

int i2 = Integer.parseInt(b); //에러

// 출력 //

Exception in thread "main" java.lang.NumberFormatException: For input string: "11.1"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:67)
	at java.base/java.lang.Integer.parseInt(Integer.java:668)
	at java.base/java.lang.Integer.parseInt(Integer.java:786)
	at pj.t1.main(t1.java:13)



ArrayIndexOutOfBoundsException

배열 인덱스 범위 초과 에러

		int[] a = {1,2,3};
		
		System.out.println(a[3]);

// 출력 //

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
	at pj.t1.main(t1.java:10)



예외 처리

단일사용

try{
예외 발생 가능성 코드
}
catch( 예외클래스명 변수명){
예외 발생시 처리
}

		try {
			int[] a = {10,20,30};
			int b = 3;
			System.out.println(a[b]);
			
		}
		catch(ArrayIndexOutOfBoundsException c) {
			System.out.println("인덱스 오류");
		}
        
// 출력 //
 
인덱스 오류

 

다중사용

try{
예외 발생 가능성 코드
}
catch( 예외클래스명 변수명){
예외 발생시 처리
}
catch( 예외클래스명 변수명){
예외 발생시 처리
}

먼저 발생한 예외에 맞게 빠져나옴

		try {
			
			int[] a2 = null;
			System.out.println(a2[1]);	
			
			int[] a = {10,20,30};		
			int b = 3;
			System.out.println(a[b]);
			
		}
		catch(ArrayIndexOutOfBoundsException c) {
			System.out.println("인덱스 오류");
		}
		catch(NullPointerException c) {
			System.out.println("null값 오류");
		}

// 출력 //

null값 오류

 

finally

예외 발생유무와 상관없이 반드시 실행하는것으로
생략가능

		try {
			
			int[] a2 = null;
			System.out.println(a2[1]);	
			
			int[] a = {10,20,30};		
			int b = 3;
			System.out.println(a[b]);
			
		}
		catch(ArrayIndexOutOfBoundsException c) {
			System.out.println("인덱스 오류");
		}
		catch(NullPointerException c) {
			System.out.println("null값 오류");
		}
		finally {
			System.out.println("종료");
		}

// 출력 //

null값 오류
종료




래퍼클래스(Wrapper Class)

래퍼 클래스란?
자바의 자료형은 기본 타입(primitive type)과 참조 타입(reference type)으로 구분
기본 타입 : Int, char, float, double, boolean 등
참조 타입 : class interface 등
프로그래밍을 하다보면 기본 타입의 데이터를 객체로 표현해야 하는 경우가 종종있음

기본타입을 객체로 다루기 위해서 사용하는 클래스를 래퍼클래스(Wrapper)라고 한다.
래퍼는 포장하다는 의미를 가지고 있음

 

래퍼클래스의 종류

기본 타입래퍼클래스

byte Byte
char Character
int Integer
float Float
double Double
boolean Boolean
long Long
short Short

 

대략적으로 대문자를 넣는 형태로 쓰며
대표 클래스인 Object 클래스를 상속 받아 사용하고 있다.
Object 클래스 는 Boolean, Character, Number를 가지고 있고
Number 안에 정수와 실수를 저장하는 래퍼 클래스 보유

 

박싱(Boxing)과 언박싱(UnBoxing)

박싱 : 기본 타입의 값을 포장 객체로 만드는 과정

언박싱 : 포장객체에서 기본타입의 값을 얻어내는 과정

    public static void main(String[] args)  {
        Integer num = new Integer(17); // 박싱
        int n = num.intValue(); //언박싱
        System.out.println(n);
    }

 

자동 박싱과 언박싱
자동적으로 일어나는 경우도 있다.
참조 타입에 기본값이 대입될때나
기본 타입에 참조값이 대입될때 자동으로 일어남

힙 영역에 생성됨

    public static void main(String[] args)  {
        Integer num = 17; // 자동 박싱
        int n = num; //자동 언박싱
    }

 

래퍼클래스의 사용예제

문자열을 기본타입 값으로 변환

    public static void main(String[] args)  {
        String str = "10";
        String str2 = "10.5";
        String str3 = "true";
        
        byte b = Byte.parseByte(str);
        int i = Integer.parseInt(str);
        short s = Short.parseShort(str);
        long l = Long.parseLong(str);
        float f = Float.parseFloat(str2);
        double d = Double.parseDouble(str2);
        boolean bool = Boolean.parseBoolean(str3);
		
        System.out.println("문자열 byte값 변환 : "+b);
        System.out.println("문자열 int값 변환 : "+i);
        System.out.println("문자열 short값 변환 : "+s);
        System.out.println("문자열 long값 변환 : "+l);
        System.out.println("문자열 float값 변환 : "+f);
        System.out.println("문자열 double값 변환 : "+d);
        System.out.println("문자열 boolean값 변환 : "+bool);
    }

 

값비교

참조형 과 참조형으로 비교하면 다르다고 나옴
참조형 주소값을 갖고 있기 때문에
기본값을 넣으면 자동 박싱 되어 힙영역에 올라가
비교하면 같다고 나옴

	public static void main(String[] args) {
		Integer a = new Integer(10);
		Integer b = new Integer(10);
		
		System.out.println("참조형 == 참조형  "+(a==b));
		
		Integer c = 10;
		Integer d = 10;
		
		System.out.println("박싱 == 박싱  "+(c==d));
		
		
		
	}

// 출력 //

참조형 == 참조형  false
박싱 == 박싱  true

 

Object 클래스 활용

Object 클래스는 모든 클래스의 부모로
타입을 정하게 되면 값에 따라서 어떠한 클래스로든 볼수 있다.

public class t1 {
	
	Object data;
	
	void adddata(Object a) {
		this.data = a;
	}

	public static void main(String[] args) {
			
		t1 a = new t1();
		a.adddata(new Integer(100));
		
		System.out.println("Integer형태 = " + a.data);
		
		a.adddata(new String("안녕"));
		System.out.println("String형태 = " + a.data);
		
	}
}

// 출력 //

Integer형태 = 100
String형태 = 안녕

 

Value 및 문자열 변형

public class t1 {
	
	Object data;
	Integer i;
	
	void adddata(Object a) {
		this.data = a;
	}

	public static void main(String[] args) {
			
		t1 a = new t1();
		
		a.i = new Integer(10);
		int i = a.i.intValue();
		
		System.out.println(i);
		
		Scanner sc = new Scanner(System.in);
		System.out.print("문자열 입력 >> ");
		a.i = a.i.parseInt(sc.next());
		i = a.i.intValue();
		
		System.out.println(i);
		
	}
}

// 출력 //

10
문자열 입력 >> 500
500




제너릭

데이터 형식에 의존하지 않고 하나의 값이
여러 다른 데이터 타입들을 가질 수 있도록 하는 방법

 

Object 타입으로 데이터 잡을때 문제점

일반적으로 동일한 스타일의 클래스들은
하나의 형태로 만들어 주는것이 객체지향의 장점을
살리는데 기본임

유사한작업을 하는 클래스

public class t1 {
	
	public static void main(String[] args) {
			iclass ic = new iclass(10);
			idata id = new idata(ic);
			
			sclass sc = new sclass(5);
			sdata sd = new sdata(sc);
			
			System.out.println(id.a.i);
			System.out.println(sd.a.i);
		
	}
}

class iclass{
	int i;
	iclass(int a){
		this.i = a;
	}
}

class idata{
	iclass a;
	idata(iclass a){
		this.a = a;
	}
}

class sclass{
	int i;
	sclass(int a){
		this.i = a;
	}
}

class sdata{
	sclass a;
	sdata(sclass a){
		this.a = a;
	}
}

// 출력 //

10
5

 

모두가 가지고 있는 공통 부모로 변경할 수 있음
Object 클래스형태로 변경

public class t1 {
	
	public static void main(String[] args) {
			iclass ic = new iclass(10);
			data id = new data(ic);
			
			sclass sc = new sclass(5);
			data sd = new data(sc);
			
			iclass ic2 = (iclass)id.a;
			sclass sc2 = (sclass)sd.a;
			
			System.out.println(ic2.i);
			System.out.println(sc2.i);
			
		
	}
}

class iclass{
	int i;
	iclass(int a){
		this.i = a;
	}
}


class sclass{
	int i;
	sclass(int a){
		this.i = a;
	}
}

class data{
	Object a;
	data(Object a){
		this.a = a;
	}
}

// 출력 //

10
5

 

참조 타입을 넣어주는 이유는
그 참조타입으로만 데이터를 받으려고 하였지만
Object는 부모이기 때문에
어떠한 데이터 타입이 들어가도 문제가 없다고 나옴
물론 Object말고 프로그래머가 만든 클래스는 문제가 발생

		int a = 10;
		data id = new data(a);
		iclass ic = (iclass)id.a;	

// 출력 //

에러



제너릭을 사용하는 이유

내가 원하는 타입의 데이터만을 넣어줄수 있도록
객체를 만들때 데이터 타입을 선정해주어
데이터중 들어갈수 있는 것만 넣어줌

 

예시

class data<c>{ //c는 이름일 뿐
	c a;
	data(c a){
		this.a = a;
	}
}
public class t1 {
	
	public static void main(String[] args) {
		iclass ic = new iclass(1);
		sclass sc = new sclass(10);
		
		data<iclass> id = new data<iclass>(ic);
		//에러 data<sclass> id2 = new data<sclass>(ic); 다른 타입 들어감
		data<sclass> id2 = new data<sclass>(sc);
		System.out.println(id.a.i);
		System.out.println(id2.a.i);
	}
}

class iclass{
	int i;
	iclass(int a){
		this.i = a;
	}
}


class sclass{
	int i;
	sclass(int a){
		this.i = a;
	}
}

class data<c>{
	c a;
	data(c a){
		this.a = a;
	}
}

// 출력 //

1
10



제너릭의 한계 및 해결

제너릭은 기본타입에 대해서는 넣어줄수 없다.
그래서 기본타입의 래퍼클래스인 참조타입으로 시행

public class t1 {
	
	public static void main(String[] args) {
		//에러 기본형은 안됨 data<int> a = new data<int>(10);
		data<Integer> a = new data<Integer>(10);
		System.out.println(a.a);
		System.out.println(a.a.intValue());
	}
}

class data<T>{
	T a;
	data(T a){
		this.a = a;
	}
}

// 출력 //

10
10




람다식

public class t1 {
	
	public static void main(String[] args) {
		itf o = (a,b) -> a>b ? a:b;
		System.out.println(o.max(100, 20));
	}
}

interface itf{
	int max(int a, int b);
}

 

 

 

'언어 수업자료 > 자바' 카테고리의 다른 글

JAVA 2  (0) 2024.05.18
JAVA 1  (0) 2024.04.20
JAVA 2  (0) 2024.01.20
JAVA 1  (0) 2023.12.23