※ F2 : 클래스 이름 수정
※ ctrl + space : 기본(default) 생성자 추가
어노테이션 (Annotation)
: 메타 데이터(코드에 대한 설명 제공) 용도 大 (=주석)
코드 문법 에러 체크
코드 자동 생성
실행 시 특정 기능 실행
참고:
https://honbabzone.com/java/java-anontation/
JAVA 어노테이션에 대한 정리
자주 등장하는 어노테이션(annotation)에 대해 조금더 개념적으로 접근하고자 하여 정리하였습니다.
honbabzone.com
https://bangu4.tistory.com/199
[Java] Annotation 어노테이션 - 총정리
1. 어노테이션이란? 자바 어노테이션(Java Annotation) 에노테이션은 주석이라는 의미를 가진다. 자바 소스 코드에 사이에 @ 기호를 앞에 붙여서 사용하는데, JDK 1.5 버전 이상에서 사용 가능하다. 어
bangu4.tistory.com
- 내장 어노테이션
@Override
int witdhraw(int amount) throws Exception { //오류 발생 => 오타 방지
- 커스텀 어노테이션
new - Annotation - Add @Retention-Runtime & Add @Target
=>
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RUNTIME)
public @interface PrintAnnotation {
String value() default "#"; //값 전달받지 않으면 default로 # 출력
int number() default 20;
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class Service {
@PrintAnnotation
public void corona() {
System.out.println("코로나 박멸!");
}
@PrintAnnotation("*") //PrintAnnotation.class 값 변경
public void corona2() {
System.out.println("오미크론 박멸!");
}
@PrintAnnotation(value="$", number=30) //PrintAnnotation.class 값 변경
public void corona3() {
System.out.println("변이 코로나 박멸!");
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import java.lang.reflect.Method;
public class ServiceEx1 {
public static void main(String[] args) {
Method[] methods = Service.class.getDeclaredMethods();
//서비스 클래스에서 만들어진 메소드 정보 얻음 for (Method m : methods) {
if (m.isAnnotationPresent(PrintAnnotation.class));
PrintAnnotation print = m.getAnnotation(PrintAnnotation.class);
System.out.println("***"+m.getName()+"***"); //메소드이름 (corona) 출력
for (int i=0;i<print.number();i++) {
System.out.print(print.value());
}//내부for
System.out.println();
try{
//메소드 호출
m.invoke(new Service());
//메소드 안 내용 출력 요구 //try catch 필수( null의 가능성) }catch(Exception e) {
System.out.println("메소드 처리 에러");
}
}//외부for
}
}
|
cs |
|
|
|
//
***corona***
####################
코로나 박멸!
***corona3***
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
변이 코로나 박멸!
***corona2***
********************
오미크론 박멸!
- 독도 사랑 통장
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public class DokdoAccount extends Account { //상속
//필드
int point=0; //기금 포인트 누적, 0.1% => 1000원하면 1원 됨
//생성자
public DokdoAccount(String accountNo, String ownerName, int balance, int point) {
super(accountNo, ownerName, balance); //부모생성자 호출
this.point=point;
}
//메소드
@Override
void deposit(int amount) {
super.deposit(amount); //예금한 금액 //부모메소드 호출
point+=(int)(amount*0.001); //누적된 포인트
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class DokdoAccountEx1 {
public static void main(String[] args) {
DokdoAccount chulsu = new DokdoAccount("1-22-333", "김철수", 0, 0);
chulsu.deposit(10000);
System.out.println("잔액 : "+chulsu.balance);
System.out.println("독도사랑기금 : "+chulsu.point);
chulsu.deposit(50000);
System.out.println("잔액 : "+chulsu.balance);
System.out.println("독도사랑기금 : "+chulsu.point);
}
}
|
cs |
다형성
: 같은 타입의 다양한 객체를 이용할 수 있는 성질
기본 타입 타이어 => 규격에 맞으면 금호타이어, 한국타이어 모두 교체 가능
클래스 다형성 (자동 타입 변환)
부모클래스 A = new 자식클래스();
=> 부모클래스로 선언, 자식클래스로 생성 => 결과적으로 부모클래스 타입 산출됨
=> 부모클래스에 존재하는 메소드만 사용 가능
=> 부모, 자식클래스에 동시에 존재 => 자식클래스가 오버라이딩한 메소드 사용
cf. 강제 타입변환 (부모 객체가 자식 타입으로 강제 타입 변환)
조건 : 자식 -> 부모 -> 자식 클래스로 재변환하는 경우만 가능
부모클래스에 기본(default) 생성자 없으면 자식클래스 기본생성자 생성 불가(오류)
- 자동 형변환 / 강제 형변환
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class PolymorphismEx1 {
public static void main(String[] args) {
Account chulsu1 = new Account();
CheckingAccount gildong1=new CheckingAccount();
//원 클래스에 디폴트 생성자 추가함 CreditLineAccount chanho1 = new CreditLineAccount();
Account chulsu = new CheckingAccount(); //자동 형변환
//선언은 Account, 생성은 CheckingAccount => 결과: Account 타입
//선언된 클래스의 메소드만 사용 가능 ex. Account (withdraw, deposit)
Account gildong = new CreditLineAccount();
//오버라이드한 메소드 이용 (Credit의 withdraw)
Account chanho = new DokdoAccount(null, null, 0, 0);
//오버라이드 메소드 이용 (Dokdo의 deposit)
CheckingAccount younghee = (CheckingAccount)chulsu1; //강제형변환
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
public class Car {
//필드
Tire frontLeftTire = new Tire("앞 왼쪽", 7);
Tire frontRightTire = new Tire("앞 오른쪽", 3);
Tire backLeftTire = new Tire("뒤 왼쪽", 5);
Tire backRightTire = new Tire("뒤 오른쪽", 4);
//default 생성자
//메서드
int run() {
System.out.println("자동차가 달립니다. 씽씽");
if(frontLeftTire.roll()==false) {
stop();
return 1;
}
if(frontRightTire.roll()==false) {
stop();
return 2;
}
if(backLeftTire.roll()==false) {
stop();
return 3;
}
if(backRightTire.roll()==false) {
stop();
return 4;
}
return 0; //펑크 안 날 때
}
void stop() {
System.out.println("자동차가 멈춥니다.");
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public class Tire {
//필드
public int maxRotation; //타이어 수명
public int accumulatedRotation; //누적 회전수
public String location; //타이어 위치 (4곳)
//생성자
public Tire(String location, int maxRotation) {
this.location=location;
this.maxRotation=maxRotation;
}
//메서드
public boolean roll() {
accumulatedRotation++;
if (accumulatedRotation<maxRotation) {
System.out.println(location+" 타이어의 수명 : "+(maxRotation-accumulatedRotation)+"회");
return true;
}else {
System.out.println("*** "+location+" 타이어 펑크 ***");
return false;
}
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class HankookTire extends Tire {
//필드 상속
//생성자
public HankookTire(String location, int maxRotation) {
super(location, maxRotation);
}
//메소드 오버라이드
@Override
public boolean roll() {
accumulatedRotation++;
if (accumulatedRotation<maxRotation) {
System.out.println(location+" 한국타이어의 수명 : "+(maxRotation-accumulatedRotation)+"회");
return true;
}else {
System.out.println("*** "+location+" 한국타이어 펑크 ***");
return false;
}
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public class KumhoTire extends Tire {
//필드 상속
//생성자
public KumhoTire(String location, int maxRotation) {
super(location, maxRotation);
}
//메소드 오버라이드
@Override
public boolean roll() {
accumulatedRotation++;
if (accumulatedRotation<maxRotation) {
System.out.println(location+" 금호타이어의 수명 : "+(maxRotation-accumulatedRotation)+"회");
return true;
}else {
System.out.println("*** "+location+" 금호타이어 펑크 ***");
return false;
}
}
}
|
cs |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
public class CarEx1 {
public static void main(String[] args) {
Car csMyCar = new Car(); //인스턴스 객체 생성
for (int i=1;i<=5;i++) { //5번 달림
int problemLocation = csMyCar.run();
switch (problemLocation) { // 펑크 안 나면 0
case 1:
System.out.println("앞 왼쪽 금호타이어로 교체");
csMyCar.frontLeftTire=new KumhoTire("앞 왼쪽", 15); //★다형성
break;
case 2:
System.out.println("앞 오른쪽 한국타이어로 교체");
csMyCar.frontRightTire=new HankookTire("앞 오른쪽", 10);
break;
case 3:
System.out.println("뒤 왼쪽 한국타이어로 교체");
csMyCar.backLeftTire=new HankookTire("뒤 왼쪽", 13);
break;
case 4:
System.out.println("뒤 오른쪽 금호타이어로 교체");
csMyCar.backRightTire=new KumhoTire("뒤 오른쪽", 12);
break;
}//switch
System.out.println("-----------------");
}//for
}
}
|
cs |
매개변수의 다형성
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
public class Driver {
//메소드
void Drive(Vehicle vehicle) { //Vehicle 타입의 클래스 받음
vehicle.run();
}
}
public class Vehicle {
//메서드
public void run() {
System.out.println("차량이 달립니다.");
}
}
public class Bus extends Vehicle {
@Override
public void run() {
System.out.println("버스가 달립니다.");
}
}
public class Taxi extends Vehicle {
@Override
public void run() {
System.out.println("택시가 달립니다.");
}
}
public class DriverEx1 {
public static void main(String[] args) {
Driver chulsu = new Driver();
Taxi taxi = new Taxi();
Bus bus = new Bus();
chulsu.Drive(taxi); //오버라이딩
chulsu.Drive(bus);
}
|
cs |
//
택시가 달립니다.
버스가 달립니다.
추상클래스
: 실체 클래스 간 공통 특성 추출해 선언한 클래스
=> 인터페이스와 유사, 인터페이스가 더 자주 쓰임
실체 클래스들의 필드, 메소드의 이름 통일시킴
실체 클래스 작성 시 시간 절약
=>
메소드 이름만 추상 클래스에서 미리 정의해두고, 통일된 이름 다른 클래스들에서 사용하도록
추상클래스 내에는 반드시 추상 메서드(메소드 본체 없음)가 있음
자식 클래스는 추상 메서드 구체화시켜야 함
new 로 객체 생성 불가 => 상속 통해 자식 클래스 생성만 가능함
틀만 만들고 구현은 자식클래스에 넘김
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public abstract class Animal {
String name;
//추상 메서드 : 메서드 본체(중괄호 열고 기능 적는 것)가 없음
abstract void move();
}
public class Tiger extends Animal{
int age; //일반 클래스 사용함
@Override
void move() {
System.out.println("네 발로 이동");
}
}
public class Eagle extends Animal{
String home;
@Override
void move() {
System.out.println("날개로 이동");
}
}
public class AnimalEx1 {
public static void main(String[] args) {
Tiger tiger1 = new Tiger();
Eagle eagle1 = new Eagle();
tiger1.name = "대한이";
tiger1.age = 2;
System.out.println(tiger1.name+"는 "+tiger1.age+"살 입니다.");
tiger1.move();
eagle1.name = "대머리";
eagle1.home = "소나무 둥지";
System.out.println(eagle1.name+"는 "+eagle1.home+"에 삽니다.");
eagle1.move();
}
}
|
cs |
//
대한이는 2살 입니다.
네 발로 이동
대머리는 소나무 둥지에 삽니다.
날개로 이동
7장 상속 확인문제
자바=> 다중 상속 비허용 (하나의 부모 클래스만 상속 가능)
private 필드 메소드 => 상속의 대상이 아님 (외부 클래스 접근 불가해서)
final 클래스 => 상속 X / final 메소드 => 오버라이딩 X (변경 불가)
자식 객체는 부모 타입으로 자동 타입변환
부모 객체는 자식 타입으로 강제 타입변환 (조건: 자식타입이 부모타입으로 자동변환한 후, 다시 자식타입으로 변환할 때만 가능 / 자식->부모->자식 재변환만 가능 / 부모타입 변수가 부모객체 참조하면 불가)
instanceof 연산자 : 강제타입변환 전에 변환 가능한지 검사 (부모타입이기 전에 자식타입이었는지 확인)
자식 메소드 => 부모 메소드보다 좁은 접근제한자 X (부모: public -> 자식 : private)
- 5번 문제
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class Parent {
public String name;
public Parent(String name) { //매개변수 있는 생성자 있으면 -> default 생성자 안 만들어짐
this.name=name;
}
}
public class Child extends Parent {
private int studentNo;
public Child (String name, int studentNo) {
super(name); //부모 생성자 호출
//부모클래스에 default 생성자 없으면 자식클래스에 부모 생성자 명시 호출 필수
(부모 물려받은 것 표시) //this.name=name 시 오류
this.studentNo=studentNo;
}
}
|
cs |
부모클래스에 default 생성자 X
=> super(매개변수) 명시적 호출
부모클래스에 default 생성자 O
=> super();
- 6번 문제
this() : 같은 클래스의 다른 생성자 호출
- 7번 문제
자식=> 부모타입으로 자동형변환 됐을 때, 부모 타입이더라도 메소드는 오버라이딩한 메소드 사용
//
자동, 강제타입변환
super 사용 시점