ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 0809. Java 추상클래스, 인터페이스, 예외처리
    Java 2023. 8. 10. 09:23

    📍추상클래스 Abstract Class

     

     

    다른 클래스와의 차이점

    동물 중에는 조, 곤충, 어류, 포유류 등이 있다.

    동물만이라고 칭할 수 있는게 있을까? => 없다. 

    동물이란 것은 분류하기 위함이고 조류, 곤충, 어류를 지칭하기 위한 "참조" 용도이다. new로 인스턴스를 생성할 필요없다.

     

    참조를 위한 개념이다.

    예시에서 Sleep, eat은 자식이 결정한 것이다.

    부모클래스의 역할만 하며 단독 객체는 없다.

    전략패턴에서 쓰기 위함.

     

    ** 추상 클래스의 선언 **

    abstract가 붙으면 new 는 못 한다.

    그리고 이 부모클래스만의 인스턴스를 만들지 못 한다. (원래는 각 객체로 실행도 되지만 여긴 선언만 할 수 있다)

    자식 인스턴스를 참조하기 위한 용도이다.

     

     

    public class PhoneEx {

    public static void main(String[] args) { // Phone phone = new Phone(); (x) 인스턴스 못 만든다.

    적용예시 ⬇️

    더보기
    public class SmartPhone extends Phone {
    	// 생성자
    	public SmartPhone(String owner) {
    		super(owner);
    	}
    
    	// 메소드
    	public void internetSearch() {
    		System.out.println("인터넷 검색을 합니다.");
    	}
    
    }
    public class PhoneEx {
    	public static void main(String[] args) { // Phone phone = new Phone(); (x)
    
    		SmartPhone smartPhone = new SmartPhone("홍길동");
    
    		smartPhone.turnOn();// Phone의 메서드
    		smartPhone.internetSearch();
    		smartPhone.turnOff(); // Phone의 메서드
    
    		Phone phone = new SmartPhone("홍길동");
    
    		phone.turnOn(); // Phone의 메서드
    		((SmartPhone) phone).internetSearch();
    		phone.turnOff(); // Phone의 메서드
    	}
    
    }

     

    동물은 소리를 낸다. 그러나 동물의 소리란 것을 콕 집어 말할 순 없으니 자식 클래스에서 정의를 내리는데,

    각 실체동물들의 소리는 제각기 다르다.

    sleep은 추상클래스까지, 

    howl은 추상메서드까지 가야한다.

    => 오버라이딩이 된다.

     

    추상메서드는 선언부만 있어 미완성인 상태이므로 완성품으로 만들기 위해 반드시 자식클래스에서 구현부를 재정의, 즉 오버라이딩해야 한다.

     

     


     

     

    자식 클래스는 부모클래스가 추상클래스일 때 추상메서드도 무조건 상속받아야 한다.

    그리고 내부 {} 안에 abstract 메서드,클래스 등의 멤버가 하나라도 존재하면

    그 바깥({}밖) 클래스는 반드시 abstract 클래스여야한다.

    추상화
    클래스간의 공통점을 찾아내서 공통의 조상을 만드는 작업

    구체화
    상속을 통해 클래스를 구현, 확장하는 작업

    📍인터페이스 Interface

     

    추상메서드로만 구성되어 있는 규격이다.

    추상클래스 대신 인터페이스라고 명명한다.

    그러니 abstract 키워드는 안 붙여도 된다.

     

    용도는 다른 객체와 대화하기 위함이다. 추상처럼 참조용이기에 new도 못 쓴다.

    그러니 public 키워드도 생략가능하다.

     

     

     

    ** 인터페이스 선언 **

     

    타입은 return 타입을 뜻한다.

     

    1. 상수 필드 선언

    public static final

     

     

    2. 디폴트 메서드 선언


    3. 정적 메서드 선언

     

     

     


    인터페이스 구현

    (*추상클래스는 상속 UML 실선 / 인터페이스는 구현 UML 점선)

     

    구현 객체와 구현 클래스

     

    implements : 추상메서드를 구현하겠다.

    +) 오버라이드도 해야한다.

     

    인터페이스 구현하기 (1)
    인터페이스 구현하기 (2)

    짠 만들어졌다.

    package java_study.chapter08.sec09;
    
    public class Television implements RemoteControl {
    
    	@Override
    	public void turnOn() {
    		// TODO Auto-generated method stub
    
    	}
    
    	@Override
    	public void turnOff() {
    		// TODO Auto-generated method stub
    
    	}
    
    	@Override
    	public void setVolume(int volume) {
    		// TODO Auto-generated method stub
    
    	}
    
    }

     

     


     

    익명 인터페이스 구현

     

    RemoteControl


     

    다중 인터페이스 구현 클래스

    상속은 다중상속이 안 되지만 인터페이스는 다중구현이 된다.

     

    Searchable

     

    ---

     

    만약 여기서 인스턴스 = new SmartTelevision(); 을 추가한다면

     

    1. 제한 x

    2. turnon, turnoff 메서드만

    3. search 메서드만

    4.object : toString 등 같은 거

    2,3은 거기서 선언한 메서드만 가능.

     

    => 인터페이스 분리의 원칙


    ** 인터페이스 사용 **

    1번 비권장 / 2번을 권장.

    2번을 권장하는 이유 : 결합도가 낮아져서

    타입만 remotecontrol인 게 정해졌을 뿐 어떤 객체를 받을지는 정해져있기 때문.

    다양한 운영, Dependency Injection 가능

    "Program to Interface" 인터페이스를 이용해서 프로그래밍해라.

    인터페이스는 표준, 규격의 역할을 한다.

     

     

     

     


    예외처리 인트로

     

    예외(복구가능)와 에러(복구불가능) 구분

    에러라고 말하는 건 사실 거의 "예외"이다.

    • 예외의 종류

     

     

     

    object를 상속받음으로써 사용자예외를 만들 수 있다.

     

     

     

    예외처리 >> Unhandled exception type IOException.. 이제 이거에 대해 알아보자

     

     

     

     

     

     


    📍예외처리

    위험성이 있는 코드를 다룰 때 쓰는 방법

     

    • 일반 예외 처리 try-catch-finally

     

    method() throws xxx{  } : throw가 붙은 메서드를 사용할 때 반드시 try catch를 사용하여 예외를 전달

     

    예외 발생 이전 상태로 돌려줌

    * 자바 자체의 클래스 : Class

    자바에서 부여한 클래스명 Class 를 사용하기 위해 clazz 라고 표기된 것.

    클래스 로더에게 java.lang.String2<< 이 클래스 있냐고 요청하는 메소드

    찾아서 참조값을 달라.

     

    1. try 블럭을 달라.

    2. 자바에 String2라는 클래스는 없으므로 catch가 출력.

    catch도 생략이 가능한데, 그러면 finally를 써야한다. 밑에서 더 읽어보자.

     

    3.String이라는 클래스는 존재하므로 try 블럭을 출력.

     

     

    4.finally는 예외가 있든 없든 무조건 실행하는 "옵션"임. 생략이 가능하다.

    그러나 catch가 없으면 무조건 finally를 써야 에러가 뜨지 않는다.

     

     

     

    5.여기서 쓰는 return

    예외가 발생하지 않으면 메인 메서드를 리턴해라

    그런데 메인메서드만 출력해도 finally는 옵션이니까 무조건 출력된다.

     

     


    다중 Catch

     

    element 타입 : 문자열

    args는 무엇일까?

     

    1. 그냥 실행하면 별거 없다.

     

    Arguments 창에서 문자열 입력 후 Run 누른 후 실행하면 0이 2로 바뀐다.

    인덱스로 호출하면 입력했던 hello, world 내용이 보인다.

    그리고 문자열인 내용을 정수형으로 출력하면 에러가 뜬다.

     

     

     

    try 씌우고 문자열, 숫자 개수 맞춰서 넣어보기.

    이렇게 나온다

     이것저것 넣어보기

     

    띄어쓰기 단위로 개수를 세어서 7, => 한글로[0], 쓸[1]

     

     

    1 숫자 하나만 넣으면 매개변수가 부족하다고 뜬다.

    try 블럭에는 다양한 예외가 발생할 수 있다.


    예외처리에서의 상속

    가장 상위 : Exception

     

    Exception을 위에 두어버리면 모든 예외가 Exception으로 가므로 아래는 절대 시행 안 된다.

    그러므로 쓰려면 단독으로 쓰거나, 맨 마지막에 써야 한다.

    이 위치를 위로 올려보자.
    이렇게 에러가 뜬다.

     

     

    멀티 catch

    or 연산 " | "

     

    아웃오브바운드거나 넘버포맷이면 해당 블록, 아니면 exception으로 가라.

     

    너무 길어지니까 그냥 exception으로 묶는 게 낫다.

    뭐가 되었든 exception이 막으니까.

     

     

    오류나면 어디서 났는지 찾는 방법

    e.printStackTrace();


    throws

    예외 떠 넘기기

     

     

    a에서 발생한 예외를 b로 넘겼다.

    b에서 발생한 예외는..?

    a로 던져 떠넘긴다..

     

    Add throws declaration

    첫 번째 항목을 선택하면 자동으로 완성된다. ⬇️

    throws ClassNotFoundException

    이제 다시 메인메서드에서의 처리가 필요하다.

     

     

    두 번째 항목 선택

    Surround with try/catch 선택

    예외를 호출했던 쪽(ClassNotFoundException)으로 다시 떠 넘길 수 있다.

     

     

     

    IOException

     

     

    Ctrl 키 누르고 우클릭으로 해당 에러 클래스를 선택하면 설명창으로 이동할 수 있다.


    사용자 정의 예외

    자신하고 가장 유사한 부모클래스를 상속받아서 하면 된다.

    주로 Exception을 상속받아서 정의한다.

    그리고 생성자 2개를 만들면 된다.

     

    한 개는 디폴트 생성자

    한 개는 에러의 이유를 담고 있는 생성자 ⭐

    super는 Exception을 가리킨다.

     

    클래스명은 예외의 이유를 구체적으로 적어주는 게 좋다.

     

    if 문 검사해서 잔액 부족 판단 시 (여기서 계산하여) { } 직접 예외를 발생시켜야 한다.

     

    예외객체(인스턴스)를 하나 만들어야 한다. (또는 메시지를 담은 예외객체)

    이후 메서드에 throw를 붙이면 된다.

     

     

    더보기
    package java_study.chapter09.sec01;
    
    public class Account {
    	private long balance;
    
    	public Account() {
    	}
    
    	public long getBalance() {
    		return balance;
    	}
    
    	public void deposit(int money) {
    		balance += money;
    	}
    
    	public void withdraw(int money) throws BalanceInsufficientException {
    		if (balance < money) {
    			throw new BalanceInsufficientException("잔고부족:" + (money - balance) + " 모자람");
    		}
    		balance -= money;
    	}
    }

     

    throw에 s가 붙은 복수형인 throws인 이유 (동사인 줄 알았는데 명사고..)

    뒤에 예외는 여러 개 생길 수 있어서 .. 콤마로 이어서 적으면 된다.

     

     

    잔고부족

    스택을 보자..

    AccountEx 13열이 바닥, Account 19열이 탑

    여기서 예외가 발생한 곳은 탑인데

    원인제공은 주로 호출한 곳이다. 여기서는 바닥

     

     

    이런 걸 예외처리없이 if else로 계속 검사한다면 상당히 번거롭다.
    그냥 성공 시 try, 실패 시 catch가 알아서 하게끔 하면 성공만 신경쓰면 되니 더 편하다.
Designed by Tistory.