코드스테이츠_국비교육/[Section1]

14_객체지향 프로그래밍 심화(추상화)_22.09.07

생각없이 해도 생각보다 좋다. 2022. 9. 7. 12:33

학습 키워드

  • 추상화
  • abstract 제어자
  • 추상 클래스
  • final 키워드
  • 인터페이스

추상화

>의미

: 기존 클래스들의 공통적인 요소를 뽑아 다른 클래스(상위 혹은 하위)를 만들어 내는 것.

 

>abstract 제어자

: 기타 제어자 중 하나

: 추상 클래스(abstract class) 혹은 추상 메서드(abstract method)를 만드는 제어자

>추상 메서드

: 메서드 시그니처만 있고, 바디가 없는 메서드

: 추상 메서드가 포함된 것의 객체를 생성하기 위해선, 무조건 추상 메서드의 바디를 정의하는 것이 선행되어야 한다.

>추상 클래스

: 하나 이상의 추상 메서드를 포함한 클래스

: 메서드 바디를 완성해야 객체 생성이 가능(구현)

>추상 클래스의 목적

  • 1. 유연한 하위 클래스의 생성

: 상위 클래스가 추상 클래스라면 선언부만 작성되어 있기 때문에 구체적인 내용을 하위 클래스에서 구현할 수 있다.

: 메서드 내용 중 일부 기능이 필요없어 질 수도 있는 상황을 없앨 수 있다.

  • 2. 오류 최소화

: 공통적인 속성에 대해서는 협업하는 모든 개발자가 같은 변수와 메서드를 사용할 수 있음.

: 다른 변수와 메서드를 사용하여 생길 수 있는 오류를 미연에 방지함.

>final 키워드

: 변수를 상수로 바꿔주는 키워드

: 메서드와 클래스에도 적용 가능

: 메서드와 클래스에 적용하면 상속, 오버라이딩 등 확장이 불가능해진다.

>추상 클래스 코드 예시

//abstract 제어자 : 추상 클래스라는 것을 의미
abstract class Animal {
	public String kind;
	public abstract void sound(); // 추상 메소드, 내용이 없음.
}

 


인터페이스

>의미

: 추상 메서드와 상수만으로 이루어진 집합체

: 추상 클래스와 비슷하지만 더 추상적임.

: 추상 클래스가 미완성 설계도라면, 인터페이스는 밑그림 스케치 정도.

>인터페이스 정의 조건

  • 1. class 위치에 interface로 작성하여 선언한다.

: 예시, public interface Name {...}

  • 2. 내부 필드는 모두 public static final로 정의한다.

: public, static, final 중 무엇을 생략하더라도 컴파일러가 자동으로 추가한다.

  • 3. 내부 메서드는 모두 public abstract로 정의한다.

: public, abstract 중 무엇을 생략하더라도 컴파일러가 자동으로 추가한다.

+ default, static 메서드도 추가할 수 있다. (개선된 부분)

>인터페이스 구현

: implements 키워드를 사용하여 인터페이스 바디를 정의하는 클래스를 따로 작성해야함.

: 인터페이스에 정의된 반드시 모든 추상메서드를 구현해야함.

: 구현은 사실 해당 클래스에서 인터페이스를 implements하여 메서드를 오버라이딩하는 것!

>인터페이스의 다중 구현

: implements A, B, C, ... 처럼 다중 구현이 가능함.

: 대신 구현해야할 모든 인터페이스의 모든 추상메서드를 정의해야함.

: 추상 클래스 상속+ 인터페이스 구현도 가능함.

>다중 상속이 불가능한 이유

: 부모 클래스는 필드와 메서드가 완성되어 있기 때문에 같은 필드나 메서드가 존재하는 경우 충돌이 발생함.

>다중 구현이 가능한 이유

: 인터페이스는 필드와 메서드가 모두 미완성형이기 때문에 충돌이 발생하지 않음.

>인터페이스의 특징 및 장점

  • 1. 인터페이스 참조형으로 구현한 클래스의 인스턴스를 생성할 수 있음.

: 상속관계에서 상위 클래스 참조형으로 하위 클래스의 인스턴스를 생성하는 꼴과 같음.

: 이는 상위 클래스 참조형으로 객체 다형성을 이용한 것처럼 똑같이 사용할 수 있음.

  • 2. 미완성된 인터페이스를 각각의 클래스에서 구현하기 때문에 독립적인 프로그래밍을 할 수 있다.

: return "A"; return "B"; 처럼 정해진 값을 반환하는 return을 사용하는 경우에도 각 클래스마다 다르게 반환값을 줄 수 있다.

// 뭔가 상속에서도 다 실행되는 기능들 같다. 그냥 인터페이스는 충돌없이 상속받는 꿀템 정도로 기억하는게 좋겠다.

>인터페이스의 코드 예시

public class Main {
    public static void main(String[] args) {
        PersonA p1 = new PersonA();
        PersonB p2 = new PersonB();
        p1.eat(); // 치킨 냠
        p1.name(); // 철수
        p2.eat(); // 국밥 냠
        p2.name(); // 영희
        Human[] arr = new Human[]{new PersonA(), new PersonB()};
        arr[0].name(); // 철수
        arr[1].name(); // 영희
        //.name()메소드만 호출 가능
        //Human 참조형이기 때문에.
        //상위 참조형으로 배열로 만드는 게 진짜 개꿀
    }
}
//인터페이스 1.
interface Animal {
    public abstract void eat();
}
//인터페이스 2.
interface Human {
    void name(); // public abstract 생략(자동 추가)
}
//인터페이스 1,2를 구현한 PersonA
class PersonA implements Animal, Human {
    public void eat() {
        System.out.println("치킨 냠");
    }
    public void name() {
        System.out.println("철수");
    }
}
//인터페이스 1,2를 구현한 PersonB
class PersonB implements Animal, Human {
    public void eat() {
        System.out.println("국밥 냠");
    }
    public void name() {
        System.out.println("영희");
    }