추상 메소드
-설계만 되어있고, 구현체가 없는 것이다.
-abstract 리턴타입 메소드이름(); 와 같은 형태이지만 중괄호 안에 있는 내용은 자식클래스에서 구현해야하는 것을 말한다.
-반드시 자식 클래스에서 오버라이딩해야 사용할 수 있는 메소드를 의미한다.
-자바에서 추상메소드를 선언하여 사용하는 목적은 추상 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함이다.
-이런 추상메소드는 선언부만 존재하고, 구현부는 작성되어 있지 않고, 자식클래스에서 오버라이딩한다.
그럼 추상 메소드를 왜 써 ?
추상메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시 추상 메소드를 구현하도록 하기 위함이다. 일반 메소드로 구현하면 사용자에 따라서 구현할수도, 안할 수 도 있기때문이다.
abstract class Animal { abstract void cry(); }
class Cat extends Animal { void cry() { System.out.println("냐옹냐옹!"); } }
class Dog extends Animal { void cry() { System.out.println("멍멍!"); } }
public class Polymorphism02 {
public static void main(String[] args) {
// Animal a = new Animal(); // 추상 클래스는 인스턴스를 생성할 수 없음.
Cat c = new Cat();
Dog d = new Dog();
c.cry();
d.cry();
}
}
인터페이스
자식 클래스가 여러 부모 클래스를 상속 받을 수 있다면, 다양한 동작을 수행할수있다. 그렇지만 클래스를 이용하여 다중상속을 받는 경우에 메소드 출처의 모호성과 여러가지 문제가 발생할 수있어서 자바는 다중상속을 지원하지 않는다. 그렇지만 이런 이점을 버릴수 없기에 인터페이스를 통해서 다중상속을 지원하고 있다.
인터페이스란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하고, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미한다.
인터페이스는 오로지 추상 메소드와 상수만 포함 할 수 있다.
-인터페이스
1. 구현하려는 객체의 동작의 명세
2. 다중 상속 가능
3. implements를 이용하여 구현
4. 메소드 시그니처(이름, 파라미터, 리턴 타입)에 대한 선언만 가능
-추상클래스
1. 클래스를 상속받아 이용 및 확장을 위함
2. 다중 상속 불가능 , 단일 상속
3. extends를 이용하여 구현
4. 추상메소드에 대한 구현 가능
코드를 완벽하게 짯다고해서 항상 프로그램이 성공적으로 도는 것은 아니다! 다양한 예외 상황이 발생할수있는데, 이것을 대응하기 위해서 예외 처리 코드가 필요하다!
-에러(error)
에러 혹은 오류는 시스템 레벨에서 프로그램에 심각한 문제를 야기하여 실행중인 프로그램을 종료시킨다. 이러한 오류는 개발자가 미리 예측하여 처리할 수 없는 것이 대부분이므로, 오류에 대한 처리를 할 수 없다.
-예외(exception)
예외는 오류와 마찬가지로 실행 중인 프로그램을 비정상적으로 종료시키지만, 발생 할 수 있는 상황을 미리 예측하여 처리 할 수 있다.
-예외 처리(exception handling)
try {
예외를 처리하길 원하는 실행 코드;
} catch (e1) {
e1 예외가 발생할 경우에 실행될 코드;
} catch (e2) {
e2 예외가 발생할 경우에 실행될 코드;
}
...
finally {
예외 발생 여부와 상관없이 무조건 실행될 코드;
}
class ArrayCalculation {
int[] arr = {0, 1, 2, 3, 4};
public int divide(int denominatorIndex, int numeratorIndex) throws ArithmeticException, ArrayIndexOutOfBoundsException { //이런 에러가 발생할수있어! 라고 말해주는 것
return arr[denominatorIndex] / arr[numeratorIndex];
}
}
public class Main {
public static void main(String[] args) {
ArrayCalculation arrayCalculation = new ArrayCalculation();
System.out.println("2 / 1 = " + arrayCalculation.divide(2, 1));
try {
System.out.println("1 / 0 = " + arrayCalculation.divide(1, 0)); // java.lang.ArithmeticException: "/ by zero"
} catch (ArithmeticException arithmeticException) {
System.out.println("잘못된 계산입니다." + arithmeticException.getMessage());
}
try {
System.out.println("Try to divide using out of index element = "
+ arrayCalculation.divide(5, 0)); // java.lang.ArrayIndexOutOfBoundsException: 5
} catch (ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException) {
System.out.println("잘못된 인덱스입니다 " + arrayIndexOutOfBoundsException.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
System.out.println("now()를 활용하여 생성");
LocalDate date = LocalDate.now();
LocalTime time = LocalTime.now();
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(date);
System.out.println(time);
System.out.println(dateTime);
System.out.println("of()를 활용하여 생성");
LocalDate newDate = LocalDate.of(2021, 03, 29);
LocalTime newTime = LocalTime.of(22, 50, 55);
System.out.println(newDate);
System.out.println(newTime);
}
}
LocalDate, LocalTime, LocalDateTime는 java.time패키지의 기본이 되는 클래스이다. 이것을 출력하니 쉽게 현재 날짜와 시간을 출력할수있었다.
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT);
String shortFormat = formatter.format(LocalTime.now());
System.out.println(shortFormat);
이전의 포맷과는 조금 다르게 오전/오후가 추가되었고 직관적인 형태도 만들어줄수있다.
FormatStyle에서 FULL ,LONG, MEDIUM, SHORT 등등을 통해서 다양하게 표현이 가능하다.
지정해준 사이 기간을 알수있는 코드다.
public class Main {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
LocalDate birthday = LocalDate.of(2020, 1, 1);
Period period = Period.between(today, birthday);
System.out.println(period.getMonths());
System.out.println(period.getDays());
}
}
오늘과 생일로 설정한 날짜 사이에서 몇달이 지났고 몇일이 지났는지를 출력가능하다.