: 불필요한 정보를 제거하고 본질적 특징만 남기는 것.
→ 유지보수성이 좋은 프로그램
공통적인 속성과 기능을 정의
→ 코드의 중복 ↓
→ 클래스 간 관계를 효과적으로 설정
abstract 제어자abstract가 클래스나 메서드에 붙으면, 자동으로 추상 클래스와 추상 메서드가 된다. => 미완성된 클래스나 메서드라고 생각하면 된다.
abstract class 클래스 () { --- } 이렇게 추상 클래스로 작성되어있다면, 이건 상속을 통해 내부의 추상 메서드를 구현해주어야 한다.
Interface & implements인터페이스는 추상 클래스의 일종이다.
인터페이스는 implements 키워드를 통해 활용할 수 있다.
LifeForm 인터페이스를 상속한 Animal 인터페이스, 그리고 두 인터페이스를 활용하는 Cat, AnimalMain 클래스로 알아보자
//LifeForm 인터페이스
public interface LifeForm {
void exists();
}
extends 키워드를 통해 LifeForm 인터페이스를 Animal 인터페이스가 상속받았다.
//Animal 인터페이스
public interface Animal extends LifeForm{
void makeSound();
}
implements 키워드를 통해 Animal 인터페이스를 활용할 수 있다
//Cat 클래스
public class Cat implements Animal{
@Override
public void exists(){
System.out.println("cat is exist");
}
@Override
public void makeSound() {
System.out.println("Meow");
}
public void scratch(){
System.out.println("scratch");
}
}
//AnimalMain 클래스
public class AnimalMain {
public static void main(String[] args) {
Cat cat = new Cat();
cat.exists();
cat.makeSound();
cat.scratch();
}
}
AnimalMain 클래스를 실행하면 기능들이 상속되어 출력되는 모습을 확인할 수 있다. 이처럼 상속과 추상화를 잘 활용하면, 개발자들에게 틀을 제공하므로서 중복 없이 더 효과적으로 코딩할 수 있다.

: 하나의 타입으로 여러 객체를 다룰 수 있는 기술이다!
보통 하나의 객체는 하나의 타입으로 고정되어 있지만, 다형성을 사용하면 하나의 객체가 다른 타입으로 사용될 수 있다는 뜻이다.
위의 추상화 개념을 활용해 다형성을 구현해보자
자바에서 부모 타입은 자신은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. => ✨다형적 참조✨
예제를 통해 이해해보자.
Parent클래스와 그를 상속하는Child클래스, 그리고 PolyMain 메인 클래스를 만들어보자
public class Parent {
public void parentMethod(){
System.out.println("Parent.parentMethod");
}
}
extends로 Parent 클래스를 상속한다
public class Child extends Parent{
public void childMethod(){
System.out.println("childMethod");
}
}
public class PolyMain {
public static void main(String[] args) {
System.out.println("부모가 부모 참조");
Parent parent = new Parent();
parent.parentMethod();
System.out.println("자식이 자식 참조");
Child child = new Child();
child.childMethod();
child.parentMethod();
System.out.println("부모가 자식 참조");
Parent poly = new Child();
poly.parentMethod();
}
}
PolyMain코드를 보자.
Parent클래스와 Child 클래스가 자신의 인스턴스를 참조하는 것은 당연히 가능하다.
여기서 다형성을 이용한다면,
부모 클래스인 Parent 클래스는 자식 클래스인 Child 클래스를 참조할 수 있다
하지만 반대는 불가능하다(컴파일 오류가 발생한다)
자바에서 부모 타입은 자신은 물론이고, 자신을 기준으로 모든 자식 타입을 참조할 수 있다. ➡️ 다형적 참조
이때 부모타입으로 자식 타입을 다룰 수 있었던 이유는 바로 자동 형변환(Casting) 덕분이다!
자식 → 부모 : 업캐스팅(UpCasting) - 자동으로 이루어짐
부모 → 자식 : 다운캐스팅(DownCasting) - 명시해주어야 함
Parent poly = new Child(); //⭐️ 자동 형 변환
poly.parentMethod();
//poly.childMethod -> 컴파일 오류 발생
위의 예제처럼 부모가 자식 클래스를 쓸 수 있었던 이유는 ✨업캐스팅✨ 덕분이었다.
위의 예제의 업캐스팅은 부모의 타입으로 데이터를 다룰 수 있지만, 자식 클래스의 고유 기능은 사용 불가하다.
부모클래스가 자식 클래스를 참조해 자식의 기능도 사용하고 싶다면 ✨다운캐스팅✨을 알아야한다
다운캐스팅: 다운캐스팅으로 자식 클래스의 고유 메서드를 사용 가능하다
Parent poly = new Child();
poly.parentMethod();
//⭐️ 다운캐스팅 (부모 Parent -> 자식 Child)
Child child = (child) poly;
child.childMethod //⭐️ 자식 클래스의 기능 활용 가능함.
instanceof잘못된 다운 캐스팅을 컴파일 단계에서 감지할 수 없기 때문에,
꼭 instanceof를 활용하는 것이 좋다.
: 객체가 특정 클래스나 인터페이스의 인스턴스인지 확인해줌
Parent poly = new Child();
poly.parentMethod();
//⭐️ 다운캐스팅 (부모 Parent -> 자식 Child)
Child child = (child) poly;
child.childMethod(); //⭐️ 자식 클래스의 기능 활용 가능함.
if (poly instanceof Child){
Child child = (child) poly;
child.childMethod();
} else {
System.out.println("다운캐스팅이 잘못됐어요");
}
이렇게 개념만 봐서는 왜 다형성을 써야하지...?라고 생각이 들었다.
예시를 보면서 장점을 알아보자
고양이와 강아지의 특성을 출력하고 싶을때, 다형성을 사용하면 코드의 길이를 줄이고 중복없이 깔끔하게 적을 수 있다.
public class Main {
public static void main(String[] args) {
Animal[] animals = {new Cat(), new Dog()};
for (Animal animal : animals) {
animal.makeSound();
}
}
}