1. 추상클래스
추상클래스의 작성
추상 클래스?
상속이 자손 클래스를 만드는데 조상 클래스를 사용하는 것이라면, 추상 클래스는 기존의 클래스의 공통부분을 봅아내서 조상 클래스를 만드는 것이라고 할 수 있다.
추상 클래스는 추상 메서드를 포함하고 있다는 것을 제외하고는 일반 클래스와 전혀 다르지 않다. 추상클래스에도 생성자가 있으며, 멤버변수와 메서드도 가질 수 있다.
추상 클래스 작성 방법
- 메서드는 선언부와 구현부 두가지 섹션이 존재한다.
- 추상 메서드는 선언부만 작성하고 구현부는 작성하지 않은 채로 남겨둔 것이다.
사용 방법
추상 메서드는 보통 자식 클래스에서 공통적으로 사용하지만 그 메서드가 각각 다른 행동을 해야할떄, 그와 동시에 무조건 작성해야 할 때 사용한다. 오버라이딩을 위해서 그냥 빈 메서드로 남겨둘 수 있지만 자식 메서드에게 꼭 선언하라고 하는것과 같다. 다만 조심할 점은 조상 참조변수로 자식 인스턴스에 접근하지 않으면 해당 메서드를 사용 할 수 없을 수 없기 떄문에 주의해야한다.
추상 클래스의 예시
2. 인터페이스(interface)
인터페이스의 의미와 작성
➡️ 의미
인터페이스는 일종의 추상클래스이다. 인터페이스는 추상클래스처럼 추상 메서드를 갖지만 추상클래스보다 추상화 정도가 높아서 추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다. 오직 추상메서드와 상수만을 멤버로 가질 수 있으며, 그외의 어떠한 요소도 허용하지 않는다.
➡️ 용도
인터페이스는 그 자체만으로 사용되기 보다는 다른 클래스를 작성하는데 도움 줄 목적으로 작성된다.
➡️ 작성
인터페이스의 작성은 클래스를 작성하는 것과 같다.
- 모든 멤버변수는 public static final이여야 하며, 이를 생략할 수 있다.
- 모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다.
→ 생략된 제어자는 컴파일 시에 컴파일러가 자동으로 추가해준다.
인터페이스의 상속
➡️ 인터페이스의 상속
인터페이스는 인터페이스로만 상속받을 수 있으며, 클래스와는 달리 다중상속이 가능하다.
➡️ 인터페이스의 다중 상속
기본적으로 JAVA에서는 단일 상속만 허용한다. 하지만 인터페이스를 사용하면 다중 상속처럼 사용할 수 있다. 한개의 클래스를 상속받고 implement를 이용하여 인터페이스를 확장시키면 다중 상속처럼 사용할 수 있다.
- 이렇게 구현한 인터페이스를 확장할 수 있다.
➡️인터페이스 끼리의 다중 상속
- 인터페이스의 경우 다중 상속이 가능하다.
- 다중상속으로 Fightable은 move(), attack() 메서드를 멤버로 갖게 된다.
인터페이스의 구현
➡️인터페이스의 구현
인터페이스도 추상 클래스처럼 그 자체로는 인스턴스를 생성할 수 없다. 클래스에 확장 시켜주어야 한다.
- 인터페이스 이름에는 주로 ~를 할 수 있는 의미인 able로 끝나는 경우가 많다.
➡️구현 시 주의사항
- 만약 구현하는 인터페이스의 메서드중 일부만 구현한다면, abstract를 붙여서 추상 클래스로 선언하여야 한다.
- 클래스에서는 상속과 인터페이스 구현을 둘다 할 수 있다.
- 인터페이스에 구현된 메서드를 오버라이딩 할 때에는 반드시 인터페이스가 가지고 있는 접근 제어자보다 더 넓은 제어자를 사용해 주어야 한다.
인터페이스의 다형성
➡️개요
인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있으며, 인터페이스 타입으로의 형변환도 가능하다.
➡️예시
- 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스 참조
- 메서드의 매개변수 타입으로 사용 가능
- 메서드 호출 시 해당 인터페이스를 구현한 클래스의 인스턴스를 매개변수로 제공해야 한다는 것이다. 따라서 attack method를 호출할 때에는 매개변수로 Fightable인터페이스를 구현한 클래스의 인스턴스를 넘겨주어야 한다.
예제
➡️Return type이 인터페이스?
- 리턴 타입이 인터페이스라는 것은 메서드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미한다.
➡️예제
➡️인터페이스의 장점
- 개발 시간을 단축시킬 수 있다.
- 표준화가 가능하다.
- 서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
- 독립적인 프로그래밍이 가능하다.
🙄 Why?
- 인터페이스가 작성되면 이를 이용해서 프로그램을 작성하는게 가능하다. 그리고 동시에 다른 한쪽에서는 인터페이스를 구현하는 클래스를 작성하게 하면, 인터페이스를 구현하는 클래스가 작성될때 까지 기다리지 않고 양쪽에서 동시 개발이 가능하다.
- 기본 틀을 인터페이스로 구현하면 개발자들의 표준화가 가능하다.
- 서로 상속 관계에 있지도 않고 같은 조상클래스를 갖고 있지 않아도 관계를 맺어줄 수 있다.
- 한 클래스의 변경이 관련된 다른 클래스에 영향을 미치지 않기 때문에 독립적인 프로그래밍이 가능하다.
➡️인터페이스를 사용한 가용성 증진
부모 클래스 building 아래 4가지 건물이 있다고 가정하자
해당 클래스 중 아파트와 집에 추가적이며 동일한 메서드를 구현하고 싶다.
물론 인터페이스를 구현하여 각자 추가를 해주어도 되지만 클래스를 하나 생성하여 내부적으로 사용하는 방법이 있다.
인터페이스의 이해
인터페이스의 작성 방법, 사용방법을 알아 보았다. 매개변수로 사용하여 구현된 클래스를 전달할 수도, 리턴타입을 인터페이스 타입으로 줘서 인터페이스가 구현된 클래스를 반환하는 것 또한 시도해보았다.
이 외에도 인스턴스를 활용하면 의존성 문제를 분리할 수 있다. 사전에 두개의 지식을 염두하고 가야한다.
- 클래스를 제공하는 쪽과 클레스를 사용하는 쪽이 있다.
- 클래스를 사용하는 쪽은 사용하려는 변수 혹은 메서드만 알면 된다. (뭐가 구현되어 있는지는 자세하게 알 필요가 없다.)
인터페이스를 사용한 관계 분리
클래스B는 db를 관리하는 서버, A는 그 db를 접근할 필요가 있는 시스템이라고 가정하자. 만약 상속을 통하거나 구현의무를 A가 갖게되면 클래스 B에서 db가 변경되면 그에 맞춰서 A도 접근 요소를 바꾸어야 한다. 하지만 Interface를 통하여 필요한 메서드를 구현하고 A에서는 그 메서드만 사용할 수 있도록 설정했다.
- B가 변경되어도 A에서는 connect라는 메서드만 사용하면 되기때문에 의존성 문제가 보다 쉽게 해결됩니다.
Interface에서의 default 메서드와 static 메서드
JDK 1.8부터 인터페이스에 static메서드와 (default) 메서드의 추가를 허용한다.
➡️default 메서드
인터페이스 같은 경우에는 보통 추상 메서드가 추가가 되기 때문에 만약 메서드가 추가되게 된다면 해당 인터페이스를 확장 받는 모든 클래스에 새로운 메서드가 추가가 되어야 한다. 따라서 JDK 설계자들은 default 메서드를 고안해 내었다. 디폴트 메서드는 추상 메서드의 기본적인 구현을 제공하는 메서드로, 추상 메서드가 아니기 떄문에 디폴트 메서드가 새로 추가되어도 해당 인터페이스를 구현한 클래스를 변경하지 않아도 된다.
예시)
default method와 중복이 된다면 어떻게 될까
- 여러 인터페이스의 디폴트 메서드 간의 충돌
→ 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버라이딩 해야 한다.
- 디폴트 메서드와 조상 클래스 메서드 간의 충돌
→ 조상 클래스의 메서드가 상속되고, 디폴트 메서드는 무시된다.