본문 바로가기
프로젝트 개발 기록/[개발] java | spring

[Java] 다형성(polymorphism), 추상 클래스, 인터페이스, 내부 클래스

by HelloJudy 2022. 10. 12.

다형성 (polymorphism)

여러 가지 형태를 가질 수 있는 능력 (하나의 객체가 여러개의 자료형 타입을 가질 수 있는 것)
조상 타입 참조 변수로 자손 타입 객체를 다루는 것

 

  • 자손 타입의 참조변수로 조상 타입의 객체를 가리킬 수 없다.

 

조상: TV, 자손: SmartTV

Tv t = new SmartTV();  // OK
SmartTv s = new TV();  // 에러

 

멤버의 개수가 7가진데 5가지만 참조변수로 사용할 수도 있다.

 

자바의 정석 유튜브 강의 중

 

✔️ 참조변수의 형변환

사용할 수 있는 멤버의 개수를 조절하는 것

 

  • 조상 자손 관계의 참조변수는 서로 형변환 가능하다.

 

자손타입 -> 조상타입(up-casting) : 형변환 생략가능
조상타입 -> 자손타입(down-casting) : 형변환 생략불가
FireEngine f = new FireEngine();
Car c = (Car) f;

 

✔️ instanceof 연산자

참조변수의 형변환 가능여부 확인에서 사용. 가능하면 true 반환

 

  1. 형 변환 가능 확인 (instanceof 사용해서)
  2. 형 변환
어떤 타입에 대한 instanceof연산의 결과가 true라는 것은 검사한 타입으로 형변환이 가능하다는 것을 뜻한다.

 

✔️ 다형성 장점

매개변수의 다형성

: 메서드의 매개변수로 조상타입의 참조변수를 사용해서 하나의  메소드로 여러 타입의 객체를 받을 수 있다.

 

여러 종류 객체를 배열로

: 하나의 배열에 여러 종류 객체 저장 가능하다.

 

Product p1 = new TV();
Product p2 = new Computer();
Product p1 = new Audio();

Product p[] = new Product[3];
p[0] = new TV();
p[1] = new Computer();
p[2] = new Audio();

 


추상 클래스 (abstract class)

미완성 설계도. 미완성 메서드(추상 메서드)를 갖고 있는  클래스.

 

abstract class Player {
	abstract void play(int pos);
	abstract void stop();
}

 

  • 추상 클래스로 인스턴스 생성 불가
  • 상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능
class AudioPlayer extends Player {
	void play(int pos) {}
    void stop() {}
}

AudioPlayer ap = new AudioPlayer();
Player ap = new AudioPlayer();

 

✔️ 추상 메서드 (abstract method)

미완성 메서드. 구현부(몸통, {}가 없는 메서드)
abstract 리턴타입 메서드이름();

 

꼭 필요하지만 자손마다 다르게 구현될 것으로 예상되는 경우

 

 

추상 클래스 작성

  • 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성한다.
  • 기존 클래스의 공통 부분을 뽑아서 추상클래스를 만든다.

자바의 정석 유튜브 중

 

추상 클래스를 의미있는 단위로 나눠서 작성하면 내가 원하는대로 상속받아서 개발하기 편하다.

 

추상화 <- -> 구체화

 

 


인터페이스 (interface)

추상 메서드의 집합

구현된 것이 전혀 없는 설계도. 껍데이 (모든 멤버가 public)

 

  • 추상 클래스: 일반 클래스인데 추상 메서드를 가지고 있는 것 (생성자, iv 있을 수 있다)
  • 인터페이스: 완전히 추성 메서드만 있는 것
interface 인터페이스 이름 {
	public static final 타입 상수이름 = 값;
	public abstract 메서드이름(매개변수목록);
}

 

인터페이스 상속

  • 인터페이스의 조상은 인터페이스만 가능 (Object가 최고 조상 아님)
  • 다중 상속이 가능하다. (추상메서드는 충돌해도 문제가 없다.)
interface Fightable extends Movable, Attackable {}

 

인터페이스 구현 

: 인터페이스에 정의된 추상 메서드를 완성하는 것

 

  • extends: 추상 클래스상속을 통해서 추상 클래스를 완성 (구현)
  • implements: 인터페이스구현을 통해서 추상 클래스 완성 (구현)
class 클래스이름 implements 인터페이스이름 {
  // 인터페이스에 정의된 추상메서드를 모두 구현해야 한다.
}

 

✔️ 추상 클래스 vs 인터페이스

  1. 공통점: 추상 메서드를 가지고 있다. 미완성 설계도이다.
  2. 차이점: 인터페이스는 iv를 가질 수 없다.

 

✔️ 인터페이스를 이용한 다형성

interface Fightable {
	void move(int x, int y);
	void attack(Fightable f);
}

class Fighter extends Unit implements Fightable {
	public void move(int x, int y) {}
	public void attack(Fightable f) {}
}

Unit u = new Fighter();
Fightable f = new Fighter();

f.move(100, 200);
f.attack(new Fighter());

 

  • 인터페이스를 메서드의 리턴 타입으로 지정할 수 있다.
  • 반환 타입을 인터페이스로 하면 메서드는 인터페이스를 구현한 객체를 반환해야 된다.

 

✔️ 장점

  • 두 대상(객체) 간의 '연결, 대화, 소통'을 돕는 '중간 역할'을 한다.
  • 선언(설계)와 구현을 분리시킬 수 있게 한다.
  • 개발 시간을 단축할 수 있다.
  • 변경에 유리한 유연한 설계가 가능하다.
  • 표준화가 가능하다.
  • 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.

 

예시

class B {
	public void method() {
		System.out.println("methodInB");
    }
}

껍데이와 알맹이가 함께 있어서 유연하지 않고 변경에 불리하다.

 

그래서 이것을 선언부만 인터페이스로 떼어내서 분리한다.

 

  • 메서드 선언, 추상메서드 (껍데기)
interface I {
	public void method();
}
  • 메서드 구현 (알맹이)
class B implements I {
	public void method() {
		System.out.println("methodInB");
    }
}

 

✔️ 디폴트 메서드와 static 메서드

  • 인터페이스에 디폴트 메서드, static 메서드 추가 가능 (JDK 1.8부터)
  • 인터페이스에 새로운 메서드(추상 메서드)를 추가하기 어려움.
    • 그래서 default method

 

예외사항

interface MyInterface {
	void method();
    default void newMethod() {} 
}

 

충돌 -> 오버라이딩 하자!

 


📌 Reference

  • 남궁 선, 「자바의 정석」, 도우출판
반응형

댓글