1. 추상 클래스
(1) 추상클래스란?
: 추상 메소드를 0개 이상 포함하는 클래스 (추상 메소드가 없어도 추상 클래스로 만들 수 있다.)
- 추상 메소드: 메소드의 기능이 없고 헤더부만 존재하는 불완전한 메소드
- 추상 메소드가 있으면 반드시 추상 클래스로 만들어야 한다.
- 스스로 자신의 생성자를 활용한 인스턴스 생성 불가(불완전한 클래스)
-> 추상클래스는 상속을 활용해 하위 클래스 타입의 인스턴스를 이용해서 인스턴스 생성해야 한다.
// 추상 클래스 선언
public abstract class Product {
// 추상 클래스는 필드를 가질 수 있다.
private int nonStaticField;
private static int staticField;
// 추상 클래스는 생성자를 가질 수 있지만 직접적으로 인스턴스를 생성할 수는 없다.
public Product() {}
// 추상 클래스는 일반적인 메소드를 가질 수 있다.
public void nonStaticMethod() {
System.out.println("Product 클래스의 nonStaticMethod");
}
public static void staticMethod() {
System.out.println("Product 클래스의 staticMethod");
}
// 추상 메소드 작성
public abstract void abstMethod();
}
// 자식 클래스 선언
// 추상 클래스를 상속 받을 경우엔 추상 메소드를 반드시 오버라이딩 해야 한다. (오버라이딩 강제화)
public class SmartPhone extends Product {
@Override
public void abstMethod() {
System.out.println("Product 클래스의 abstMethod 오버라이딩 한 메소드 호출");
}
/* 추가적 메소드 작성 */
public void printSmartPhone() {
System.out.println("SmartPhone 클래스의 printSmartPhone 메소드 호출");
}
}
public class Application {
public static void main(String[] args) {
/* 추상 클래스는 인스턴스 생성 불가 */
// Product product = new Product();
SmartPhone smartPhone = new SmartPhone();
System.out.println(smartPhone instanceof SmartPhone);
System.out.println(smartPhone instanceof Product);
/* 다형성을 적용해서 추상 클래스를 레퍼런스 타입으로 사용할 수 있다. */
Product product = new SmartPhone();
product.abstMethod();
product.nonStaticMethod();
Product.staticMethod();
}
}
(2) 추상 클래스를 사용하는 이유
- 추상클래스는 스스로 인스턴스를 만들지는 못하지만 다형성 적용을 위한 부모 타입 역할을 해낼 수 있다.
- 추상 메소드를 통해 자식 클래스에 오버라이딩에 대한 강제성 부여 가능
(추상 클래스를 상속받는 자식 클래스는 반드시 추상 메소드를 오버라이딩 해야하기 때문)
-> 필수 기능을 정의해 일관된 인터페이스(동일 기능) 제공에 있어 도움이 된다.
2. 인터페이스
(1) 인터페이스란?
: 추상 메소드와 상수 필드만 가질 수 있는 클래스의 변형체
- 상수 필드, 추상메소드만 작성 가능하다. (따라서 모든 필드는 묵시적으로 public static final )
- 생성자를 가질 수 없다.
- 구현부가 있는 non-static 메소드를 가질 수 없다.
- default 키워드를 사용하면 non-static 메소드 작성 가능. default 메소드는 완성되어 있으므로 오버라이딩이 강제화되지 않는다.
- 인터페이스는 인터페이스를 상속할 수 있다. (이 때는 extends 사용)
ㄴ 클래스 extends 클래스 (단일 상속)
클래스 implements 인터페이스1, 인터페이스2 (다중 상속)
인터페이스 extends 인터페이스1, 인터페이스2 (다중 상속)
public interface InterProduct extends java.io.Serializable {
// 인터페이스는 상수 필드만 작성 가능
public static final int MAX_NUM = 100;
int MIN_NUM = 0;
// 인터페이스는 생성자를 가질 수 없다.
// public InterProduct(){}
// 인터페이스는 구현부가 있는 non-static 메소드를 가질 수 없다.
// public void nonStaticMethod(){}
// 추상 메소드만 작성이 가능하다.
public abstract void nonStaticMethod();
void abstMethod();
// static 메소드 작성 가능하다. (JDK 1.8 추가) */
public static void staticMethod(){
System.out.println("InterProduct 인터페이스의 staticMethod 호출");
}
// default 키워드를 사용하면 non-static 메소드도 작성 가능하다. (JDK 1.8 추가)
// default 메소드는 완성 되어 있으므로 오버라이딩이 강제화 되지 않는다.
// 일반적으로는 {} 만 작성하고 내용을 비워놓는다.
public default void defaultMethod() {
System.out.println("InterProduct 인터페이스의 defaultMethod 호출");
}
}
public class Product extends Object implements InterProduct, java.io.Serializable {
// InterProduct의 추상 메소드는 반드시 구현해야 한다. (오버라이딩 강제화) */
@Override
public void nonStaticMethod() {
System.out.println("InterProduct의 nonStaticMethod 오버라이딩한 메소드 호출");
}
@Override
public void abstMethod() {
System.out.println("InterProduct의 abstMethod 오버라이딩한 메소드 호출");
}
// static 메소드는 오버라이딩 할 수 없다.
// default 메소드는 오버라이딩이 강제화 되지 않는다.(선택적 오버라이딩)
// default 키워드는 인터페이스 내에서 사용하는 키워드이고, 오버라이딩 시에는 제거한다.
@Override
public /* default */ void defaultMethod() {
System.out.println("InterProduct의 defaultMethod 오버라이딩한 메소드 호출");
}
}
public class Application {
public static void main(String[] args) {
// InterProduct interProduct = new InterProduct();
// 다형성을 이용하여 레퍼런스 타입으로 사용
InterProduct interProduct = new Product();
// 오버라이딩 된 메소드 호출
interProduct.abstMethod();
interProduct.nonStaticMethod();
interProduct.defaultMethod(); // default이지만 오버라이딩 했음
// static 메소드 호출
InterProduct.staticMethod();
// 상수 필드
System.out.println(InterProduct.MAX_NUM);
System.out.println(InterProduct.MIN_NUM);
}
}
(2) 인터페이스를 사용하는 이유
- 인터페이스는 일종의 추상 클래스라고 할 수 있는데,
추상클래스처럼 추상메서드를 갖지만, 추상 클래스보다 추상화 정도가 높아서 추상 메서드와 상수만을 멤버로 가질 수 있다.
추상 클래스를 미완성 설계도라고 하면 인터페이스는 밑그림만 그려져 있는 기본 설계도라고 할 수 있다.
전체적인 틀을 짜준 후 실제 구현 클래스에서 메서드 내용 부분을 채워넣어 구현을 해주는 것이다.
- 모든 클래스는 하나의 부모 클래스 외에도 여러 개의 인터페이스 구현 가능
3. 추상클래스와 인터페이스
구분 | 추상 클래스 | 인터페이스 |
상속 가능 범위 | 단일 상속 | 다중 상속 |
키워드 | extends | implements |
자체 인스턴스 생성 | 생성 불가 | 생성 불가 |
다형성 적용 시 상위 타입 활용 가능 유무 |
가능 | 가능 |
'Java' 카테고리의 다른 글
[Java] 배열의 값을 출력하기(반복문, Arrays.toString()) (0) | 2024.08.11 |
---|---|
Java(9) 자주 쓰는 API - Object 클래스, String 클래스, 이스케이프 문자 (0) | 2024.08.08 |
Java(7) 다형성 (0) | 2024.08.08 |
Java(6) 상속 (0) | 2024.08.07 |
Java(5) final (0) | 2024.08.07 |