[JAVA] OOP 3 - 다형성 / 추상화

zirryo·2022년 7월 12일
0

⚡️ STUDY

목록 보기
7/15
post-thumbnail
week 3 / 22.07.12

Polymorphism

💿 다형성

하나의 객체가 여러 가지 형태를 가질 수 있는 성질

자바에서의 다형성

  • 한 타입의 참조변수를 통해 여러 타입의 객체를 참조할 수 있도록 하는 것.
  • 상위 클래스 타입의 참조변수를 통해 하위 클래스 객체를 참조할 수 있도록 허용. (상속관계 전제)
    class Subject {
        public void info() {
            System.out.println("이번 시간은");
        }
    }
    class Music extends Subject { 
        public void info() {
            System.out.println("음악입니다");
        }
    }
    class Art extends Subject {
        public void info() {
            System.out.println("미술입니다");
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Subject subject = new Subject(); // 객체 타입과 참조변수 타입의 일치
            Music music = new Music(); // 객체 타입과 참소변수 타입 일치
            Subject art = new Art(); // 객체 타입과 참조변수 타입의 불일치
    
            subject.info();  // 이번 시간은
            music.info();   // 음악입니다
            art.info();    // 미술입니다
        }
    }

    art의 참조변수 타입을 Subject(상위 클래스)로 지정.
    art 참조변수가 사용할 수 있는 멤버의 수는 상위클래스의 멤버의 수가 됨.

    // Art sub1 = new Subject(); 
       객체 타입과 참조변수 타입의 불일치

    하위 클래스 타입으로 상위 클래스 객체 참조 불가


  • 참조 변수 타입 변환 == 사용할 수 있는 멤버의 개수 조절
    1. 서로 상속관계에 있는 상위 클래스
    : 하위 클래스 사이에만 타입 변환 가능.
    2. 업캐스팅 / 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환
    : 형변환 연산자(괄호) 생략 가능.
    3. 다운캐스팅 / 상위 클래스에서 하위 클래스 타입으로 변환
    : 형변환 연산자(괄호) 생략 불가능.

  • instanceof 연산자
    • 캐스팅이 가능한 지 여부를 boolean 타입으로 확인하는 문법 요소.
    • 일일이 생성 객체의 타입을 확인하기 어려울 때 연산자를 사용하여 형변환 여부를 확인할 수 있으며, 이를 통해 에러를 줄일 수 있음.
      참조변수 instanceof 타입   
    • true : 참조변수를 해당 타입으로 변환 가능
    • false : 참조변수를 해당 타입으로 변환 불가, 참조변수==null 인 경우
      public class InstanceOfExample {
          public static void main(String[] args) {
              Book book = new Book();
              System.out.println(book instanceof Object); //true
              System.out.println(book instanceof Book); //true
              System.out.println(book instanceof Novel); //false
              System.out.println(book instanceof Essay); //false
      
              Book novel = new Novel(); // 객체타입 Novel, 참조타입 Book 
              System.out.println(novel instanceof Object); //true
              System.out.println(novel instanceof Book); //true
              System.out.println(novel instanceof Novel); //true
              System.out.println(novel instanceof Essay); //false
          }
      }
      
      class Book {};
      class Novel extends Book{};
      class Essay extends Book{};




Abstraction

📀 추상화

기존 클래스들의 공통적인 요소들을 추출하여 상위클래스를 만드는 것
상속계층도의 상층부의 위치할 수록 추상화의 정도가 높고, 내려갈수록 구체화.

  • abstract 제어자
    자바의 기타 제어자 중 한 종류. 자바에서 '미완성'의 의미로 사용됨.
    클래스와 메서드의 형용 키워드로 사용되며, 추상 메서드가 포함된 클래스는 자동으로 추상 클래스가 됨.
    abstract class AbExample { // 추상 메서드가 최소 하나 이상 포함돼있는 추상 클래스
    	abstract void start(); // 메서드 바디가 없는 추상메서드
    }

  • 추상 메서드
    • 메서드의 시그니처만 있고 바디가 없는 메서드, 즉 미완성 메서드. 메서드 앞에 abstract 키워드를 붙여서 표시.
  • 추상 클래스 : 미완성의 설계도이기 때문에 메서드 바디가 완성되기 전까지 해당 클래스를 기반으로 객체 생성 불가능
    • 클래스 앞에 abstract 키워드를 붙여서 표시.
    • 상속 관계에 있어 새로운 클래스를 작성하기 유용함.
    • 추상화를 구현하는 핵심 요소.
    • 추상 클래스를 상속받는 경우 반드시 모든 추상 메서드를 오버라이딩 해야 함.
      AbExample ab = new AbExample(); // 추상 클래스로 객체 생성 불가능

  • final 키워드
    • 클래스 : 변경 or 확장 불가능 클래스, 상속 불가
    • 메서드 : 오버라이딩 불가
    • 변수 : 값 변경 불가




📀 인터페이스

추상 클래스보다 높은 추상성을 가지는 '밑그림'
기본적으로 추상 메서드와 상수만을 멤버로 가질 수 있다.

인터페이스의 기본 구조

  • class 대신 interface 키워드를 사용함.
  • 내부의 모든 필드를 public static final로 선언함.
  • staticdefault 메서드 이외의 모든 메서드는 public abstract.
  • 모든 인터페이스 필드와 메서드에는 위의 두가지 요소가 내포되어 있기 때문에 조건을 명시하지 않고 생략하는 것도 가능함. (컴파일러 자동 추가)
    public interface InterfaceEx {
        public static final int breakfast =  8; // 인터페이스 인스턴스 변수 정의
        final int lunch = 12; // public static 생략
        static int dinner = 19; // public & final 생략
    	void eat(); //public abstract 생략 
    }

인터페이스의 구현

  • implements 키워드를 사용함.
  • 추상클래스와 같이 그 자체로 인스턴스를 생성할 수 없음.
  • 특정 인터페이스를 구현한 클래스는 해당 클래스 내부에서 인터페이스의 모든 추상 메서드를 오버라이딩하여 바디를 완성해야 함.
    class 클래스명 implements 인터페이스명 {
    		... // 인터페이스에 정의된 모든 추상메서드 구현
    }

인터페이스의 다중 구현

  • 클래스 간의 상속은 다중 상속이 허용되지 않으나, 인터페이스는 다중적 구현 가능.
  • 즉, 하나의 클래스가 여러개의 인터페이스를 구현 가능.
  • 특정 클래스는 상속을 받으면서 동시에 인터페이스 구현 가능.
  • 인터페이스는 인터페이스로부터의 상속만 허용되며, 클래스의 Object와 같은 최고 조상은 존재하지 않음.
    class Exclass implements Inter1, Inter2, Inter3 {
                         ......
    }                                    // 다중 구현 문법
  • 다중 구현 예시 코드
    interface Book { // 인터페이스 선언. public abstract 생략 가능.
    	public abstract void read();
    } 
    interface BookStore {
    	void buy();
    }
    class Novel implements Book, BookStore { // 인터페이스 다중 구현
        public void read(){ // 메서드 오버라이딩
            System.out.println("소설 읽기"); 
        }
        public void buy(){ // 메서드 오버라이딩
            System.out.println("소설 구입하기");
        }
    }
    
    class Cartoon implements Book, BookStore { // 인터페이스 다중 구현
        public void read(){
            System.out.println("만화 읽기");
        }
        public void buy(){
            System.out.println("만화 구입하기");
        }
    }
    
    public class MultiInheritance {
        public static void main(String[] args) {
            Novel novel = new Novel();
            Cartoon cartoon = new Cartoon();
    
            novel.read();    // 소설 읽기
            novel.buy();     // 소설 구입하기
            cartoon.read();  // 만화 읽기
            cartoon.buy();   // 만화 구입하기
        }
    }

  • 추상 클래스 상속 & 인터페이스 구현 예시 코드
    abstract class Book { // 추상 클래스
    	public abstract void read();
    } 
    interface Bookstore { // 인터페이스
    	public abstract void buy();
    }
    
    class Novel extends Book implements Bookstore { // Book클래스 상속 & Bookstore 인터페이스 구현
        public void read(){
            System.out.println("소설을 읽음");
        }
    
        public void buy(){
            System.out.println("소설을 구입함");
        }
    }
    
    class Essay extends Book implements Bookstore { // Book클래스 상속 & Bookstore 인터페이스 구현
        public void read(){
            System.out.println("에세이를 읽음");
        }
        public void buy(){
            System.out.println("에세이를 구입함");
        }
    }
    
    public class MultiInheritance {
        public static void main(String[] args) {
            Novel nov = new Novel();
            Essay ess = new Essay();
    
            nov.read();  // 소설을 읽음
            nov.buy();   // 소설을 구입함
            ess.read();  // 에세이를 읽음
            ess.buy();   // 에세이를 구입함
        }
    }

인터페이스의 장점

  • 역할과 구현을 분리시켜서, 복잡한 내용의 구현 or 변경과 상관없이 해당 기능 사용 가능
  • 코드 변경의 번거로움 최소화, 손쉽게 특정 기능 사용 가능.
  • 독립적인 프로그래밍을 통해 각각의 클래스들이 다른 클래스에게 주는 영향을 줄임.

0개의 댓글