Developer/JAVA

JAVA , 인터페이스 , 인터페이스와 추상클래스의 차이

단님 2024. 10. 28. 10:02
728x90
인터페이스란 ?

 

추상클래스의 추상메서드를 활용하는 것과 같이

더 강력하게 추상만 넣어두어 규칙만 명시한것이라고 볼 수있다.

클래스와 클래스를 연결하는 기법이고,

서로 상속관계가 아닌 클래스들을 연관성 있게 다형성을 활용하여 체계성을 만들고 싶을때 사용한다.

추상 메서드와 상수(리터럴 의무!) 만 올 수있다.

 

interface의 특징
1. 완전한 추상화 : 인터페이스는 기본적으로 모든 메서드가 추상 메서드이며 , 구현을 가질 수 없다.
(Java 8 이후부터는 디폴트 메서드와 정적 메서드에 한해 구현을 가질 수 있다. 아래의 메서드 사용법 있음.)
2. 상태없음 : 인스턴스 변수를 가질 수없다
(단 , 상수는 가질 수 있다.)
3. 다중 상속 지원 : 하나 이상의 인터페이스를 구현 할 수 있다.
4. 구현 : 클래스가 인터페이스를 구현할 때  implements 키워드를 사용한다.

 

 

 

 

 

  • 인터페이스 형태
interface Animali{
	final static int LEGS = 4;
	
	void breath ();
	void sound ();
    //void Animali{
	//	System.out.println("생성자 ?");
	//} //생성자는 사용할 수 없다.
}

추상 클래스 앞에 추상을 명시했듯,

interface는 interface를 명시해야하고,

상수와 추상 메서드만 올 수 있다.

이 규칙이 적용되기 때문에 생략해서 쓸 수 있는 부분이 생긴다

상수 : public static final 생략가능.
추상 메서드 : public abstract 생략가능. → 후손이 사용하기 위해 public임.

 

인스턴스의 생성
인터페이스는 직접 생성이 불가능하고 ,
인스턴스의 타입으로는 정의가 가능하다.
즉 , 구현된 클래스를 통해 생성된다.
사용범위는 인터페이스에 정의된 만큼 사용이 가능하고, 생성자는 사용할 수 없다.
  • 인터페이스 구현 클래스
class Cati implements Animali{

	@Override
	public void breath() {
		System.out.println("고양이는 숨을 쉽니다 ! , class ) Cati -Animali(Animali 의 추상메서드) ");
		
	}

	@Override
	public void sound() {
		System.out.println("야옹 야옹 , class ) Cati -Animali(Animali 의 추상메서드) ");
		
	}
	
}

 

 

  • 메인메서드에서의 사용

인터페이스는 직접적으로 생성할 수 없고 타입으로 사용할 수 있다.

멤버의 사용범위가 추상클래스처럼 , 인터페이스에 정의된 만큼 사용할 수 있다.

Animali ani = new Cati();
		
ani.breath();
ani.sound();
System.out.println(Animali.LEGS); // static 임으로 static 으로 접근할것.

cati 은 클래스 이기 때문에 생성자가 사용 가능하다


 

 

인터페이스의 구현 메서드
반드시 바디 구현,
오버라이드의무 없음.
  • interface 의 static 메서드

우리가 일반적으로 알고 있는 static 메서드.

	static void staticTest() {
		System.out.println("interface NewInter 의 static void staticTest 메서드 ");
	}

static 메서드는 클래스 종속임으로 , 오버라이딩과는 무관.

동명의 static 메서드는 허용

 

  • interface default 메서드

구현부가 있는 일반 메서드. 추상메서드와 구분을 해주기 위해 default 를 명시.

	default void crying() {
		System.out.println("default 메서드는 default를 명시 . interface ) Animali");
	}

인터페이스의 default메서드는 구현클래스에서 오버라이딩의무는 없으나 필요시에 허용됨.

단 , default 의 키워드 사용 불가, 접근범위는 조상보다 최소한 같거나 넓어야함.

참고로 조상(interface)의 경우에는 접근범위가 명시되어있지 않다면 , public 이다.

주의할 점은 접근제어자 default 는 접근 제어자를 정의하지 않았을때의 기본값을 의미하는 것 뿐이다.

인터페이스명.super를 사용하여 특정 인터페이스의 default 메서드를 명시적으로 호출할 수있다.

 


 

인스턴스 확인 연산자
instanceof
  • 개념

istanceof 는 객체가 특정 클래스의 인스턴스이거나 ,

클래스의 상위 클래스 혹은 인터페이스를 구현한 경우 true를 반환한다.

 

추상 클래스나 클래스 타입을 확인할 떄에는 instanceof 가 필수적이지 않을 수 있다.

반면 , 인터페이스 타입의 경우에는 런타임 시점에서 오류가 발생할 가능성이 있어서

instanceof 연산자로 확인하는 것이 안전하다.

 

추상클래스나 클래스 타입과의 비교
if (cat1 instanceof Animal) {
    System.out.println("cat1 은 Animal 의 인스턴스 이다.");
}

클래스 타입비교에서는 instanceof 를 사용하지 않아도 컴파일러가 타입 오류를 잡아 내기 때문에 큰 의미가 없을 수 있다.

 

인터페이스와의 비교
if (ani instanceof Animali) {
    System.out.println("ani는 Animali 의 인스턴스인가 ? yes");
}

인터페이스 타입의 확인은 런타임에 오류 발생할 가능성이 있어서 , instanceof로 사전에 확인하는 거싱 좋음.

 

실제 테스트
 if(eagle instanceof Animali) {
     System.out.println("eagle 는 Animali의 인스턴스 인가 ? yes ");
 } else {
     System.out.println("eagle 는 Animali의 인스턴스 인가 ? no ");
 }

 

 


 

인터페이스의 다향성

 

인터페이스 정의
interface Soundable {
    void makeSound(); // 동물의 소리를 나타내는 메서드
}

 

인터페이스 구현 클래스들
class Dog implements Soundable {
    @Override
    public void makeSound() {
        System.out.println("Woof! Woof!");
    }
}

class Cat implements Soundable {
    @Override
    public void makeSound() {
        System.out.println("Meow! Meow!");
    }
}

class Cow implements Soundable {
    @Override
    public void makeSound() {
        System.out.println("Moo! Moo!");
    }
}

 

다형성을 적용한 메서드
public class AnimalSoundTest {
    public static void main(String[] args) {
        Soundable dog = new Dog();
        Soundable cat = new Cat();
        Soundable cow = new Cow();

        // 다형성 적용 - 동일한 인터페이스 타입을 통해 호출 가능
        playSound(dog); // Woof! Woof!
        playSound(cat); // Meow! Meow!
        playSound(cow); // Moo! Moo!
    }

    public static void playSound(Soundable animal) {
        animal.makeSound(); // 인터페이스에 정의된 메서드 호출
    }
}

 

  • playSound 메서드는 Soundable 인터페이스 타입을 매개변수로 받음으로써
    다양한 클래스의 인스턴스를 처리할 수 있다.
  • 각기 다른 Soundable 인스턴스를 playSound 메서드에 전달하면,
    실제 인스턴스에 따라 makeSound()의 구현이 호출된다.
  • 이런 식으로 인터페이스를 통해 다형성을 구현하면,
    동일한 메서드를 호출하더라도 서로 다른 동작을 실행할 수 있다.

인터페이스와 추상 클래스의 차이

 

  • 추상 클래스 : 구현 할 수있는 기본 동작을 정의하면서 상속을 통한 재사용이 가능하도록 설계. 상속 계층 구성시 사용
  • 인터페이스 : 주로 규약(기능 구현의 약속)을 제공하고 다중 구현이 가능함. 다양한 클래스에서 인터페이스를 사용하여 다형성을 구현할 수 있음.

 

 

 

  • 인터페이스는 클래스 간의 규약을 설정해 일관성을 유지하게 하고, 다형성을 지원하며, 구현체에 대한 결합도를 낮출 수 있다.
  • 추상 클래스는 기본 동작을 상속 계층에 제공하는 데 유용하지만, 단일 상속만 가능하기 때문에 인터페이스에 비해 유연성이 적다.
  • 따라서 인터페이스는 객체 지향 설계에서 다양한 객체의 상호작용을 구조적으로 설계할 때 중요한 역할을 한.

 


인터페이스를 사용하는 이유

 

다형성 구현

인터페이스를 사용하면 특정 클래스에 종속되지 않고도 일관된 방식으로 동작을 구현할 수 있다.

느슨한 결합

인터페이스를 사용하면 , 구현된 클래스에 대한 구체적인 정보 없이도 코드 간의 결합도를 낮출 수 있다.

예를 들어 , 데이터 저장소를 바꾸는 상황에서 인터페이스만 동일하다면 구현체를 쉽게 교체가 가능하다. 

다중 상속 효과

자바는 클래스에서 다중 상속을 지원하지 않지만 , 인터페이스를 통해 다중 구현을 가능하게 한다.

즉 , 여러개의 인터페이스를 구현할 수 있기 때문에 다중 상속과 비슷한 효과를 낼 수 있다.