[멋사 TIL] 13기 day8

이은서·2024년 12월 14일
1

멋사

목록 보기
9/11
post-thumbnail

복습

String은 불변클래스였다.
string을 print할 때 생각하면 또 생기고 또 생기고 또 생기고 했던 거네?
→ 더 효율적으로 쓸 수 있게 도와주는 것이 string buffer, string builder
→ 이것으로 객체 만들어 여기서 연산 -> 이런 일 방지

String str1 = "hello";
String str2 = "hello";
System.out.println(str1 == str2); // true
System.out.println(str1.equals(str2)); // true; 같은 객체예요~

주소를 봤는데도 같은 것으로 보아 같다

toString()
객체의 정보 한눈에 보고 싶음: 서랍을 꼭 열어보지 않아도 가능해짐

final
메서드 : 오버라이드 불가
클래스 : 상속 불가

(레퍼런스 변수명) instanceof
인스턴스만 보는 것
너 ~의 인스턴스야?




day6의 이걸 기억하는가?

편할 것 같다고 해서 무조건 상속받아서는 안된다.

그런데 여전히 이 문제가 남아있다.

🤔 "중복된 코드를 계속 둬야 할까?"
🤷🏻‍♀️ "어떻게 해결할 수 있을까?"

중복되는 코드가 많을 때 수정해야 할 파트가 많아지기 때문에 오류 발생 확률이 높아진다. 그래서 코드를 불러다 쓰는 방법이 없을까 하고 고민해야 함
차, 트럭, 스포츠카, 오토바이 모두 "달린다" 코드가 중복될 텐데.. 상속을 쓰자니 말은 안되고... 어떻게 해야 할까?

또 비슷한 케이스

나비, 새, 비행기, 헬기는 모두 날 수 있다.
각자 나는 방식은 다르지만 추상클래스의 추상메서드처럼 만들고 싶을 수 있음
추상메서드는 상속을 해야 하는데, 이 넷은 일반화시키기 애매



인터페이스

이럴 때 기능만 가지고 있는, 구현체도 없는 [ 날다라는 인터페이스 ]를 이용할 수 있다.

인터페이스란?   기능만 가지고 있는, 리모콘 같은 애


인터페이스의 특징

기능의 통일성

어느 리모콘을 봐도 작동방법을 고민하지 않고 전원버튼을 키고 동작이 가능하다. 즉, 인터페이스는 기능이 통일되어 있다.

결합도가 낮다

결합도가 높으면 안 되는 이유는 얘를 수정하면 쟤도 수정해야 함
결합도를 낮추는 방식으로 인터페이스를 이용하는 것
(직접 접근하는 대신)

TV 만들기

STV 따로 LTV 따로 만들기 --- ①
VS
TV 인터페이스로 둘 다 만들기 --- ②

package day08;

public class STV implements TV{
    //전원,채널,소리
    private boolean power;
    private int channel;
    private int volume;


    public void togglePower(){
        power = !power;
        if(power) {
            System.out.println("STV가 켜졌습니다.");
        }else{
            System.out.println("STV가 꺼졌습니다.");
        }
    }

    public void volumeUp(){
        if(power) {
            volume++;
            System.out.println("STV가 볼륨을 키웁니다." + volume);
        }
    }

    public void volumeDown(){
        volume--;
        System.out.println("STV가 볼륨을 줄입니다."+volume);
    }

    public void channelUp(){
        channel++;
        System.out.println("STV가 채널이 바뀌었습니다."+channel);
    }
    public void channelDown(){
        channel--;
        System.out.println("STV가 채널이 바뀌었습니다."+channel);
    }
    public void setChannel(int channel){
        this.channel = channel;
        System.out.println("STV가 채널을 돌립니다."+channel);
    }


}

① - 결합도가 높은 상태
그래서 새로운 객체를 사용하면 몽땅 바뀌어야 함

② - 결합도가 낮은 상태
인터페이스를 쓰는 지금, TVUser클래스에서는 코드를 많이 수정해줄 필요 없이 인터페이스 TV의 메소드들을 구현해주기만 하면 된다. 뒷단에서 바뀌더라도 앞단에서 별다르게 바뀌지 않는다.
껍데기를 같도록 정의한 것.

cf. 웹 개발 단에서 살펴본 인터페이스



인터페이스 갖다쓰기

구현체가 있는 메서드를 쓸 수 있다 (java 8 이후로)

추상 메서드만 갖는 구조이지만, 자바 8 이후로 구현체{}가 있는 메서드에 defaultstatic을 붙이면 가질 수 있다.

필드값을 가질 수 있다. (java 8 이후로)

public int A = 10; // final static 생략됨 (상속)

⁕ 단, 변수가 아닌 고정인 상수값만!

인터페이스도 상속 가능!

가끔 아예 비어있는 인터페이스들도 있음

다중 상속이 가능하다.

상속에서는 부모가 여럿일 경우 어떤 부모의 것을 가져다 써야하는지 알 수 없는 문제 때문에 다중 상속이 안 됐었다.
근데 인터페이스는 상수값과 static값만 가지기 때문에 다중 상속이 가능하다.

주의
인터페이스는 static final만 가질 수 있는 거지 변수를 가지진 못함~ 인터페이스 내에 상수는 가능하지만 일반 변수는 안됨

이렇게 해주는 이유?
인터페이스 안에 static 메소드를 선언해주는 이유: 그냥 인터페이스 안에 있는 상수처럼 그렇게 가지고 있고 싶었던 거


default() 메소드

세상에 이미 인터페이스가 만들어져 이걸 이용하는 객체들이 많은데 이 인터페이스를 수정하면 오류가 날 것임
그래서 그럼 오류가 나지 않도록, 이제부터 만들어지는 애들은 추가했으면 좋겠어~ 할 때 default() 써주면 됨
가장 본질적 목적은 ObjecttoString() equals()
오버라이드해서 쓸 필요 있는 애만 갖다 쓰던 식이었으니깐

cf. Interface Serializable :(뭐였더라)

캘린더: 추상 클래스; new Calendar가 안됨
그런데 Calendar.getInstance()
생성자에 private 붙어 있는 클래스: 자기 자신을 리턴하는 메서드가 있어야 클래스 쓸 수 있을 것

final 필드의 필요성 중
가독성을 위해 상수에 final 필드를 사용해볼 수 있다




예외처리

예외를 만나면 프로그램이 종료된다. 그러면 안되기 때문에 미리 예외를 예측하고 미리 "처리"해야 한다.

try-catch

try{a} : a를 해봐!
근데 예외가 발생하잖아? 그럼
여기 catch(){b}b를 해줘!
~를 해보구(try) 안되면 이렇게 처리(catch)해줘!

이렇게 하면 프로그램이 종료되지 않고 이후 코드 실행이 가능하다.

❗주의

  • try 블록을 실행하는데 예외가 발생하면 안에 있더라도 그 다음 문장이 실행이 안된다. 예를 들어 try 블록의 첫줄을 실행하고 에러가 뜨면 try 블록의 2번째, 3번째 코드는 실행이 되지 않는다.

  • 미리 [A예외]를 생각해서 catch처리를 해줬는데 다른 [B예외]가 발생하는 상황이 생길 수 있다.
    catch 블록을 여러 개 쓸 수 있다.

e.g.
늦잠을 위한 예외 처리: 알람
이중삼중 예외처리: ..."엄마부탁"



Exception 클래스

모든 예외의 조상은 Exception 클래스이므로 이를 가리킬 수 있다.
Exception을 상속받으면 다 예외.
🔗 Java Docs    🔎 java api Exception
↳ 들어가보면 Exception 클래스가 java.lang 밑에 있으면서 모든 예외의 조상으로 있는 걸 볼 수 잇음

자바 정의 예외 vs 사용자 정의 예외
import가 없는 exception
lang 패키지 api 문서에 자바가 정의한 예외들
뻔한 경우에 나오는 애들

import 하는 exception
패키지 임포트해주고 사용하는 예외들

③ 사용자 정의 exception
사용자 정의 예외는 우리가 예외상황을 만드는 것


cf. Exception etoString()오버라이드 되어있음을 볼 수 있음! System.out.println(e)하면 확인 가능



finally

finally가 필요한 이유

  • 물론 모든 예외 대해 catch(Exception e){}해서 '너가 처리해~' 할 수 있다. 하지만 이렇게 하겠다는 건 '난 어떤 예외가 나와도 다 똑같이 처리할 거야~' 하는 것이다.
  • 앞서 try-catch문에서 catch를 여러 개 써서 A예외, B예외에 대해 처리해주는 경우를 살펴봤다. catch를 여러개 써서 잡히면 다행이지만 그래도 비효율적이며, 또 모르는 제 3의 예외가 발생할 수 있음. 즉, try문 실행 중 또 에러가 날 수 있다는 뜻
  • 어딘가에 뭔가 연결했다~ 하는 애들은 열 수 잇는 숫자 한정되어 있기 때문에 썼으면 반납해야 함. 이렇듯 반드시 실행해야 하는 코드들이 있음.

따라서 필수적인 finally 블록.


❓각각의 예외 객체들이 하는 일이 있을까?
자체가 뭘 하지는 않는다.

다른 경우라면 printStackTrace():

0개의 댓글