[추상]
- 어느 정도의 틀은 잡아놓고 다형성을 이용하여 추상클래스의 자식들은 메서드를 오버라이딩하여 클래스를 완성시킨다.
정해진 틀은 있지만 각 클래스마다 별도로 작성되기 때문에 다들 개성이 살아있다.
package ch09.abstract11;
public abstract class Employee {
protected String empno; // 사번
protected String name; // 이름
public Employee(String empno, String name) {
this.empno = empno;
this.name = name;
}
public void showEmployeeInfo() {
System.out.println("-------------------");
System.out.println("empno : " + empno);
System.out.println("name : " + name);
}
public abstract double getMonthPay(); // 추상 메서드
// public abstract String getViewInfo();
}
위의 코드처럼 abstract로 어느 정도의 틀만 갖춰진 미완성 클래스를 만들어준다.
package ch09.abstract11;
// 일용직 사원
public class PartTimeEmployee extends Employee{
protected int dailyPay; // 일당
protected int workDay; // 일한 일수
public PartTimeEmployee(String empno, String name,
int dailyPay, int workDay) {
super(empno, name);
this.dailyPay = dailyPay;
this.workDay = workDay;
}
@Override
public double getMonthPay() {
double mPay = dailyPay * workDay;
return mPay;
}
@Override
public void showEmployeeInfo() {
super.showEmployeeInfo();
System.out.println("dailyPay : " + dailyPay);
System.out.println("workDay : " + workDay);
System.out.printf("monthPay : %.2f\n", getMonthPay());
}
}
처럼 추상 클래스를 상속받고 미완성된 메서드를 오버라이딩해서 사용한다.
추상자식은 반드시 조상 클래스에서 미구현된 메소드를 구현해야한다.
[abstract 조건 및 용도]
- 추상 클래스는 미완성된 메소드가 있을때 사용
- 클래스의 설계의 목적으로 사용한다. 객체를 못만든다. 미구현 메소드빼고는 나머지는 구현되어있다.
- 다형성은 부모클래스에 자식객체를 담을 수 있다.
- 부모클래스의 참조변수로 메서드를 호출하면 각 객체의 메소드가 호출된다.(이때 각 객체 -> 자식의 교유개성은 발현(유지)된다.)
- interface 도 마찬가지로 설계에서 껍데기만 만들어주고 세부 값, 메소드나 변수들 선언이 안되있다.
[인터페이스]
인터페이스란 추상 클래스와 상당히 유사하다. 추상 클래스와 동일하게 추상 메서드를 가지지만
오직 추상 메서드와 상수만을 멤버로 가질 수 있다. 추상 클래스가 미완성된 설계도라 하면, 인터페이스는 미완성 설계도도 아니라 구현된 메서드나 변수들이 존재하지도 않는 기본 설계도라고 생각하면 된다.
해당 인터페이스를 사용하는 주된 이유는 직접 코드에 영향을 주는 것이 아닌 다른 클래스를 작성하는데 도움주기 위해 사용한다.
package ch09.interface12;
/* 인터페이스 == 추상클래스
* 모든 메서드가 추상 메서드
*
* 1) 상속을 전제로 한다.
* 2) 부모의 인터페이스 변수에 자식 객체를 저장할 수 있다.
* 3) 다형성의 의미(묶어서 관리하고 쉽고, 각 변수는 저장된 객체에 따라 각각 개성있게 동작)
* 4) 클래스와 클래스를 연결
* 5) 유연한 설계
* 6) 디자인 패턴에 자주 사용
* 7) 리터럴 상수를 의미있는 문자열 상수로 만들어준다.
* */
public interface StarUnit {
public void walk(); // 컴파일할때 자동으로 abstract가 생략된다.
public void attack();
public void die();
}
---------------------------------------------
package ch09.interface12;
public class Marine implements StarUnit { // 구현한다(사실상 상속)
@Override
public void walk() {
System.out.println("아장아장");
}
@Override
public void attack() {
System.out.println("두두두두");
}
@Override
public void die() {
System.out.println("으아아악");
}
}
처럼 추상 클래스 보다 더 구현돼있는 것이 없다.
하지만 인터페이스를 사용하는 이유는
1. 개발시간이 단축된다.
2. 기본 틀만 작성돼있기 때문에 일관되고 정형화된 프로그램 개발이 가능해진다.
3. 다중 상속이 가능하다.
- 인터페이스는 정해진 틀도 없고 껍데기만 존재하기 때문에 클래스 상속 시 발생했던 문제점들이 없다.
4. 서로 관계없는 클래스끼리 관계를 맺어줄 수 있다.
- 관계없는 클래스끼리 인터페이스를 공통적으로 구현하도록 함으로써 관계를 맺어줄 수 있다.
인터페이스에는 default 메서드와 static 메서드를 선언할 수 있다.
default 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로 새로 디폴트 메서드가 추가되어도 인터페이스를 구현한 클래스를
변경하지 않아도 된다.
만약 새로 추가된 디폴트 메서드가 기존의 메서드와 이름이 중복되어 충돌이 일어나는 경우가 있는데
이때 쉽게 생각해서 필요한 쪽의 메서드와 같은 내용으로 오버라이딩을 해버리면 된다.
[추상과 인터페이스의 차이점]
추상 클래스 = 70~80%가 완성된 설계도
인터페이스 = 20~30%만 완성돼있는 정말 기본적인 틀만 잡힌 설계도
인터페이스에서 구현시켜 놓은 것도 얼마 없으니까 상속의 조건에도 미달
→ 그래서 여러 개의 클래스를 상속받아도 문제 X
→ 다중 상속 허용
추상 클래스는 틀이 거의 잡혀있기 때문에 상속을 시켜줄 것도 많음
→ 여러 개의 상속을 받으면 에러 발생 확률이 높아짐
→ 그래서 단일 상속만 허용
이러한 기능들 때문에 인터페이스는 기본적인 설계도에서 상속받은 하위 클래스가 미완성된 설계도를 완성시키려고 하는 게 존재의 목적이라면, 추상 클래스는 거의 완성된 틀에 미완성된 부분만 오버라이딩시켜서 확장하는 것이 존재의 목적이다.
'스터디 > JAVA' 카테고리의 다른 글
[JAVA] 컬렉션 (1) | 2024.02.18 |
---|---|
[JAVA] Thread (0) | 2024.02.15 |
[JAVA] 상속 (0) | 2024.02.12 |
[JAVA] 배열 (1) | 2024.02.07 |
[JAVA] 클래스 (1) | 2024.02.03 |