final
final의 의미는 최종적이랑 뜻을 가지고 있다.
final 키워드는 클래스, 필드, 메소드 선언 시에 사용할 수 있다. 해당 선언이 최종상태이고, 수정 될 수 없다.
final 타입 필드 [=초기값];
final 변수: 값 변경하지 못한다.
int a = 10;
final int b = 10;
a++;
b++; //컴파일 오류
final 메서드
final 메서드는 오버라이딩 할 수 없다. 메서드를 선언할 떄 final 키워드를 붙이게 되면 이 메서드는 최종적인 메서드이므로 오버라이딩을 할 수 없는 메서드가 된다. 즉 부모 클래스를 상속해서 자식 클래스를 선언 할 때 부모 클래스에서 선언된 final 메서드는 자식 클래스에서 재정의 할 수 없다.
public class Car {
//필드
public int speed;
//메서드
public void speedUp() {speed += 1;}
//final 메서드
public final void stop(){
System.out.println("차를 멈춤");
speed = 0;
}
}
public class SportsCar extends Car {
@Override
public void speedUp() {speed +=10; }
@Override //오버라이딩을 할 수 없다.
public void stop() {
System.out.println("스포츠카를 멈춤");
speed = 0;
}
}
위의 코드를 보면 부모클래스에 stop 메서드는 final 로 선언이 되어있다. 그렇기 때문에 자식클래스에서 오버라이딩을 하지 못하는 것을 알 수 있다.
final 클래스
클래스를 선언할 때 final키워드를 class 앞에 붙이게 되면 이 클래스는 최종적인 클래스이므로 상속 할 수 없는 클래스가 된다. 즉 final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다는 것이다.
class A{}
final class B{}
class C extends A{}
class D extends B{} //컴파일 오류
class E extends String{} //컴파일 오류
final클래스의 대표적인 예는 자바 표준 API 에서 제공하는 String 클래스이다.
abstract 추상
abstract 는 메서드 앞, 클래스 앞에 붙힐 수 있다.
사전적 의미로 추상(abstract) 은 실체 간에 공통되는 특성을 추출한 것을 말한다. 예를 들어 새, 곤충, 물고기 등의 실체에서 공통되는 특성을 추출해보면 동물이라는 공통점이 있다. 이와 같이 동물이나 회사는 구체적인 실체라기보다는 실체들의 공통되는 특성을 가지고 있는 추상적인 것이라고 할수 있다.
abstract class B{
abstract void m();
void k{}
}
class BB1 extneds B{
void m(){}
}
class BB2 extends B{ //컴파일 오류
}
abstract 메서드 : 반드시 재정의해야한다.
abstract (추상) 클래스 : 실체 클래스의 공통되는 필드와 메서드를 추출해서 만들었기 때문에 객체를 직접 생성해서 사용할 수 없다.
- 객체 생성을 못한다. new 키워드로 객체생성을 하면 안된다. -> getInstance() 메서드 사용
추상메서드를 포함하고 있는 클래스는 반드시 abstract를 붙혀야 한다. 그렇지만 추상 클래스를 가지고 있다고 해서 추상 메서드를 가지는 것은 아니다.
getInstance() 메서드
public class CalendarTest {
public static void main(String[] args) {
Calendar now;
//now = new Calendar(); - new로 객체 생성이 불가능하기 때문에 getInstance()로 대신한다.
// now = Calendar.getInstance(); //일반화된 클래스 사용
now = new GregorianCalendar(); //구체화된 클래스 사용
System.out.println(now); //now.toString() 호출
int year = now.get(Calendar.YEAR); //지금 실행하고 있는 컴퓨터 날짜
int month = now.get(Calendar.MONTH); //첫번쨰 값이 0이다. 월 -1 값을 반환하게 된다.
int date = now.get(Calendar.DATE);
System.out.println("년도:"+ year);
System.out.println("월:"+ month);
System.out.println("일:"+ date);
}
}
now = Calendar.getInstance();
new로 객체 생성이 불가능하기 때문에 getInstance()로 대신한다. = 일반화된 사용법
now = new GregorianCalendar();
하위클래스의 객체를 생성하여 상위클래스로 upcasting 한다. = 구체화된 클래스를 사용하는 것
* 느슨한 결합도 유지법 * (제공자 코드가 바뀌어도 사용자 소스코드는 계속 사용가능하다.)
구체화된 클래스 사용보다 일반화(추상화)된 클래스나 인터페이스를 사용하라
둘다 결과값은 같으나 좀 더 확장성을 고려하고 느슨한 결합도를 유지하기 위해서
구체화된 클래스를 사용했을때를 보면 향후 라이브러리를 지원하지 않을 때 코드는 컴파일 에러가 발생한다.
상위 클래스를 사용하여 추상화된 클래스를 사용하는 것이 유지 보수에 효율적인 방법이다.
'java' 카테고리의 다른 글
java_ 3_조건문(if문, switch문) (0) | 2021.10.22 |
---|---|
java_11_인터페이스 (0) | 2021.10.21 |
java_9_ 타입 변환 & 강제 타입 변환(Casting) (0) | 2021.10.20 |
java_9_ 다형성과 Overriding (0) | 2021.10.20 |
java_8_상속(문제) (0) | 2021.10.19 |