상세 컨텐츠

본문 제목

추상 클래스 인터페이스 (Java 8 디폴트 메서드, 정적 메서드)

기록 - 프로그래밍/Java

by wjjun 2024. 1. 18. 00:28

본문

 

 

추상 클래스 사용 목적

[1] 실체 클래스들의 공통된 필드, 메서드 이름을 통일

객체의 사용 방법에 따라 실체 클래스마다 다른 메서드와 필드 이름을 가질 수 있습니다.

이때, 추상 클래스를 상속하여 필드와 메서드 이름을 통일 시킬 수 있다.

 

[2] 실체 클래스 작성시간 절약

추상클래스에 공통 필드와 메서드를 선언하고 실체 클래스에는 필요한 부분만 다르게 메서드를 작성하여 사용할 수 있다.

개발자가 작성해야할 클래스가 많다면 필드와 메서드 이름을 각각 다르게 작성할 수 있다. 이 경우, 동일 필드와 메서드를 작성하도록 추상클래스로 설계 규칙을 만드는 것이 좋습니다.

그리고 추상 클래스를 상속한 구체 클래스를 만들도록 하면 됩니다.

 

 

선언

추상 클래스는 new 연산자로 직접 생성자 호출을 할 수는 없지만 자식 객체가 생성되면 super(...)를 호출해서 추상 클래스 객체를 생성합니다. 그래서 추상클래스도 생성자가 반드시 있어야 합니다.

public abstract class Phone {
    // 공통 필드
    public String owner;
    
    public Phone(String owner) {
        this.owner = owner;
    }
    
    ...
    // 공통 메서드
}

public class SmartPhone extends Phone {
    public SmartPhone(String owner) {
        super(owner)
    }
}

 

 

추상 메서드와 오버라이딩

실체 클래스의 필드와 메서드 멤버를 통일하는 목적이 있습니다. 메서드 선언만 통일하고 실제 구현은 클래스마다 달라야 하는 경우가 있습니다.

 

그리고 만약 구체 클래스에서 실제 구현을 빼먹지 않도록 구현을 강제하도록 할 수 있습니다.

추상 메서드를 선언하면 됩니다.

 

추상 메서드는 추상클래스에만 설정할 수 있습니다.

메서드의 선언부만 있고, 메서드 실행 내용이 들어가는 중괄호 { } 는 없는 메서드 입니다.

 

추상 클래스를 설계할 때, 하위 클래스가 반드시 실행 내용을 채우도록 강요하고 싶은 메서드가 있다면 추상 클래스에서 추상 메서드로 선언하면 됩니다. 

접근제어자 abstract 리턴타입 메서드명 (매개변수, ...);

public abstract class Animal {
    public abstract void sound();
}

 

중괄호가 없습니다. Animal을 상속받는 구체 클래스에서는 sound() 메서드를 강제로 재정의 해야만 합니다

 

 

public class A동물 extends Animal {
    @Override
    public void sound() {
        sout("A동물의 소리");
    }
}

구체 클래스에서의 추상메서드 재정의

 

 

 

인터페이스  선언

인터페이스는 상수와 메서드만 구성 멤버로 갖습니다.

인터페이스는 객체를 생성할 수 없어 생성자가 없으며 자바 8부터는 디폴트 메서드와 정적 메서드 선언이 가능해졌습니다.

default 타입 메서드명 (매개변수, ...) {...}
static 타입 메서드명 (매개변수, ...) {...}

 

디폴트 메서드

객체(구현 객체)가 갖고 있는 인스턴스 메서드라고 생각하면 됩니다.

자바 8에서 디폴트 메서드를 허용한 이유는 기존 인터페이스를 확장하여 새 기능을 추가할 수 있도록 하기 위함입니다.

 

기존에는 인터페이스에 추상 메서드만 정의할 수 있었습니다. 이제 디폴트 메서드를 사용하면 이미 존재하는 인터페이스에 새로운 메서드를 추가해도 기존 구현 객체에는 영향이 없이 메서드를 추가할 수 있습니다.

디폴트 메서드는 해당 인터페이스를 구현하는 클래스에서 재정의(오버라이드)하여 사용할 수도 있습니다.

interface Sample {
    default void sampleMethod {
        if (sample) {
            sout("샘플입니다");
        else {
            sout("샘플이 아닙니다");
        }
    }
}

 

 

정적 메서드

자바 8부터 작성할 수 있는 정적 메서드는 디폴트 메서드와 다르게 객체가 없어도 인터페이스만으로 호출이 가능합니다.

이것은 인터페이스를 구현한 클래스의 인스턴스(객체)가 없어도 직접 호출을 할 수 있는 메서드입니다.

interfact Sample() {
    static void staticMethod();
}

public class Main {
    public static void main(String[] args) {
        Sample.staticMethod();
    }
}

인터페이스의 정적 메서드를 호출하는 코드입니다. 클래스 인스턴스를 생성하지 않고 인터페이스 수준에서 정적 메서드 호출이 가능합니다.

 

 

인터페이스 상수 필드

인터페이스는 데이터를 저장할 수 없기에 데이터 저장 인스턴스나 정적 필드 선언이 불가합니다.

단, 상수 필드만 선언 가능합니다.

public interfacce Sample {
    public int MAX_VALUE = 10;
    public int MIN_VALUE = 0;
}

 

인터페이스 추상 메서드 선언

인터페이스를 통해 호출된 메서드는 객체에서 실행됩니다. 그래서 인터페이스의 메서드는 실행 블록이 필요 없는 추상메서드를 선언합니다.

추상 메서드는 중괄호 {} 가 필요하지 않으며 리턴타입, 메서드명, 매개변수만 기술합니다.

 

public abstract로 붙이지 않아도 컴파일 시점에서 자동으로 public abstract를 붙이게 됩니다.

인터페이스의 모든 메서드는 기본적은 public 접근 제한을 갖기 때문에 public 보다 낮은 접근 제한으로 작성할 수 없습니다.

 

인터페이스 선언된 추상 메서드에 대응하는 실체 메서드를 구현 클래스가 작성하지 않으면, 구현 클래스는 자동적으로 추상 클래스가 됩니다. 그렇기 때문에 클래스 선언부에는 abstract 키워드를 추가해줘야 합니다.

public abstract class Television implements RemoteControl {
    public void turnOn() {...}
    public void turnOff() {...}
}

 

 

인터페이스 자동타입 변환

구현한 여러 클래스의 객체를 해당 인터페이스 데이터 타입으로 변환하는 것을 의미합니다.

서로 다른 클래스들을 특정 인터페이스 형태로 처리할 수 있어, 재사용과 유연성을 높일 수 있습니다.

 

interface Shape {
    void draw();
}

class Circle implements Shape {
    @Override
    public void draw() {
        System.out.println("원 그리기");
    }
}

class Rectangle implements Shape {
    @Override
    public void draw() {
        System.out.println("사각형 그리기");
    }
}

public class Main {
    public static void main(String[] args) {
        Shape circle = new Circle(); // Circle 객체를 Shape 인터페이스로 다룸
        Shape rectangle = new Rectangle(); // Rectangle 객체를 Shape 인터페이스로 다룸
        
        circle.draw(); // "원 그리기" 출력
        rectangle.draw(); // "사각형 그리기" 출력
    }
}

Shape 인터페이스 데이터 타입으로 선언은 되었지만, 실제는 Circle과 Rectangle 객체를 가리키고 있습니다.

다형성의 한 형태를 보여주고 있습니다.

 

 

인터페이스 상속

인터페이스도 다른 인터페이스 상속이 가능합니다. 인터페이스는 클래스와 다르게 다중 상속이 가능합니다.

public interface 하위 클래스 extends 상위 인터페이스1, 상위 인터페이스 2 {...}

 

하위 인터페이스를 구현하는 클래스를 하위 인터페이스 뿐만 아니라 상위 인터페이스의 모든 추상 메서드에 대한 실체를 갖고 있어야 합니다.

 

하위 인터페이스로 타입 변환이 되면 상,하위 인터페이에 선언된 모든 메서드 사용이 가능합니다.

상위 인터페이스로 타입 변환이 되면 상위 인터페이스에 선언된 메서드만 사용 가능하며, 하위 인터페이스에 선언되 메서드는 상용할 수 없습니다.

관련글 더보기

댓글 영역