인터페이스란 ?
추상클래스의 추상메서드를 활용하는 것과 같이
더 강력하게 추상만 넣어두어 규칙만 명시한것이라고 볼 수있다.
클래스와 클래스를 연결하는 기법이고,
서로 상속관계가 아닌 클래스들을 연관성 있게 다형성을 활용하여 체계성을 만들고 싶을때 사용한다.
추상 메서드와 상수(리터럴 의무!) 만 올 수있다.
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()의 구현이 호출된다. - 이런 식으로 인터페이스를 통해 다형성을 구현하면,
동일한 메서드를 호출하더라도 서로 다른 동작을 실행할 수 있다.
인터페이스와 추상 클래스의 차이
- 추상 클래스 : 구현 할 수있는 기본 동작을 정의하면서 상속을 통한 재사용이 가능하도록 설계. 상속 계층 구성시 사용
- 인터페이스 : 주로 규약(기능 구현의 약속)을 제공하고 다중 구현이 가능함. 다양한 클래스에서 인터페이스를 사용하여 다형성을 구현할 수 있음.
- 인터페이스는 클래스 간의 규약을 설정해 일관성을 유지하게 하고, 다형성을 지원하며, 구현체에 대한 결합도를 낮출 수 있다.
- 추상 클래스는 기본 동작을 상속 계층에 제공하는 데 유용하지만, 단일 상속만 가능하기 때문에 인터페이스에 비해 유연성이 적다.
- 따라서 인터페이스는 객체 지향 설계에서 다양한 객체의 상호작용을 구조적으로 설계할 때 중요한 역할을 한.
인터페이스를 사용하는 이유
다형성 구현
인터페이스를 사용하면 특정 클래스에 종속되지 않고도 일관된 방식으로 동작을 구현할 수 있다.
느슨한 결합
인터페이스를 사용하면 , 구현된 클래스에 대한 구체적인 정보 없이도 코드 간의 결합도를 낮출 수 있다.
예를 들어 , 데이터 저장소를 바꾸는 상황에서 인터페이스만 동일하다면 구현체를 쉽게 교체가 가능하다.
다중 상속 효과
자바는 클래스에서 다중 상속을 지원하지 않지만 , 인터페이스를 통해 다중 구현을 가능하게 한다.
즉 , 여러개의 인터페이스를 구현할 수 있기 때문에 다중 상속과 비슷한 효과를 낼 수 있다.
'Developer > JAVA' 카테고리의 다른 글
Java에서의 SQL 데이터 처리: Statement, PreparedStatement ,ResultSet (0) | 2024.10.30 |
---|---|
JAVA , JAVA와 데이터베이스 연동을 통한 데이터 처리 (2) | 2024.10.30 |
JAVA , Exception의 직접 처리와 위임 처리 , 사용자 정의 Exception (0) | 2024.09.23 |
Java , 예외 처리 Exception , try-catch (0) | 2024.09.22 |
JAVA , 열거형 클래스 enum ! (1) | 2024.09.21 |