1. 추상클래스
1.1 추상클래스의 필요성
- 비슷한 기능을 하는 두개의 클래스를 공통의 메서드로 관리하기 위한 클래스이다.
- 두개의 정렬 메서드를 확인 해보자
- 2개의 메서드는 기능은 같지만, sorter.run()과 sorter.start()의 메서드명과 매개변수가 다르다.
- 같은 기능을 하지만 경우에 따라 2개를 각각 호출해야한다.
static void display(BubbleSort sorter, int[] values) {
sorter.run(values);
}
static void display(QuickSort sorter, int[] values) {
sorter.start(values, 0, values.length - 1);
}
1.2 추상클래스의 개념
- 그렇기 때문에 추상클래스를 통해 공통의 분모를 수행하는 추상클래스를 생성한다.
- 추상클래스를 직접적으로 사용하지는 않지만, 같은 메소드와 같은 매개변수로 넘겨 줄수 있다.
public abstract class Sorter {
public void sort(int[] values) {};
}
public class QuickSort extends Sorter {
@Override
public void sort(int[] values) {
start(values, 0, values.length - 1);
}
//후략//
}
public class BubbleSort extends Sorter {
@Override
public void sort(int[] values) {
int size = values.length;
for (int i = 0; i < size - 1; i++) {
for (int j = 0; j < size - i - 1; j++) {
if (values[j] > values[j + 1]) {
//System.out.printf("%d <==> %d\n", values[j], values[j + 1]);
int temp = values[j];
values[j] = values[j + 1];
values[j + 1] = temp;
}
}
}
}
}
- 여기에 다형성 개념을 대입하면 부모클래스의 변수명으로 자식클래스 타입을 할당할 수 있다.
- 또한 사용자는 Soter sort = new Soter(); 처럼 직접적인 사용을 할 수 없다.
Sorter sort = new BubbleSort();
display(sort, values); // OK!
Sorter sort2 = new QuickSort();
display(sor2, values); // OK!
1.3 추상클래스의 한계
- 추상클래스를 선언하였지만, 자식클래스에서 추상클래스의 메서드를 사용 안할 수도 있다.
- 하지만 추상클래스의 메소드를 사용 안하는 경우도 있다.
public class MergeSort extends Sorter {
void merge(int arr[], int l, int m, int r)
{ // 생략//
}
}
1.4 추상메서드의 활용
- 추상클래스를 사용 안하면, 상속을 받는 의미가 없다.
- 따라서 추상클래스의 메소드를 강제적을 사용하게 하는 방법이 필요하다.
- 추상클래스의 메소드를 강제적으로 사용하게 하는 것이 바로 추상메서드 이다.
public abstract class Sorter {
// 메서드를 추상 메서드로 선언하는 순간
// => 모든 서브 클래스는 반드시 이 메서드를 구현해야 한다.
// => 구현하지 않으면 추상 클래스가 될 수 밖에 없다.
// => 서브 클래스에게 구현을 강제하는 효과가 있다.
public abstract void sort(int[] values);
}
1.5 인터페이스의 등장
- 이처럼 추상클래스를 가지고 메소드사용을 강제하는데 제약이 있어, 인터페이스를 사용하게 된다.
- 추상메서드만 있을 경우, 객체 사용규칙을 정의하는 인터페이스로 전환 가능하다.
- 추상클래스 안에 일반 메서드가 있다면, 인터페이스로 전환이 불가능하다.
public interface Sorter {
// 인터페이스는 호출 규칙을 정의하는 것이기 때문에
// 모든 메서드는 기본이 public 이고, abstract 이다.
// => 다음과 같이 메서드 선언에 public 과 abstract를 생략해도 된다.
void sort(int[] values);
}
2. 캡슐화
1.1 캡슐화의 필요성
- 클래스의 필드 값에 직접적인 접근을 하면 해당 필드값을 참조하는 결과값도 영향을 받는다
- 필드에 직접적인 접근 보다 set과 get 메서드들을 통해 접근하면,
- 변경에 따른 추가적인 필드 변경 메서드를 추가할 수 있다.
1.2 접근제어자
- private : 클래스에 소속된 같은 멤버만 접근 가능
- (default) : 같은 패키지에 소속된 멤버만 접근 가능
- protected : 같은 패키지에 소속되거나 자손 클래스의 멤버만 접근 가능
- public : 모두 접근 가능
*자식 클래스에서 상속 받아 만든 변수가 아니면 부모클래스로 생성해도 protected 접근불가
1.3 싱글톤 패턴
- 클래스의 생성자의 접근을 제한하며 static 메서드를 통해 하나의 인스턴스만 생성
public class Car{
//생성자를 접근제한
private Car();
//하나의 값(전역변수)만을 가지는 인스턴스 선언
private static Car instance;
//인스턴스의 고유성 여부를 확인
public static Car getInstance(){
if(instance == null){
//private은 같은 class내에서 접근 가능
instance = new Car();
}
//고유한 인스턴스 생성
return instance;
}
}
'개발자 꿈나무의 하루 > 01_Boot Camp' 카테고리의 다른 글
(네이버클라우드 부트캠프) 30일차 - 토이프로젝트(ToDoList만들기) (0) | 2024.07.05 |
---|---|
(네이버클라우드 부트캠프) 29일차 - Java프로그래밍 기초(인터페이스) (1) | 2024.07.05 |
(네이버클라우드 부트캠프) 26일차 - Java프로그래밍 기초(상속) (0) | 2024.07.01 |
(네이버클라우드 부트캠프) 24_25일차 - 미니프로젝트 가계부만들기 (0) | 2024.07.01 |
(네이버클라우드 부트캠프) 23일차 - 실습프로젝트(인터페이스) (0) | 2024.06.26 |