본문 바로가기

개발지/Today I learn

[0731] 자바 객체지향 프로그래밍 심화 (추상화)

#추상화

- 핵심은 공통성과 본질을 모아 추출하는 것.

- 객체의 공통적인 속성과 기능을 추출하여 정의하는 것을 의미한다.

- 기존 클래스들의 공통적인 요소들을 뽑아서 상위 클래스를 만들어 내는 것.

- 추상 클래스와 인터페이스 문법 요소를 사용해서 추상화를 구현한다

 

#abstract 제어자

- 클래스와 메서드 앞에 붙여 사용한다. 제어자를 사용하면 각각 추상 메서드, 추상 클래스가 된다.

- 추상 메서드, 추상 클래스는 미완성 메서드, 미완성 클래스라고 하며, 바디가 완성되기 전까지 객체 생성이 불가능하다.

 

#추상 클래스

- 메서드 시그니처만 존재하고 바디가 선언되어 있지 않은 추상 메서드를 포함한 미완성 클래스.

- 객체 생성 불가능

- 상속 관계에 있는 새로운 클래스를 작성하는 데 유용하다.

  상위 클래스에서는 선언부만 작성하고, 상속을 받는 하위 클래스에서 구현하는 방식으로 이용한다.

  이 때, 오버라이딩을 사용해 추상 클래스로부터 상속받은 추상 메서드를 구현하여 메서드를 완성시킨다.

abstract class Animal {
	public String kind;
	public abstract void sound();
	}
    
class Dolphin extends Animal { // 추상 클래스 Animal 클래스로부터 상속
	public Dolphin() {
		this.kind = "포유류";
	}
    
    pbulic void sound() { // 메서드 오버라이딩 -> 구현부 완성
		System.out.println("끼오오");
	}
}

class Tiger extends Animal { // 상속
	public Tiger() {
		this.kind = "포유류";
	}
    
	public void sound() {
		System.out.println("어흥!");	
	}
}

class AnimalExample {
	public static void main(String[] args) throws Exception {
		Animal dolphin = new Dolphin();
        dolphin.sound();
        
        Tiger tiger  = new Tiger();
        tiger.sound();
	}
}

// 출력값
끼오오
어흥!

 

- 추상 클래스와 오버라이딩을 통해 객체의 특징에 맞는 메서드 구현 가능

- 상속계층도에서 상층부의 클래스일수록 추상화의 정도가 높고 아래로 내려갈수록 구체화됨

 

#final 키워드

- 필드, 지역 변수, 클래스 앞에서 사용 가능.

(1) 필드: 변경 또는 확장 불가능한 클래스, 상속 불가

(2) 메서드: 오버라이딩 불가

(3) 변수: 값 변경이 불가한 상수

-> 파이널 사용 시 변경이 불가하거나 확장되지 않는 성질이 생김

 

#인터페이스

- 추상 클래스보다 더 높은 추상성을 가짐.

- 추상 메서드와 상수만을 멤버로 가질 수 있음.

- 기본 구조

  ▪ class 키워드 대신 interface 키워드 사용.

  ▪ 내부의 모든 필드가 public static final로 정의됨

- 인터페이스는 추상 클래스와 마찬가지로 객체 생성 불가능, 메서드 바디 정의하는 클래스 작성 필요

- 이 때 상속은 extends 키워드가 아닌 implements 키워드를 통해 이뤄진다.

- 인터페이스를 구현(implements)한 클래스는 해당 인터페이스에 정의된 모든 추상메서드를 구현해야 한다.

  즉 인터페이스의 구현 클래스는 반드시 인터페이스의 추상 메서드를 구현해야한다.

  (모든 추상 메서드들을 오버라이딩하여 바디 완성)

 

- 인터페이스 클래스는 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있음. (일반 클래스는 다중 상속 금지)

class ExampleClass implemets ExampleInterface1, ExampleInterface2, ExampleInterface3 {
	...
}

- 인터페이스는 인터페이스로부터만 상속 가능. 

interface Animal { // 인터페이스 선언. public abstract 생략 가능.
	public abstract void cry();
}

interface Pet {
	void play();
}

class Hamster implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
	public void cry() { // 메서드 오버라이딩
		System.out.println("찍찍!");
	}
    
    public void play(){ // 메서드 오버라이딩
		System.out.println("휠 굴리기~");
	}
}

class Parrot implements Animal, Pet { // Animal과 Pet 인터페이스 다중 구현
	public void cry() {
		System.out.println("안녕!");
	}
    
    public void play(){
		System.out.println("반가워 주인");
	}
}

public class MultiInheritance {
	public static void ain(String[] args) {
		Hamster hamster = new Hamster();
        Parrot parrot = new parrot();
        
        hamster.cry();
        parrot.cry();
        hamster.play();
        parrot.play();
	}
}

//출력값
찍찍!
안녕!
휠 굴리기~
반가워 주인

-인터페이스를 사용하는 이유

(1) 역할과 기능이 분리되어 있어, 변동사항이 생기더라도 해당 기능을 사용할 수 있음.

(2) 코드 변경의 번거로움을 최소화한다.

(3) 선언과 구현을 분리시켜 개발시간을 단축화.