본문 바로가기

Programming/국비학원

220504 - 어노테이션, 다형성(클래스, 메소드, 매개변수), 추상클래스, 7장 상속 확인문제

※ 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""김철수"00);
        
        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(nullnull00);
        //오버라이드 메소드 이용 (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 사용 시점