꿈 : 멋진 개발자 🧸/자바의 정석

추상 클래스 & 인터페이스

hyeya_ 2022. 5. 6. 23:03

[추상 클래스

-미완성 설계도. 미완성 메서드를 갖고 있는 클래스. abstract가 붙는다.

   abstract class Player {              //추상클래스(미완성 클래스)

         abstract void play(int pos); //추상메서드(몸통{ }이 없는 미완성 메서드)

         abstract void stop();          //추상메서드

}

-다른 클래스 작성에 도움을 주기 위한 것. 인스턴스 생성 불가

Player P = new Player( ); //에러. 추상클래스의 인스턴스 생성 불가

 

-상속을 통해 추상 메서드를 완성해야 인스턴스 생성 가능

class AudioPlayer extends Player {

void play(int pos) { /* 내용 생략 /* }//추상메서드를 구현

void stop() { /* 내용 생략 /* }        //추상메서드를 구현

}

->더 이상 미완성 설계도(추상 클래스)가 아님

AudioPlayer ap = new AudioPlayer( ); // 인스턴스 생성 ok

Player ap = new AudioPlayer();         //조상타입 참조변수로 자손타입 객체 다룰 수 있음(다형성)

 

[추상 메서드] 

-미완성 메서드, 선언부만 있고 구현부(몸통 { })가 없는 메서드

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

 

-다른 클래스 작성에 도움을 줄 목적의 클래스

 → 상속을 통해 자손 클래스에서 추상 메서드, 즉 몸통을 구현하도록 강제성을 부여한다.

(Why? 미완성 메서드가 있으면 객체 생성이 안되므로.. 필수적인 기능(메서드)은 상속받아 구현하라고 알려주는 것)

 

-추상 메서드도 호출은 가능함

(상속을 통해 자손 클래스가 메서드를 완성한 후 자손 객체를 생성하고 나서 정상적으로 호출된다.)

 

-조상으로부터 물려받은 추상 메서드 중 구현되지 않은 메서드가 있다면 그 자손 클래스 역시 추상 클래스이다.

 

[추상 클래스의 작성]

1. 여러 클래스에 공통적으로 사용될 수 있는 추상 클래스를 바로 작성한다.

2. 기존 클래스의 공통 부분을 뽑아서 추상 클래스를 만든다.(코드가 간결해짐)

공통부분을 뽑아 만든 추상 클래스를 배열로 하여 여러 종류의 객체를 저장한다.

(다형성의 장점)

unit[ ]group = { new Marine( ), new Tank( ), new dropship( ) };

→ 배열생성, 초기화를 한번에 하는 코드

3. 추상클래스를 단계별로 작성

관리 용이

 

[추상화     <->   구체화]

애매,불명확 vs 명확,구체적

추상화된 코드는 구체화된 코드보다 유연하다. 변경에 유리함.

 

[인터페이스 interface]

-추상 메서드의 집합

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

 

[인터페이스 <-> 추상클래스]

비교하는 질문 많이 나옴

-추상클래스는 일반 클래스인데 추상 메서드를 가지고 있다. (일부가 미완성이다)

   일반 클래스이므로 생성자, iv를 가지고 있다.

-인터페이스는 추상 메서드 집합이다. 구현된 것이 아무것도 없다. (껍데기)

 

-인터페이스는 상수만 가질 수 있다(변수x)

-예외 없이 인터페이스의 모든 멤버는 public이다.

-메서드는 전부 추상 메서드이다. (선언부만 존재, 구현부X)

 

interface 인터페이스 이름 {

public static final 상수 이름 = 값;

public abstract 메서드 이름(Object... paramList); }

 * interface에서 너무나 당연한 public, abstract, final 생략 가능

 

[인터페이스의 상속]

-인터페이스의 조상은 인터페이스만 가능(Object가 최고 조상 아님)

-다중 상속이 가능. (추상 메서드는 충돌해도 문제 없음 구현부가 없으니까)

 

[인터페이스의 구현]

-인터페이스도 미완성 설계도이다.

-인터페이스에 정의된 추상 메서드를 완성하는 것을 구현한다고 한다.

-일부만 구현하는 경우, 클래스 앞에 abstract를 붙여야 함.

class  클래스이름 implements 인터페이스이름 {

           //인터페이스에 정의된 추상 메서드를 모두 구현해야 한다.

}

 

 

Q. 인터페이스란?

A. 추상 메서드의 집합

 

Q. 인터페이스의 구현이란?

A. 인터페이스의 추상 메서드 몸통{ }만들기(미완성 설계도 완성하기)

 

Q. 추상 클래스와 인터페이스의 공통점은?

A. 추상 메서드를 가지고 있다. (미완성 설계도)

 

Q. 추상 클래스와 인터페이스의 차이점은?

A. 인터페이스는 iv를 가질 수 없다!!!!!!!!!!!!

→추상 클래스는 일반 클래스인데 추상 메서드를 가지고 있는 것이며 일부만 미완성 상태이다.

→인터페이스는 추상클래스로만 이루어져 있다. 구현된 것이 아무것도 없는 껍데기이다.

  

[인터페이스를 이용한 다형성]

-인터페이스도 구현 클래스의 부모이다.

-인터페이스타입 매개변수는 인터페이스를 구현한 클래스의 객체만 가능(매우 중요)

→ 매개변수 타입이 인터페이스라는 것은 인터페이스를 구현한 객체만 받겠다는 뜻임

-인터페이스를 메서드의 반환타입으로 지정할 수 있다.

(반환타입의 인터페이스를 구현한 클래스의 인스턴스를 반환)

→  반환타입이 인터페이스다 → 이 인터페이스를 구현한 놈들(객체)을 반환하겠다는 뜻임

  메서드를 호출한 쪽에서는 반환타입과 일치하는 또는 자동형변환이 가능한 타입의 변수에 결과를 저장.

 

[이해를 돕기 위한 예제]

abstract class Unit {
	int x,y;
	abstract void move(int t, int y);			//추상메서드
	void stop() {System.out.println("멈춥니다.");}//인스턴스 메서드
}

interface Fightable { //인터페이스의 모든 메서드는 public abstract. 예외없이
	void move(int x, int y);  //public abstract가 생략됨
	void attack(Fightable f); //public abstract가 생략됨
}

class Fighter extends Unit implements Fightable {
	//오버라이딩 규칙: 조상(public)보다 접근제어자 범위가 좁으면 안된다.
	public void move(int x, int y) {
		System.out.println("["+x+","+y+"]로 이동");
	} 
	public void attack(Fightable f) {
		System.out.println(f+"를 공격");
	}
	
	//싸울 수 있는 상대를 불러오는 메서드
	Fightable getFightable() {
		Fighter f = new Fighter(); //Fighter를 생성해서 반환
		return (Fightable) f;	   //반환타입인 Fightable로 형변환
	}
}


public class FighterTest {
	public static void main(String[] args) {
		Fighter f = new Fighter();
		Fightable f2 = f.getFightable();
		
		
		
		Unit u = new Fighter(); 	 
		Fightable f1 = new Fighter(); //조상Fightable의 리모콘으로 자손Fighter객체 다룰 수 있음 
		u.move(100,200); 
		u.stop();
//		u.attack(new Fighter());     //Unit에는 attack()이 없어서 호출 불가	
		
		
		f1.move(100,200); 
//		f1.stop(); 		//fightable에는 stop()이 없어서 호출 불가
		f1.attack(new Fighter());  //아래 두문장을 한 문장으로 
		
//		Fighter f2 = new Fighter();
//		f.attack(f2);
	}

}

 

[인터페이스의 장점]

1.두 대상(객체)간의 연결, 대화, 소통을 돕는 중간 역할을 한다.

-인터페이스가 사용자와 컴퓨터사이의 윈도우(OS)의 역할을 함. (정확히는 GUI = Graphic Users Interface)

-인터페이스(껍데기)가 있으므로 변경에 유리하다.

{인터페이스 == 컴퓨터의 껍데기, 윈도우}

본체가 바뀌더라도 껍데기는 바꾸지 않아도 사용자에게는 아무런 영향X (변경에 유리)

 

2.선언(설계)과 구현을 분리시킬 수 있게 한다.

→ 변경에 유리, 유연한 코드

알맹이가 아무리 바뀌어도 껍데기가 그대로라 쓰는 데 문제X (느슨한 결합)

 

3. 변경에 유리한 유연한 설계가 가능하다.

 

4. 개발 시간을 단축할 수 있다.

 

5. 표준화가 가능하다.

ex) JDBC(인터페이스 집합)

 

A                                                     B

자바 애플리케이션 ---데이터요청 --→ 데이터베이스(오라클,MySQL)

A가 B에 의존한다.

 

A                                                     B

자바 애플리케이션 ----JDBC- --→ 데이터베이스(오라클,MySQL)

→ 표준화된JDBC(==인터페이스 집합)가 중간에 있으면 의존X

 

6. 서로 관계없는 클래스들을 관계를 맺어줄 수 있다.