Java 추상 클래스와 인터페이스는 기능적으로 아주 유사하다.
Java를 공부하면서 이 둘이 왜 나눠졌는지 이해하는건 자바 언어의 철학을 이해하는데 한 걸음 다가간다고 생각했다. 따라서 둘의 공통점 및 구분되는 특징을 조사해보고 인터페이스, 추상 클래스를 사용하는 클래스 다이어그램을 설계하고 코드로 실습을 해 보았다.
인터페이스의 특징
- 동일한 기능을 가지는 객체들에 대한 기능적인 '틀'을 제공한다. A(자식) Has a B(부모)
- 다중 상속이 가능하다.
- 하나의 규칙으로 적용된다.
- 자식 요소들과 Has a (~할 수 있는) 관계를 가진다. (자식들이 공통된 기능을 가진다.)
- 즉, 상속 받는 객체들이 할 수 있는 '기능'에 대해 미리 정의한다.
- 주로 '~able'로 끝나도록 명명한다. ex) talkable, flyable
- 인터페이스의 메소드에는 몸통이 없다.
- 인터페이스간의 상속이 가능하고, 상속을 사용할 때 extents를 사용한다. (implements (X))
// HomeworkMakeable.java
package PNU;
public interface HomeworkMakeable {
public void makeHomework();
}
// TestMakeable.java
package PNU;
public interface TestMakeable {
public void makeTest();
}
// Submitable.java
package PNU;
public interface Submitable {
public void submit();
}
3개의 간단한 인터페이스가 있다.
아래의 교수, 학생 클래스에 implements하여 사용할 예정이다. 각각의 인터페이스에 있는 메소드들은 자식 클래스에서 구현을 마무리 지어야 하며, 구현하지 않을 경우 컴파일 에러가 발생한다.
추상 클래스의 특징
- 동일한 특성을 가지는 하위 객체들에 대한 기본 틀을 제공한다. A(자식) Is a B(부모)
- 인터페이스 역할도 하면서 실제 사용가능한 메소드도 추가 가능하다. ( 실제 사용하는 메소드 앞에는 abstract 필요없음)
- abstract class 로 선언하여 상속(extends)을 통해 자식 클래스에서 메소드들을 완성하도록 유도한다. (인터페이스랑 동일한 특성을 가진다. ), (자식 클래스에서 완성을 요구하는 메소드 앞에는 abstract를 붙인다. ex) public abstract void move();)
- 엄연한 클래스이므로 다중상속이 불가하다.
- Is a (~이다). 자식 객체들은 추상 클래스의 객체이다.
// Human.java
package PNU;
public abstract class Human {
private String name;
private String contact;
public Human(String name, String contact){
this.name = name;
this.contact = contact;
}
public String getContact() {
return contact;
}
public String getName() {
return name;
}
public void setContact(String contact) {
this.contact = contact;
}
public void setName(String name) {
this.name = name;
}
public abstract void move();
}
Human 추상클래스 이다.
멤버변수로 name과 contact를 가진다. Human을 상속받는 클래스들은 모두 getName, getContact, setName, setContact가 필요할 것이므로 추상클래스에서 미리 선언한 모습이다. 이는 자식 클래스에서 따로 오버라이드(Override)가 가능하다.
public abstract void move(); 는 자식 클래스에서 완성시켜야 하는 메소드이다. 완성하지 않는다면 컴파일 에러가 발생할 것이다.
// Professor.java
package PNU;
public class Professor extends Human implements HomeworkMakeable, TestMakeable{
public Professor(String name, String contact){
super(name, contact);
}
@Override
public void move() {
System.out.println("차를 타고 갑니다");
}
@Override
public void makeHomework() {
System.out.println("과제가 나왔습니다");
}
@Override
public void makeTest() {
System.out.println("시험은 매운맛");
}
}
// Student.java
package PNU;
public class Student extends Human implements Submitable {
public Student(String name, String contact){
super(name, contact);
}
@Override
public void move() {
System.out.println("걸어갑니다");
}
@Override
public void submit() {
System.out.println("죄송합니다");
}
}
Professor 클래스와 Student 클래스는 모두 Human 추상 클래스를 상속받는다. 이 둘은 모두 Human과 동일한 특성을 지닌 객체이기 때문이다. 하지만 interface는 서로 다른것을 상속받는다. 왜냐면 교수와 학생은 같은 사람이지만 서로 할 수 있는 일이 다르기 때문이다.
이처럼 기능적으로 같은 역할을 하는 경우에는 인터페이스를 사용해 구현을 한다. 예를 들어 Submitable 인터페이스 같은 경우에는 Student 클래스에 implement될 수도 있고, 나중에 회사원 클래스가 생길 경우 회사원도 Submit행동을 취할 수 있기 때문에 해당 인터페이스를 재사용 할 수 있다.
// Daily.java
package PNU;
public class Daily {
public static void main(String[] args) {
Professor prof = new Professor("CHO", "12345678");
Student std = new Student("KIM", "19980404");
prof.move();
prof.makeHomework();
std.move();
std.submit();
prof.makeTest();
std.submit();
}
}
인터페이스와 추상 클래스에 대해서 이론적으로 알아보고, 어떻게 적용할 수 있을 지 생각해보고, 이를 구현해서 아주 간단히 실습을 해보았다.
누군가 'java에서 추상 클래스와 인터페이스를 왜 사용하는지, 둘은 어떻게 다른지, 사용할 수 있는 예로서 어떤게 있는지' 등등을 물어본다면 자신있게 대답할 수 있을 것 같다.
'Lang > Java' 카테고리의 다른 글
[Java] Lambda 특징과 활용 (1) | 2022.10.03 |
---|---|
함수형 프로그래밍과 Java #1 (6) | 2022.09.08 |
[디자인 패턴] 싱글톤 패턴 (Creational) (0) | 2022.01.10 |
[Java] Runnable과 Thread의 차이 (0) | 2021.12.11 |
[Java] Call by Reference? Call by Value! (0) | 2021.08.31 |