추상 클래스
란 클래스 앞에 abstract 키워드가 붙은 클래스이다.
추상 메서드
란 메서드 앞에 abstract 키워드가 붙은 메서드이다.
추상 클래스와 추상 메서드를 사용하면 자식 클래스에서 반드시 오버라이딩 해야 하는 메서드를 명시적으로 지정해줄 수 있다.
추상 메서드를 지정해주기 위해서는 클래스부터 추상클래스여야 한다.
abstract class Person { // 일반 클래스에서 추상 메서드를 사용하면 에러가 난다.
void print() {
System.out.println("print");
}
abstract void absPrint();
}
class Student extends Person {
void absPrint() { // 상속받은 추상 메서드를 오버라이딩 하지 않으면 error 가 난다.
print();
System.out.println("absPrint1");
}
}
public class Test {
public static void main(String[] args) throws IOException {
Student student = new Student(); // print
student.absPrint(); // absPrint1
Person person = new Person() {
@Override
void absPrint() {
System.out.println("absPrint2");
}
};
person.print(); // print
person.absPrint(); // absPrint2
}
}
추상 클래스 자체는 다른 클래스처럼 객체 생성이 불가능하고,
오버라이딩으로 그때그때 직접 정의해야 생성할 수 있다.
인터페이스
는 추상 클래스와 비슷하지만, 추상메서드와 상수만으로 이뤄진다.
인스턴스와 클래스를 동시에 이용하면 다중 상속처럼 사용할 수 있다.
interface School {
public static final int MAX_CLASS = 20;
public static final int MAX_STUDENTS_PER_CLASS = 40;
public abstract void printSchool();
}
/* School 인터페이스만 이용 */
class Student1 implements School {
@Override
public void printSchool() {
System.out.println("00 University");
}
}
class Person {
public String name;
public void printName() {
System.out.println("Person's name is " + name);
}
}
/* School 인터페이스 + Person 클래스 둘 다 이용 */
class Student2 extends Person implements School {
int classNum;
String name;
Student2() {
}
Student2(String personName, String studentName, int classNum) {
super.name = personName;
this.classNum = classNum;
this.name = studentName;
}
public void printNickName() {
System.out.println("Student's name is " + name);
}
@Override
public void printSchool() {
System.out.println("11 University");
}
}
public class Test {
public static void main(String[] args) throws IOException {
/* interface 도 추상 클래스와 같은 방법으로 객체 생성 가능 */
School school = new School() {
@Override
public void printSchool() {
System.out.println("I'm School Interface");
}
};
school.printSchool();
/* Student1 */
Student1 interStu = new Student1();
interStu.printSchool();
/* Student2 */
Student2 interClassStu = new Student2();
interClassStu.printSchool();
/* 상속받은 메서드와 필드 우선순위 */
Student2 interClassStu1 = new Student2();
interClassStu1.name = "Horang";
interClassStu1.classNum = 1;
interClassStu1.printName();
interClassStu1.printNickName();
Student2 interClassStu2 = new Student2("LIM", "Horang", 1);
interClassStu2.printName();
interClassStu2.printNickName();
}
}
대표적으로 사용의도의 차이로 볼 수 있다.
추상 클래스
: ~이다.
와 같이 정의하는 느낌이 강하다.
인터페이스
: ~할 수 있다.
와 같이 기능적인 느낌이 강하다.
더 자세한 내용은 구글링하도록 하자.