1. main
public class 클래스명{
public static void main(String[] args){
}
}
: java 인터프리터가 명시된 클래스 파일 안에서 "public static void main(String[] args)"를 찾아서 첫번째 문장부터 실행.
2. 데이터 타입
① 기본형(Primitive) : 값을 저장하기 위한 타입
: 논리형(boolean - 1byte)
: 문자형(char (' ') - 2byte)
: 정수형(byte - 1byte, short - 2byte, int - 4byte, long - 8byte)
: 실수형(float-4byte, double-8byte)
② 참조형(Reference) : 자바프로그램 내부에서 사용하는 클래스들이 할당된 메모리의 주소를 저장.
: 자바에서 제공하는 API(클래스), 사용자 정의 클래스, 배열, 문자열(" ")
③ 데이터 타입 범위 이상의 값은 할당할 수 없다.
long l = 1000; // 1000은 int literal.
// 큰타입의 변수에 작은 타입의 값을 할당하는 것은 자동으로 데이터 타입 변환하여 가능
long l = 2147483648; // error
long l = 2147483648L; // no error
float f =10.5; // error
float f =10.5f; // no error
double d = 10.5; // 10.5은 int literal.
④ 진수표현
2진수 : 0b
8진수 : 0
16진수 : 0x
유니코드 : \u
(char) 'A' 는 (int) 65와 같다
3. 변수
① 변수사용시 주의사항
1) 지역변수를 사용하는 경우 반드시 초기화 작업을 하고 사용해야한다.
2) {}안에서 선언된 변수는 {}안에서만 사용할 수 있다.
② 기본형 데이터 타입의 형변환
1) 묵시적 형변환 - 자동형변환(큰타입의 변수에 작은 데이터를 담을경우)
byte -> short -> int -> long -> float -> double
1 2 4 8 4 8
char ->
2
char c = 'A';
int i = c; // char - > int 자동 형변환
char c = i; // int -> char 자동 형변환 되지않아 error
=> byte, short char는 연산시 기본형인 int로 변환됨.
2) 명시적 형변환 - 형변환을 직접 정의해야한다.
int i = 200;
byte b = (byte)i; // error는 발생하지않지만 int의 bit중 유실되는 값이 존재하여 원하는 값이 출력이 되지않는다.
int c =65;
(char)c; // 'A' 출력
double d = 10.0/3.0; // 3.3333
double d = 10/3.0; // 3.3333 정수와 실수 연산은 실수값 반환.
double d = 10/3; // int형 리터럴로 3이 출력되며 double 변수에 3.0으로 저장된다.
③ 실수의 연산결과는 부정확
double d = 2.0 - 1.1 // 0.8999999
④ BigDecimal 사용 : 정확한 소수점 계산 가능.
import java.math.BigDecimal;
BigDecimal m1 = new BigDecimal("2.0");
BigDecimal m2 = new BigDecimal("1.1");
m1.subtract(m2); // 0.9
⑤ 데이터의 최대 / 최소값 확인
Integer.MIN_VALUE
Integer.MAX_VALUE
Long.MIN_VALUE
Long.MAX_VALUE
Float.MIN_VALUE
Float.MAX_VALUE
⑥ 상수 : 변경 할 수 없는 값으로 정의가능.
final 데이터형 변수명 = 초기값;
4. 연산자
① 산술 연산자 + - * / %
② 증감 연산자
x=5;
y=++x;
// result : x=6,y=6
x=5;
y=x++;
// result : x=6,y=5
x=5;
y=--x;
// result : x=4,y=4
x=5;
y=x--;
// result : x=4,y=5
③ 비교 연산자 : <,>,<=,>=,!=
"문자열"+숫자 => "문자열+숫자"
④ 대입 연산자 : +=,-=,*=, /=, %=
⑤ 논리 연산자 : &&, ||, !
- 실행오류 : 컴파일은 문제가 없으나 실행 중에 오류가 발생하는 경우
ex) null.length();
- &,|과 &&, || 차이점
1) || 연산자는 왼쪽 할을 검사해서 true이면 || 연산의 특성에 따라 오른쪽 항은 검사하지않는다.
=> TRUE || 실행오류 -> 정상실행
=> TRUE | 실행오류 -> error
2) && 연산자는 왼쪽 할을 검사해서 false이면 || 연산의 특성에 따라 오른쪽 항은 검사하지않는다.
=> FALSE && 실행오류 -> 정상실행
=> FALSE & 실행오류 -> error
- 삼항 연산자 : 조건이 참이면 A return, 거짓이면 B return
조건식 ? A:B
5. 문법
- 주석
1) // : 한줄 주석
2) /* */ : 여러줄 주석 설정 (단축키 : ctrl+shift+/)
여러줄 주석 해제 (단축키 : ctrl+shift+\)
① 순차형
② 조건형
1) if
2) if else
3) 다중 if
4) switch(표현식 ) case
: 표현식에는 byte, short, int, char, String, enum만 가능.
: 표현식에는 변수, 연산식, 메소드 호출문 가능.
: switch에 int가 case에 char가 있는 경우 int를 형변환하여 비교.
ex)
int data=5;
switch(data+60) {
case 'A':
System.out.println('A');
break;
}
③ 반복형
1) for(초기값;조건식;증감식)
2) for 안 if
3) 다중 for
4) while(조건문){}
5) do{} while(조건문);
6) while break
7) for break
8) for continue
=> break와 continue는 가까운 반복문에만 적용.
=> 먼 반복문까지 이동하려면 라벨을 사용한다.
라벨:
for(int i=0; i<10;i++){
for(int i=0; i<10;i++){
break 라벨;
// or continue 라벨;
}
}
9) for-each
for(int i:array){
array[i]
}
7. 참조형 변수 : 자바언어에서 제공되는 API를 이용
① String
String str = new String("문자열 초기값");
java라는 문자열을 처리하기 위해서 String클래스를 메모리에 할당
즉, String 클래스의 charAt이라는 기능(메소드)을 사용하기 위해서 JVM이 인식하는 작업 공간인 heap에 string
클래스를 할당하고 할당된 주소를 str변수에 저장
* charAt(index) : index의 문자 추출. index는 0부터 시작( str.charAt(0) )
* length() : 문자열의 길이 리턴( str.length() )
② Random : 랜덤수를 관리하는 기능을 제공하는 클래스
import java.util.Random;
Random rand = new Random();
* nextInt() : int 범위내의 랜덤 수 리턴. ( rand.nextInt() )
* nextInt(int) : 0부터 int-1까지의 램덤 수 리턴. ( rand.nextInt(100) ) -> 0~99까지
③ Scanner : 표준 입력 (키보드)으로 입력된 값을 읽어서 리턴하는 기능을 제공하는 클래스
import java.util.Scanner;
Scanner key = new Scanner(System.in);
System.in : 표준입력(키보드 입력)
System.out : 표준출력(모니터 출력)
표준입력으로 입력한 값을 저장하기 위해 System.in을 ()안에 정의
* nextLine() : 한 문장을 입력받기 위한 메소드 ( String line = key.nextLine() )
* next() : 단어를 입력 받기 위한 메소드. 공백입력 전의 문자열을 단어로 인식. ( String data = key.next() )
* nextInt() : 정수를 입력 받기위한 메소드( int num = key.nextInt() )
* System.out.print("문자열") : 문자열 출력 후 개행 없음
* System.out.println("문자열") : 문자열 출력 후 개행 있음.
④ Array : 배열은 초기값을 가진다. 정수 0, bool false, 실수 0.0, 참조형 null
1) 배열 선언
데이터형[] 변수명;
int[] array;
int array[];
2) 배열 생성
변수명 = new 데이터형[개수];
array = new int[3];
3) 배열 선언과 생성
데이터형[] 변수명 = new 데이터형[개수];
int[] arr = new int[3];
4) 배열 get
변수명 => 주소값
array
변수명[index] => index번째 요소 값 리턴
array[0]
5) 배열 set
변수명[index] = 값;
arry[0] = 1;
6) 참조형 배열 선언, 생성
데이터형[] 변수명 = new 데이터형[개수];
Random[] randarr = new Random[3];
randarr[0] = new Random();
randarr[0] => 주소값
String[] strArr = new String[5];
strArr[0] = new String("java");
strArr.length
strArr[1] // 값 리턴.
참조형 배열의 요소의 값을 sysout으로 액세스하는 것은 참조형 배열의 할당된 객체의 toString메소드를 호출하는 것과 같다.
5) 배열 생성, 선언, 초기화
int[] myarr = {10,20,30,40,50, 60};
int[] myarr2 = new int[]{10,20,30,40,50, 60};
String myVal = new String("javascript");
String[] myarr4 = {new String("aA"),
new String("bB"),
new String("cC"),
myVal};
int[] arr;
arr={1,2,3}; // error
⑤ 다차원 배열 : 배열을 참조하는 배열
int[][] array;
array = new int[4][5];
array = new int[4][];
array = new int[][5]; => error
array = new int[][]; => error
int[][][] arr = new int[2][3][4];
for(int i=0; i<array.length;i++)
for(int j=0; j<array[i].length;j++)
array[i][j]
int[][] data= {{1,2,3,4,5},
{6,7,8,9,10}};//[2][5]
* System.arraycopy(복사하려는 원본배열, 원복배열의 복사할 시작시점(index), 복사배열을 붙여넣기 할 target 배열,붙여넣기할 target 시작위치, 복사될 요소개수);
System.arraycopy(arrSrc,0,arrDest,2,3);
8. 클래스 : 시스템을 구성하는 구성요소(시스템 적인 요소, 프로그램 내부에서 처리해야하는 구성요소)
① 형식
지정자 class 클래명{
int 멤버변수명;
}
클래스명 인스턴스명 = new 클래스명()
인스턴스명.멤버변수 = 1;
② 클래스의 구성요소 : 멤버변수, 메소드, 생성자
③ 접근 지정자
public : 다 가능
protected : 같은 클래스, 패키지, 상속 가능. 다른 패키지에서 접근 불가.
(default) : 같은 클래스, 패키지 가능. 상속,다른 패키지 불가능.
private : 같은 클래스만 가능. 같은 패키지, 상속,다른 패키지 불가능.
=> 클래스 정의시 멤버변수는 private로 처리하고 메소드로 접근하여 처리.
9. 메소드
접근제어자 리턴타입 메소드명(매개변수1,...){
// 메소드 내부 실행될 명령문
return 리턴값;
// 메소드 선언부에 명시한 리턴타입과 동일한 타입의 데이터 리턴.
}
① 메소드 호출문 종류
1) 매개변수가 없고 리턴타입이 없는 메소드의 호출
2) 매개변수가 1개 이고 리턴값이 없는 메소드의 호출
3) 매개변수가 여러 개인 메소드의 호출 - 매개변수가 여러 개인 경우 ,로 구분해서 값을 정의
=> 반드시 선언된 순서와 동일하게 값을 넘겨줘야한다.
4) 매개변수가 있고 리턴타입이 있는 메소드의 호출
=> 리턴값을 갖고 있는 메소드는 다른 메소드의 매개변수로 바로 전달할 수 있다.
② 메소드 선언 종류
1) 매개변수가 없고 리턴타입이 없는 메소드
2) 매개변수가 있고 리턴타입이 없는 메소드
3) 매개변수가 있고 리턴타입이 있는 메소드
4) 매개변수가 있고 리턴타입이 있는 메소드
③ 메소드 오버로딩
매개변수는 메소드를 유연하게 만든다.(한가지만 처리하지 않도록 하기 때문에 다양한 곳에서 호출이 가능)
매개변수 개수나 타입을 다르게 정의한 메소드명을 동일하게 사용.
④ setter 메소드와 getter메소를 정의하는 방법
set(get)+멤버변수명(멤버변수의 첫글자를 대문자로 변경)
기본 자바에서는 getter나 setter메소드의 이름을 정해진 약속대로 작성하지않아도 문제될 것이 없으나
스프링이나 웹에서 이 명명규칙을 지키지않으면 오류가 발생한다.
1) name 변수에 외부에서 전달하는 값을 셋팅하기 위한 메소드 - setter
public void setName(String name) {
this.name = name; // 멤버변수 name = 지역변수(매개변수) name
}
2) name 변수에 저장된 값을 외부에 전달하는 메소드 - getter
public String getName() {
return this.name;
//return name; // 안붙여도 가능
⑤ oop 특성 (객체 지향 프로그래밍 Object Oriented Programing)
1) 캡슐화 : private 외부에서 데이터를 접근하지 하게 처리.
: 정보 은닉
: 객체의 통신을 통해서 값을 주고 받는다.
: 외부에서는 객체가 무슨일 하고 어떤 기능을 갖고 있는지 안다.
10. 생성자 : 객체가 생성될 때 한번만 호출되는 메소드.
: 주로 자원 제어에 관련된 작업을 수행하거나 객체가 가지고 있는 멤버변수를 초기화.
: new연산자가 생성자 메소드를 통해서 메모리에 할당할 객체가 어떤 클래스인지 파악하고 호출해야 하므로
생성자 메소드를 정의할 때 규칙이 존재한다.
① 형식
클래스타입 변수 = new 생성자메소드(매개변수1, 매개변수2..)
② 규칙
1) 생성자 메소드명은 클래스명과 대소문자까지 동일하게 정의.
2) 생성자 메소드는 정의할 때 리턴타입을 명시하지않는다. (void도 미표기)
3) 클래스를 만들때 생성자 메소드를 정의하지 않으면 컴파일러가 자동으로 매개변수 없는 생성자를 추가한다.
매개변수가 없는 생성자는 기본생성자.
4) 일반 메소드처럼 매개변수 개수나 타입을 다르게 정의하면 여러 개의 생성자를 정의 가능.
생성자 메소드도 오버로딩 가능
5) 생성자 메소드도 일반 메소드처럼 외부에서 값을 전달받아 사용할 수 있도록 매개변수를 정의할 수 있다.
6) 클래스를 정의하면서 생성자 메소드를 한 개 이상 정의하면 컴파일러가 기본생성자를 제공하지않는다.
기본생성자는 자바 프레임워크(Spring)에서 기본으로 호출되므로 기본생성자를 쓸일이 없어도 반드시 기본 생성자는 정의해야한다.
7) 생성자 메소드가 오버로딩되어 있는 경우 자신의 생성자를 호출할 수 있다.
생성자 메소드 안에서 또 다른 생성자 메소드를 호출할 수 있다.
생성자내 생성자 호출시 생성자 맨앞에 호출해야한다.
this(매개변수1, 매개변수2..)
③ static변수(클래스 변수) : 클래스가 로딩될때 한번 메모리에 로딩되어 모든 인스턴스가 공유해서 사용한다.
1) 멤버변수는 객체 참조 변수(인스턴스 변수)를 이용해서 액세스가 가능 (인스턴스 변수는 객체 소유)
2) static 변수는 객체의 소유가 아님으로 인스턴스변수를 통해서 접근하지 않고 클래스명으로 접근함.
3) API 사용 시 static 메소드/변수인지 확인하여 static이면 (클래스명.메소드명) 또는 (클래스명.변수명)으로 사용.
아닐 경우 인스턴스 변수를 선언하여 사용한다. (new 사용)
④ static 메소드의 사용
1) static 메소드는 static변수를 액세스 하기 위한 목적
2) 유틸리티처럼 편하게 사용
⑤ static 메소드 내 non-static 메소드 호출
1) static 메소드에서 static 메소드 호출 - 일반적인 방법으로 접근 가능
2) non-static 메소드에서 non-static 메소드 호출 - 일반적인 방법으로 접근 가능
3) non-static 메소드에서 static 메소드 호출 - 일반적인 방법으로 접근 가능
4) static 메소드에서 non-static 메소드 호출
static메소드에서 non-static메소드를 호출하려면 자신 객체라 하더라도 객체를 생성해서 호출 해야함.
⑥ 초기화 블록 : 생성자 유사
{}
⑦ static 블록
static {}
⑧ 클래스 배열 사용
클래스명[] 인스턴스명 = new 클래스명[배열수];
Person[] personArr = new Person[3];
⑨ call by value
메소드의 매개변수로 값을 넘기는 경우 - 매개변수값을 변경해도 호출부 변수값은 변경되지않는다.
⑩ call by reference
메소드의 매개변수로 배열이나 객체를 넘기는 경우 - 매개변수값을 변경시 호출부 변수값이 변경된다..
String은 매개변수로 값은 전달되나 새로운 객체에 값이 전달된다.
change(i, mainArr);
public static void change(int i,int[] myarr) {
i = 200; => 변경안됨
myarr[2] = 300; => 변경됨
}
class Point{
int x = 10;
int y = 20;
}
Point main_p = new Point(); // 참조형
String mainStr =new String("java"); // 참조형
change(i, main_p,mainStr);
public static void change(int x,Point p,String str) { // String str = new String()이 되어 새로운 객체가 생성
x = 3000; // 값 변경 안됨.
int temp = p.x;
p.x = p.y;
p.y = temp; // 값 변경.
str = "myjava"; // 새로운 객체에 값이 전달됨.
}
11. 상속 : is a 관계 <-> 클래스와 내부 변수 관계 : has a 관계
① 형식
class 자식클래스명 extends 부모클래스명{
}
같은 클래스내 class 생성시 메인 클래스에만 public을 부여한다.
public class 부모클래스명{ // 일반화된 기능이 정의된 클래스. 상위, 부모, super클래스
}
class 자식클래스명 extends 부모클래스 { // 부모클래스를 상속받아 확장해 놓은 클래스. 하위, 자식, sub클래스
}
② 상속관계에서 멤버변수가 갖는 특징
1) 상속관계에서는 상위클래스에 선언된 멤버변수를 하위 클래스에서 접근가능.
2) 상위클래스에서 선언된 변수와 동일한 이름의 변수가 하위클래스에 선언되어 있으면 부모클래스의 멤버변수 보다
자신 클래스의 변수가 우선 순위가 높다.
3) 하위클래스에서 상위클래스의 멤버변수를 접근하고 싶은 경우 super를 이용해서 접근한다.
this : 자기자신
super : 부모
super.변수명;
4) 상위 클래스의 멤버가 private인 경우에는 하위클래스라고 하더라도 접근할 수 없다.
③ 상속관계에서 메소드가 갖는 특징
1) 상위클래스에서 정의된 메소드를 하위클래스에서 호출할 수 있다.
2) 하위클래스의 참조 변수를 통해서 상위클래스의 메소드를 호출할 수 있다.
3) 상위클래스에 정의된 메소드와 동일한 메소드를 하위클래스에서 정의한 후 호출하면 하위클래스의 메소드가
우선으로 인식됨.
* 메소드 오버라이딩 : 상위클래스의 메소드선언부를 동일하게 하여 메소드를 정의하는 것.
: 메소드를 오버라이딩하는 경우 반드시 메소드 선언부(리턴타입, 매개변수 개수, 매개변수 타입)가
상위클래스와 동일해야함.
4) super를 이용해서 부모의 메소드를 사용할 수 있다.
super.메소드명();
④ 상속관계에서 생성자의 특징
1) 모든 클래스의 모든 생성자의 첫 번째 문장은 부모의 기본 생성자를 호출하는 호출문이 생략되어있음.
: 부모의 기본생성자를 호출하는 명령문 = super()
: this()를 이용해서 자기 자신의 다른 생성자를 호출하는 경우는 기본생성자를 생성하지않음.
2) 모든 클래스의 최상위 클래스는 java.lang.Object 클래스
자바에서 객체가 갖는 공통의 특징을 Object에 정의해놓고 컴파일러를 통해서 자동으로 상속받음.
(단, 상속하고 있는 클래스가 없는 경우 - 자바는 하나의 클래스만 상속할 수 있다.)
class Super extends Object{
}
3) 상위클래스에 정의되어 있는 멤버변수의 값을 셋팅해야하는 경우 부모에 정의되어 있는 매개변수 있는 생성자를
직접 호출해서 작업할 수 있다.
super(매개변수1, ...);
- 문자열1.equals(문자열2) => String은 같은 문자열내용이 같더라도 주소값이 다를 수 있으니 equals()를 사용한다.
- static 메소드 : 객체에 의해 값이 달라지지않는 다면 static으로 처리한다.
- 메서드 오버라이딩 : static final private는 오버라이딩 불가.
11. 다형성
1) super타입의 참조변수로 super객체를 접근
Parent obj1 = new Parent();
부모타입 변수 = new 부모객체();
2) sub타입의 참조변수로 sub객체를 접근
Child obj1 = new Child();
자식타입 변수 = new 자식객체();
3) super타입의 참조변수로 sub객체를 접근
Parent obj3 = new Child();
부모타입 변수 = new 자식객체()
obj.멤버변수; => 부모 멤버변수 실행.
obj3.display(); => 부모, 자식 오버라이딩된 메소드일 경우 자식 메소드 실행.
obj3.show(); => 부모에는 없고 자식 메소드일 경우 error.
((Child)obj3).show(); => 단, 참조변수의 타입이 부모타입이지만 실제 생성된 객체가 하위 객체인 경우에는
명시적으로 하위타입으로 형변환을 해서 접근할 수 있다.
객체의 형변환 : Sub객체는 자동으로 Super타입으로 변환된다.
=> 참조형의 형변환은 상속관계에 있는 경우 상위타입의 변수가 하위타입의 객체를 참조하는 경우 자동으로 형변환됨.
1) 오버라이딩된 메소드가 있는 경우 오버라이딩된 메소드가 우선으로 인식된다.
2) 오버라이딩된 메소드를 빼면 무조건 참조변수의 타입을 기준으로 모든 멤버를 접근할 수 있다.
4) sub타입의 참조변수로 super객체를 접근(불가)
Child obj4 = new Parent(); => obj4는 형변환을 할 수 없다. Parent를 Child로 변환해야 하는
Parent에는 Child정보가 없으므로 변환이 불가능
5) sub타입의 참조변수 = Super객체를 참조하는 Super타입의 변수 (불가)
Parent obj1 = new Parent();
Child obj5 = (Child)obj1;
-> 명시적으로 캐스팅하면 컴파일러는 속일 수 있다.(단, 상속관계에 있는 경우에만 가능)
-> 컴파일러는 속였으나 실제 실행될때 obj1이 Parent를 참조하고 있으므로 Child로 타입을 변환할 수 없다.
6) sub타입의 참조변수 = Sub객체를 참조하는 super타입의 변수
Parent obj3 = new Child();
Child obj6 = (Child)obj3;
obj6.display(); => Child의 메소드
-> obj3이 parnet타입이지만 실제 참조하는 객체가 Child이므로 Child로 변환이 가능
12. 추상클래스 : 미완성된 클래스 즉, 모든 내용이 구현되어 있지 않은 클래스로 완성되지 않았으므로 객체를 생성할 수 없다.
: 내용이 정의되지 않은 메소드를 갖고 있는 클래스
추상메소드(body가 없는 메소드)
1) 추상메소드를 선언하는 방법
접근제어자 abstract 리턴타입 메소드명(매개변수list.....);
public abstract class 클래스명{ // 추상클래스
public abstract void 메소드명(int a, int b); // 추상메소드
=> 추상메소드를 정의하면 클래스도 미완성된 클래스 즉, 추상클래스가 되므로 클래스 선언부에 반드시 abstract키워드를 추가해야 한다.
}
2) 추상클래스의 특징
- 일반메소드, 추상메소드, 일반멤버변수 모두 정의할 수 있다.
- 추상메소드가 하나라도 있으면 추상클래스이므로 abstract을 클래스 선언부에 추가한다.
- 추상클래스는 객체 생성을 할 수 없다. (상위클래스로 사용할 목적으로 설계)
=> 추상클래스타입 인스턴스명 = new 추상클래스명(); => 불가.
Super s = new Super();
=> 추상클래스타입 인스턴스명 = null; => 가능.
Super s = null;
=> 추상클래스타입[] 인스턴스명 = new 추상클래스명[index]; => 가능
Super[] s = new Super[3];
- 추상클래스를 상속받은 클래스는 부모의 추상 클래스를 오버라이딩 하지않으면 에러가 발생.
=> Sub가 Super를 상속받으면 Super의 모든 멤버가 Sub의 소유가 된다.
그러므로 Sub는 추상메소드를 갖게 된다.
- abstract클래인 상위클래스가 갖고 있는 추상메소드를 오버라이딩해서 body를 구현
13. final 키워드
1) 변수 - 변수를 상수로 정의
public final static int START_VALUE = 2000; //관용적으로 상수는 대문자로 정의
START_VALUE = 3000; //error. 상수 : 절대 변경되지 않는 값을 저장하는 변수
2) 메소드 - 오버라이딩 할 수 없는 메소드
class Parent{
public final void 메소드(){ // 부모클래스의 메소드가 final이면
}
}
class Child extends Parent{
public void 메소드(){ // error. 자식 메소드는 오버라이딩 할 수 없다. (보안 목적)
}
}
3) 클래스 - 상속을 할 수 없는 클래스
final class Parent{ // 부모클래스가 final이면
public final void 메소드(){
}
}
class Child extends Parent{ // error. final인 클래스는 상속 할 수 없다. (보안 목적)
public void 메소드(){
}
}
14. interface : 추상메소드와 상수만 정의할 수 있는 클래스
: 사용목적은 다형성, 다중상속 구현
: 상위클래스로 사용하기 위한 목적
: 타입으로 사용하기 위한 목적
1) 인터페이스는 interface키워드를 이용해서 선언
2) 인터페이스는 추상메소드만 정의하는 클래스. 하위클래스에서 상속하고 오버라이딩하면 자동으로 public이 추가되므로 메소드를 정의할 때 public abstract은 생략이 가능
interface 인터페이스명1{
void 메소드명(); //추상메소드
}
3) 클래스가 인터페이스를 상속하는 경우 implements키워드를 이용.
class 자식클래스명 extends 부모클래스 implements 인터페이스명1, 인터페이스명2{
}
4) 인터페이스가 인터페이스를 상속하는 경우 extends를 이용.
interface 인터페이스명2 extends 인터페이스명1{
}
5) 인터페이스끼리 다중상속이 가능. 여러 개의 인터페이스를 ,로 연결해서 동시에 상속.
interface 인터페이스명3 extends 인터페이스1, 인터페이스2..{
}
6) 클래스가 인터페이스 다중 상속이 가능. 여러 개의 인터페이스를 ,로 연결해서 동시에 상속
7) 클래스와 인터페이스를 동시에 상속하는 경우 extends가 implements보다 먼저 선언해야한다.
class 자식클래스명 extends 부모클래스명 implements 인터페이스명1, 인터페이스명2 {
}
8) 자식 객체로 부모타입 인스턴스에 대입가능.
Interface Parent1{
}
Interface Parent2{
}
class Parent2{
}
class Child extends Parent2 implements Parent1, Parent2{
}
Child obj = new Child();
메소드1(obj);
메소드2(obj);
메소드3(obj);
public static void 메소드1(Parent1 obj){ // 부모 인터페이스 인스턴스
}
public static void 메소드2(Parent2 obj){ // 부모 인터페이스 인스턴스
}
public static void 메소드3(Parent3 obj){ // 부모 클래스 인스턴스
}
9) instanceof - 객체가 클래스타입(하위 타입)인지 체크하는 연산자
if(인스턴스 instanceof 클래스타입/인터페이스타입){ // true or false 리턴
}
10) 익명 이너 클래스(Anonymous Inner class) : 클래스명 없이 클래스의 기능을 정의하여 생성.
interface Super{
void display();
}
Super obj2 = new Super() { // 클래스명 implements Super
// Super의 하위 클래스를 바로 정의해서 생성
public void display() {
}
};
JFrame f = new JFrame("익명이너클래스 테스트");
JButton btn = new JButton("누르세요");
//이벤트 연결 - 익명클래스를 클래스 안에 바로 정의하고 생성해서 메소드의 매개변수로 전달한 예.
btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("이너클래스로 연결한 이벤트");
}
});
f.add(btn);
f.setSize(300,300);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
9. 예외처리
① Exception이 발생하는 경우
1) 개발자가 실수할 수 있는 부분
1. 0으로 나누는 경우 - ArithmeticException
10/0
2. 배열의 index 참조를 잘못한 경우 - ArrayIndexOutOfBoundsException
args[0]
3. null인 참조변수를 액세스해서 사용하려는 경우 - NullPointerException
String str = null;
str.charAt(0);
4. 캐스팅 잘못한 경우 - ClassCastException
Super obj = new Super();
Sub obj2 = (Sub)obj;
2) 사용자가 실수할 수 있는 부분
1. 사용자가 잘못된 입력 - InputMismatchException
int num = key.nextInt();
2. API에서 예외처리를 요구하는데 처리하지 않은 경우
API에서 예외처리를 문법적으로 요구하는 경우
RuntimeException의 하위 Exception이 아닌 경우 반드시 문법적으로 예외에 대한 처리를 해야한다.
예외처리를 하지않으면 문법적으로 예외처리를 하도록 오류를 발생시킨다. (컴파일체크오류)
new String().getBytes("java");
FileInputStream fs = new FileInputStream("test.txt");
② try catch catch finally
try{
// 예외발생 가능성이 있는 코드
// 예외가 발생되지않으면 catch블록이 실행되지않는다.
}
catch(ArithmeticException e){
}
catch(InputMismatchException e) {
}
catch(Exception e){ // 상위 Exception에 대한 처리는 가장 마지막 블럭으로 처리한다. 다형성
// 예외가 발생되면 처리할 코드
// 예외가 발생되면 try블럭이 끝까지 실행되지 못하고 catch가블럭으로 제어가 넘어온다.
e.getMessage();
e.printStackTrace(); // 예외발생시 오류발생 클래스와 오류 라인을 출력.
}
finally{
//반드시 실행되어야하는 문장 - 메모리해제
}
③ throws 처리 : throw를 이용해서 당장 예외가 발생되는 곳에서 처리하지않고 호출한 곳에서 try catch로 처리해야함
: 각각 다른 방법으로 예외를 처리할 수 있다.
public void test(String fileName) throws FileNotFoundException{
FileInputStream fis = new FileInputStream(fileName); // 예외 발생
}
class A{
void a(){
try {
test("test.txt");
}
catch(FileNotFoundException e) {
// 예외처리 방법 A
}
}
}
class B{
void b(){
try {
test("test.txt");
}
catch(FileNotFoundException e) {
// 예외처리 방법 B
}
}
}
public static void main(String[] args) {
A obj = new A();
B obj = new B();
obj.a();
obj.b();
}
④ 상 하위 관계의 Exception 처리 : 하위의 Exception은 상위 Exception만 처리해도 모두 적용할 수 있다.(객체의 다형성)
: RuntimeException의 하위 Exception은 throws하지않아도 문법적으로 문제사항이
아니나 명시적으로 모두 처리한다.
public void test() throws ArithmeticException{
System.out.println(10/0);
}
public void test2() throws ArithmeticException, FileNotFoundException{
test();
FileInputStream fis = new FileInputStream("test.txt");
}
public void test3() throws UnknownHostException, IOException, ArithmeticException, FileNotFoundException{
test2();
Socket socket = new Socket("127.0.0.1",12345);
}
public void test4() throws IOException{
test2();
Socket socket = new Socket("127.0.0.1",12345);
}
// UnknownHostException, FileNotFoundException은 IOException의 하위이므로
// IOException만 처리해도 모두 적용할 수 있다.
⑤ throw : 새로운 예외를 발생시킨다.
: try catch로 처리하거나 메소드인 경우 throws를 이용해서 호출하는 곳에서 처리할 수 있도록 넘긴다.
try {
throw new PasswordCheckException("패스워드가 3번 틀렸습니다.");
}
catch(PasswordCheckException e){
System.out.println(e.getMessage());
}
catch(IllegalArgumentException e){
System.out.println(e.getMessage());
}
⑥ 사용자 정의 Exception : Exception을 상속받아 구현한다. 해당 Exception class의 생성자에 매개변수를 전달하여
메시지도 정의 가능하다.
public class TempException extends Exception {
public TempException(){
}
public TempException(String message){
super(message);
}
}
<tip>
- sysout + ctrl + space => System.out.println();
- System.out.println() : 빈줄 삽입
- import 추가 단축키 : ctrl+shift+o
- break point
F5 : 함수 안으로 이동.
F6 : 다음 줄로 이동.
F7 : 현재 함수 끝까지 실행.
F8 : 다음 중단점으로.
F11 : 디버깅 시작
- 명령행 매개변수 (args 사용하기) : 실행창 오른쪽 클릭 - Run as - Run configurations - Arguments Tab -
Proram argument - Variable - string_prompt 선택 - 공백을 기준으로 arg[]배열에 입력될 값 입력.
- setter, getter 자동생성 : Source - Generate setters and getters
- setter, getter 메소드 : Source - Generate setters and getters
- 생성자 자동생성 : Source - Generate Constructor using fields