💡 객체 A는 인터페이스를 통해서 객체 B를 사용 할 수 있다.
객체 A가 인터페이스의 메소드를 호출하면 인터페이스는 객체 B의 메소드를 호출하고 그 결과를 받아 객체A로 전달해준다.
인터페이스로 구현 객체를 사용하려면 인터페이스 변수로 선언하고, 구현객체를 대입하여 사용
인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입되면 구현 객체의 번지를 저장한다.
구현객체가 대입되면, 인터페이스 변수로 추상메소드를 호출할 수 있게 된다.
이때, 어떤 구현 객체가 대입되었는지에 따라 실행 내용이 달라진다.
default,
public
을 붙일 수 있음public interface 인터페이스명{
//public 상수 필드
//public 추상 메소드
//public 디폴트 메소드
//public 정적 메소드
//private 메소드
//private 정적 메소
}
implements
키워드는 해당 클래스가 인터페이스를 통해 사용할 수 있다는 표시이며,public class B implements 인터페이스명{}
참조 타입
에 속하므로 인터페이스 변수에는 객체를 참조하고 있지 않다는 뜻으로RemoteControl rc;
RemoteControl rc=null;
rc=new Tv();
public interface RemoteControl //인터페이스 클래스
{
public void trunOn();
public void turnOff();
}
public class Tv implements RemoteControl // 두 객체 중 1개
{
@Override
public void trunOn()
{
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("TV를 끕니다.");
}
}
public class Radio implements RemoteControl // 두 객체 중 1개
{
@Override
public void trunOn()
{
System.out.println("라디오를 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("라디오를 끕니다.");
}
}
public class RemoteControlEx
{
public static void main(String[] args) //실행 클래스
{
RemoteControl rc;
rc = new Tv();
rc.trunOn();
rc.turnOff();
rc=new Radio(); // 부품만 교체
rc.trunOn();
rc.turnOff();
}
}
public static final
특성을 갖는 불변의 상수 필드 값을 멤버로 가진다.public static fianl
특징을 갖는다._
로 연결하는 것을 권장중괄호 { }를 붙이지 않는 메소드
완전한 실행 코드
를 가진 디폴트 메소드를 선언할 수 있음RemoteControl
//디폴트 메소드 : 인터페이스에 넣을 수 있는 완전히 실행코드를 가진 유일한 메소드
default void setMute(boolean mute) {
if(mute) {
System.out.println("무음 처리합니다.");
setVolume(MIN_VOLUME);
}
else {
System.out.println("무음 기능 해제합니다.");
}
}
//디폴트 메소드 재정의 : default 키워드를 삭제 후 public로 변경 후 재정의
public void setMute(boolean mute) {
if(mute) {
this.memoryVolume = this.volume; //해제 후 복구해야 하기 때문
System.out.println("무음 처리합니다.");
setVolume(MIN_VOLUME);
}
else {
System.out.println("무음 기능 해제합니다.");
setVolume(this.memoryVolume); //mute가 false일 때 원래 볼륨으로 복원
}
}
rc = new Tv();
rc.setMute(true); //디폴트 메소드 호출
rc.setMute(false);
static 리턴타입 메소드명(매개변수, ..){...}
상수 필드를 제외한
추상 메소드, 디폴트 메소드, private 메소드 등을RemoteControl
// 정적 메소드 : 추상메소드와 디폴트 메소드는 구현 객체가 필요하지만, 정적 메소드는 구현객체가 없이도 인터페이스만으로 호출 가능
static void changeBattery() {
System.out.println("리모콘 건전지를 교환해 주세요."); //순수하게 RemoteControl에 붙어있음 => 직접호출 가능
}
RemoteControl.changeBattery();
public interface RemoteControl //인터페이스 클래스
{
//public static final 상수
int MAX_VOLUME = 10;
int MIN_VOLUME = 0; //상수선언
// 추상메소드 : 바디{}가 없는 메소드 선언부만 가지고 있는 메소드
public void trunOn();
public void turnOff();
public void setVolume(int volume); //추상 메소드
//디폴트 메소드 : 인터페이스에 넣을 수 있는 완전히 실행코드를 가진 유일한 메소드
default void setMute(boolean mute) {
if(mute) {
System.out.println("무음 처리합니다.");
setVolume(MIN_VOLUME);
}
else {
System.out.println("무음 기능 해제합니다.");
}
}
// 정적 메소드 : 추상메소드와 디폴트 메소드는 구현 객체가 필요하지만, 정적 메소드는 구현객체가 없이도 인터페이스만으로 호출 가능
static void changeBattery() {
System.out.println("리모콘 건전지를 교환해 주세요."); //순수하게 RemoteControl에 붙어있음 => 직접호출 가능
}
// private 메소드 : 구현 객체가 필요한 메소드
// private 정적 메소드 : 구현 객체가 필요없는 메소드
// 인터페이스 내에서 private 메소드의 용도는 디폴드와 정적메소드들의 중복 코드를 줄이기 위해 사용
}
public class Tv implements RemoteControl // 두 객체 중 1개
{
private int volume;
@Override
public void trunOn()
{
System.out.println("TV를 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("TV를 끕니다.");
}
@Override
public void setVolume(int volume)
{
if(volume>RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
}
else if(volume<RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
}
else {
this.volume=volume;
} //인터페이스 상수 필드를 이용해서 volume 필드의 값을 제한
System.out.println("현재 Tv의 볼륨은 "+this.volume);
}
private int memoryVolume;
//디폴트 메소드 재정의 : default 키워드를 삭제 후 public로 변경 후 재정의
public void setMute(boolean mute) {
if(mute) {
this.memoryVolume = this.volume; //해제 후 복구해야 하기 때문
System.out.println("무음 처리합니다.");
setVolume(MIN_VOLUME);
}
else {
System.out.println("무음 기능 해제합니다.");
setVolume(this.memoryVolume); //mute가 false일 때 원래 볼륨으로 복원
}
}
}
public class Radio implements RemoteControl // 두 객체 중 1개
{
private int volume;
@Override
public void trunOn()
{
System.out.println("라디오를 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("라디오를 끕니다.");
}
@Override
public void setVolume(int volume)
{
if(volume>RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
}
else if(volume<RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
}
else {
this.volume=volume;
} //인터페이스 상수 필드를 이용해서 volume 필드의 값을 제한
System.out.println("현재 Radio의 볼륨은 "+this.volume);
}
}
public class WaterMachine implements RemoteControl
{
private int volume;
@Override
public void trunOn()
{
System.out.println("정수기를 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("정수기를 켭니다.");
}
@Override
public void setVolume(int volume)
{
if(volume>RemoteControl.MAX_VOLUME) {
this.volume = RemoteControl.MAX_VOLUME;
}
else if(volume<RemoteControl.MIN_VOLUME) {
this.volume = RemoteControl.MIN_VOLUME;
}
else {
this.volume=volume;
} //인터페이스 상수 필드를 이용해서 volume 필드의 값을 제한
System.out.println("현재 WaterMachine의 볼륨은 "+this.volume);
}
}
public class RemoteControlEx
{
// 인터페이스로 구현 객체를 사용하려면 인터페이스 변수로 선언하고, 구현객체를 대입하여 사용
// 인터페이스 변수는 참조 타입이기 때문에 구현 객체가 대입되면 구현 객체의 번지를 저장한다.
// 구현객체가 대입되면, 인터페이스 변수로 추상메소드를 호출할 수 있게 된다.
// 이때, 어떤 구현 객체가 대입되었는지에 따라 실행 내용이 달라진다.
public static void main(String[] args) // 실행 클래스
{
RemoteControl rc;
rc = new Tv();
rc.trunOn();
rc.setVolume(4);
rc.setMute(true); //디폴트 메소드 호출
rc.setMute(false);
rc.turnOff();
RemoteControl.changeBattery();
System.out.println();
rc = new Radio(); // 부품만 교체
rc.trunOn();
rc.setVolume(7);
rc.turnOff();
System.out.println();
rc = new WaterMachine();
rc.trunOn();
rc.setVolume(8);
rc.turnOff();
System.out.println();
// 상수는 구현 객체와 관련이 없는 인터페이스 소속 멤버이므로 바로 접근해서 상수값을 읽을 수 있다.
System.out.println("리모콘의 최대 볼륨은 " + RemoteControl.MAX_VOLUME);
System.out.println("리모콘의 최소 볼륨은 " + RemoteControl.MIN_VOLUME);
}
}
모두 public 접근 제한
을 가짐항상 외부에서 접근이 가능
public interface RemoteControl
{
void turnOn();
void turnOff();
}
public interface Searchable
{
void search(String url);
}
두 개의 인터페이스를 합친
totalinterface 이로 인해 한 번에 묶어서 두 인터페이스의 메서드를 모두 사용 가능하게 됨public interface totalinterface extends RemoteControl, Searchable //인터페이스의 다중 상속 허용
{ // 만약 필요가 없다면 부품 빼듯이 extends 뒤에서 빼거나 수정시 업데이트 하면 됨
//사용자가 보는 인터페이스 코드 느낌 => 아무것도 볼 수 없음
// 스텁, 인터페이스만 가지고 있음
}
public class SmartTv implements totalinterface
{
@Override
public void search(String url)
{
System.out.println(url);
}
@Override
public void turnOn()
{
System.out.println("스마트 티비 켭니다.");
}
@Override
public void turnOff()
{
System.out.println("스마트 티비 끝니다.");
}
}
public class MultiInterfaceEx
{
public static void main(String[] args)
{
// 두 개의 인터페이스를 같이 묶은
totalinterface ti=new SmartTv();
// RemoteControl 인터페이스 변수 선언 및 구현 객체(SmartTv) 대입
RemoteControl rc = new SmartTv();
// RemoteControl 인터페이스에 선언된 메소드만 호출 해 주세요
rc.turnOn();
rc.turnOff();
System.out.println("===================");
ti.turnOn();
ti.turnOff();
ti.search("우주하마 유투브, 혜안 유투브");
System.out.println("==================");
//Searchable 인터페이스 변수 선언하고 구현 객체 대입
Searchable s = new SmartTv();
// Searchable 인터페이스에 선언된 추상 메소드만 호출해 주세요
s.search("htts://www.youtube.com");
}
}
구현 클래스 변수 = (구현클래스) 인터페이스 변수
예외(Exception)
일반 예외(Exception)
: 컴파일러가 예외 처리 코드 여부를 검사하는 예외if(n2==0) {
System.out.println("0으로 나눌 수 없어요");
}
else {
int result = n1/n2;
System.out.println(result);
} //일반 예외처리
System.out.println("프로그램의 끝");
}
실행 예외(Runtime Exception)
: 컴파일러가 예외 처리 코드 여부를 검사하지 않는 예외try-catch-finally
블록은 생성자 내부와 메소드 내부에서 작성**Exception
은 ArithmeticException, NullPointerException 등의 부모라서 여러 개라고 해도 Exception e
만으로 처리 가능**//Exception handling 한다.
public class ExceptionEx01
{
public static void main(String[] args) {
int n1 = 5;
int n2 = 0;
int result=0;
try{
result = n1/n2;
}
catch(ArithmeticException e){
System.out.println("0으로 나눌 수 없어요");
}
catch(Exception el) {
System.out.println("예외 처리 완료");
}
finally{
System.out.println("예외처리 되었습니다.");
}
System.out.println(result);
System.out.println("프로그램의 끝");
}
}
public class NullPointEx
{
public static void printLength(String data)
{
int result = 0;
try
{
result = data.length();
} catch (NullPointerException e)
{
System.out.println(e.getMessage()); //예외 정보를 얻는 3가지 방법
// System.out.println(e.toString());
// e.printStackTrace()
} catch(Exception e1)
{
System.out.println(e1.getMessage());
}
System.out.println("문자 수: " + result);
}
public static void main(String[] args)
{
System.out.println("프로그램 시작");
printLength("[프로그램 시작]");
printLength(null);
System.out.println("프로그램 종료");
}
}
public static void classNotfoundEx(String message) {
try {
Class.forName(message);
System.out.println("자바표준 API에 "+message +" 클래스가 존재합니다.");
}
catch(ClassNotFoundException e) {
//e.printStackTrace();
System.out.println("표준 API에 없는 클래스입니다. ");
}
}
public static void main(String[] args)
{
classNotfoundEx("java.lang.String2");
}
public class ArrayIndexOutOfEx
{
public static void arryEx(String[] array) {
for(int i=0; i<array.length+1; i++) {
try {
System.out.println(array[i]);
int value = Integer.parseInt(array[i]);
}
catch(ArrayIndexOutOfBoundsException e) {
System.out.println(e.getMessage());
}
catch(NumberFormatException e) {
System.out.println(e.getMessage());
}
}
}
public static void main(String[] args) {
String[] array = {"100", "200", "300", "1ooo"};
arryEx(array);
System.out.println("프로그램종료");
}
}
데이터를 제공하는 객체
try-with-resources
블록을 사용하면 예외 발생 여부 상관없이 리소스를 자동으로 닫아줌public class MyResource implements AutoCloseable
{
private String name;
public MyResource() {};
public MyResource(String name) {
this.name = name;
System.out.println("[My Resource("+name+"]열기");
}
public String read1() {
System.out.println("[My Resource("+name+"]열기");
return "100";
}
public String read2() {
System.out.println("[My Resource("+name+"]열기");
return "abc";
}
@Override
public void close() throws Exception // throws:excetion한테 빨리 처리하라고 떠넘긴 것
{
System.out.println("[My Resource("+name+"]닫기");
}
}
public class TryWithResourceEx
{
public static void main(String[] args)
{
try(MyResource res = new MyResource("A")) {
String data = res.read1();
}catch (Exception e) {
System.out.println("예외처리:"+e.getMessage());
}
System.out.println("===========");
try(MyResource res = new MyResource("A")) {
String data = res.read2();
//NumberFormatException 발생
int value = Integer.parseInt(data);
}catch (Exception e) {
System.out.println("예외처리:"+e.getMessage());
}
System.out.println("===========");
MyResource res1 = new MyResource("A");
MyResource res2 = new MyResource("B");
try(res1; res2){
String data1 = res1.read1();
String data2 = res2.read2();
}catch (Exception e) {
System.out.println("예외처리:"+e.getMessage());
}
}
}
throws
이용해 메소드 호출한 곳으로 예외 떠넘김throws
는 메소드 선언부 끝에 작성. 떠넘길 예외 클래스를 ,
로 구분해 나열public class ThrowsEx
{
public static void findClass() throws ClassNotFoundException{
Class.forName("java.lang.String1"); //문제 발생시 예외처리 : java.lang.String1 예외가 없다면 메세지 안나옴
}
public static void main(String[] args)
{
try {
findClass();
}
catch(ClassNotFoundException e) { // 여기에 예외를 떠넘김
System.out.println("예외처리: "+e.getMessage());
}
}
}
package javastudy1.day0622.exception;
public class ThrowsEx
{
public static void findClass() throws Exception{
Class.forName("java.lang.String1");
}
public static void main(String[] args) throws Exception //jvm에서 처리
{
try {
findClass();
}
catch(Exception e) {
System.out.println("예외처리:"+e.getMessage());
}
}
}
public class InsufficientException extends Exception
{
public InsufficientException() {}
public InsufficientException(String message) {
super(message);
}
}
throw new~
throw new InsufficientException("잔고부족:"+(money-balance)+"금액 부족합니다.");
public class Account //은행계좌
{
private long balance;
public Account() {}
public long getBalance() {
return this.balance; //현재 잔고를 볼 수 있게
}
//입금 가능
public void deposit(int money) {
balance += money;
}
// 출금 기능 => 잔고보다 큰 금액은 출금할 수 없다.
public void withdraw(int money) throws InsufficientException {
if(balance < money) {
throw new InsufficientException("잔고부족:"+(money-balance)+"금액 부족합니다.");
}
balance -= money;
}
}
public class AccountEx
{
public static void main(String[] args)
{
Account account = new Account();
//예금하기 => 버튼으로 연결 가능
account.deposit(10000);
System.out.println("총 예금액 :"+account.getBalance());
//출금
try {
account.withdraw(5000); //바로 호출 불가 => exception으로 처리
System.out.println("현재 잔고 :"+account.getBalance());
account.withdraw(7000);
}
catch(InsufficientException e) {
System.out.println(e.getMessage());
}
}
}
Exception
의 자식 클래스로 선언, 실행 예외는 RuntimeException
의 자식 클래스로 선언노션에 어느정도 정리 후 블로그에 올리는 것도 생각보다 번거롭다ㅠ 그래도 노션보다는 벨로그가 인덱스같은거 정리도 해주고 좋은듯.. 다만 이게 한 단원이 다음날까지 이어지는 경우도 있어서 그 단원 끝나고 정리하고 올리느라 바로 당일날 올리기가 불가한 것 같다.
이건 공부 정리이자 잊지 않기 위한 용도이고 알고리즘을 위한 파이썬이랑 개인적으로 공부할 것 좀 따로 찾아봐야겠다.