추상화
추상화란?
추상화는 클래스들의공통적인 요소를 뽑아서 상위 클래스를 만들어내는 것입니다.
반드시 상위 클래스일 필요는 없어서, 공통적인 속성과 기능을 정의한 하위 클래스를 생성할 수도 있습니다.
추상화는 공통적인 속성과 기능을 정의함으로써 코드의 중복을 줄이고, 클래스 간 관계를 효과적으로 설정하고, 유지/보수를 용이하게 하는 것입니다.
자바에서는 추상 클래스와 인터페이스 라는 문법 요소를 통해 추상화를 구현합니다.
abstract
abstract는 주로 클래스와 메서드에 붙이는 키워드인데, 이것을 붙이면 자동으로 ‘추상 클래스’와 ‘추상 메서드’가 됩니다.
abstract는 ‘추상적인’이라는 사전적인 의미가 있지만, 핵심은 ‘미완성’이라는 개념에 있습니다.
1
2
3
abstract class 클래스명 { ... }
와 같이 클래스 선언부가 작성되어 있으면
이것은 미완성된 추상 클래스이므로 상속을 통해 내부의 추상 메서드를 구현해줘야한다는 점을 알 수 있습니다.
추상 클래스 (abstract class)
추상 클래스는 한 마디로 미완성 설계도입니다.
미완성이기 때문에 이를 기반으로 인스턴스를 생성할 수 없습니다.
오직 상속을 통해 하위 클래스에서만 완성될 수 있습니다.
클래스 역할을 못하는 추상 클래스가 필요한 이유는 이것이 새로운 클래스를 작성하는데 유용한 바탕이 되어주기 때문입니다.
무에서부터 클래스를 만드는 것보다는, 추상 클래스라는 최소한의 틀에서 확장시키는 것이 편리하기도 하고 설계에 있어 유연함을 가져다줍니다
추상 메서드 (abstract method)
추상 메서드는 구현부가 없이 선언부만 있는 메서드입니다.
추상 클래스와 마찬가지로 설계만 하고 구체적인 내용을 작성하지 않아 미완성 메서드입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 추상 클래스 정의
abstract class Shape {
// 추상 메서드 정의
public abstract double area();
public abstract double perimeter();
}
// 추상 클래스를 상속받은 구체적인 클래스 정의
class Rectangle extends Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
// 추상 메서드의 구현
@Override
public double area() {
return width * height;
}
@Override
public double perimeter() {
return 2 * (width + height);
}
}
public class Main {
public static void main(String[] args) {
// 추상 클래스를 상속받은 구체적인 클래스의 인스턴스화
Rectangle rect = new Rectangle(5, 4);
System.out.println("사각형의 면적: " + rect.area());
System.out.println("사각형의 둘레: " + rect.perimeter());
}
}
1
2
3
4
5
6
7
8
// 추상 클래스 정의
abstract class Shape {
// 추상 메서드 정의
public abstract double area();
public abstract double perimeter();
}
추상 메서드는 구현부가 없으므로 {} 대신 끝을 표시해주는 의미로 ;를 적어줍니다..
1
2
3
4
5
6
7
8
9
10
11
12
13
// 추상 메서드의 구현
@Override
public double area() {
return width * height;
}
@Override
public double perimeter() {
return 2 * (width + height);
}
부모 클래스의 추상 메서드를 자식 클래스에서 구현하는 것이 메서드 오버라이딩이라고 합니다.
인터페이스 (Interface)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 인터페이스 정의
interface Shape {
// 구현되지 않은 추상 메서드 선언
double area();
double perimeter();
// 상수 선언
public static final double PI = 3.141592653589793;
}
// 인터페이스를 구현하는 클래스
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
// 추상 메서드 구현
@Override
public double area() {
return PI * radius * radius;
}
@Override
public double perimeter() {
return 2 * PI * radius;
}
}
// 메인 클래스
public class Main {
public static void main(String[] args) {
// Circle 객체 생성
Circle circle = new Circle(5);
System.out.println("원의 면적: " + circle.area());
System.out.println("원의 둘레: " + circle.perimeter());
}
}
인터페이스는 일종의 추상 클래스입니다.
추상 클래스와 다른 점이 있다면 더 높은 추상화 정도를 가지고 있어서 바디가 있는 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없습니다.
인터페이스는 interface 키워드를 사용합니다.
구현부가 완성되지 않은 추상 메서드와 상수로만 이루어져있습니다.
상수로 정의하는 경우네는 public static final로, 메서드로 정의할 때는 public abstract로 정의합니다.
final
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// final 필드와 final 변수의 예시
class Example {
final int finalField = 10; // final 필드
void method() {
final int finalVariable = 20; // final 지역 변수
// finalVariable = 30; // 값 변경 시도 시 컴파일 오류 발생
System.out.println("finalVariable: " + finalVariable);
}
}
// final 클래스의 예시
final class FinalClass {
// 클래스 내용
}
// final 메서드의 예시
class Parent {
final void finalMethod() {
// 메서드 내용
}
}
class Child extends Parent {
// @Override // 컴파일 오류 발생: final 메서드는 오버라이딩할 수 없음
// void finalMethod() {
// // 메서드 내용
// }
}
// final 변수의 예시
public class Main {
public static void main(String[] args) {
final int finalVariable = 100;
// finalVariable = 200; // 값 변경 시도 시 컴파일 오류 발생
System.out.println("finalVariable: " + finalVariable);
}
}
‘최종’이라는 뜻을 가진 final 키워드는 필드, 지역 변수, 클래스 앞에 위치할 수 있습니다.
클래스 앞에 있을 때는 변경∙확장∙상속이 안됩니다.
메서드 앞에 있을 때는 오버라이딩이 안됩니다.
변수 앞에 있을 때는 값 변경이 안됩니다.