본문 바로가기
Study in Bootcamp/회고

Day 14 자바 JAVA 이론 (다형성, 추상화)

by Bhinney 2022. 7. 12.

2022.07.12

(본 페이지는 크롬 기준, 화면 크기를 80-90%로 보는 것이 좋습니다.)


1. 오늘의 학습

  • 다형성
  • 추상화
  • 인터페이스

2. 학습 내용

다형성(Polymorphism)

1) 다형성이란?
      • 일반적 ) polymorphism = poly(여러 개) + morphism(어떤 형체/ 실체)
                     --> 하나의 객체가 여러가지 형태를 가질 수 있다는 의미 
      • 자바 ) 한 타입의 참조 변수를 통해 여러 타입의 객체를 참조할 수 있는 것
                  상위 클래스의 참조 변수로 하위 클래스의 객체를 참조
                  오버 라이딩, 오버 로딩도 다형성의 한 예시
//다형성 예시

public class Test1 {
    public static void main(String[] args){
        Food food = new Food();
        Drink drink = new Drink();
        Food rice = new Rice(); /* >> 참조 변수 타입을 상위 클래스로 지정
                                ----> 사용할 수 있는 멤버의 개수 == 상위 클래스 멤버의 개수 */
/*       Rice rice = new Food(); >> "incompatible types" 즉, 호환되지 않는 에러 발생
                             (∵ 객체인 Food보다 참조변수 Rice의 멤버의 수가 더 많음) */

        food.FoodInfo();
        drink.FoodInfo();
        drink.DrinkInfo();
        rice.FoodInfo();
/*      rice.RiceInfo(); >> 참조 변수를 상위 클래스로 지정하였기에, 
	Food에는 없고, 하위 클래스인 Rice에만 있는 메서드는 사용할 수 없음. */
    }
}

class Food{
    public void FoodInfo(){
        System.out.println("음식");
    }
}

class Drink extends Food{
    public void DrinkInfo(){
        System.out.println("움료");
    }
}

class Rice extends Food{
    public void RiceInfo(){
        System.out.println("밥");
    }
}


2) 참조 변수의 타입 변환
     1️⃣ 서로 상속 관계에 있는 상위 클래스 - 하위 클래스 사이에서만 변환이 가능
     2️⃣ 하위 클래스에서 상위 클래스로 변환 시(업 캐스팅), 캐스팅 괄호 생략 가능
     3️⃣ 상위 클래스에서 하위 클래스로 변환 시(다운 캐스팅), 캐스팅 괄호 생략 불가능 — > 반드시 캐스팅 명시!!
// 참조 변수의 타입 변환 예시

public class Test2 {
    public static void main(String[] args){
        GalaxyBook galaxy = new GalaxyBook();
        
        Laptop laptop = (Laptop) galaxy; // 상위 클래스 타입으로 변환 + 캐스팅 생략 가능
        GalaxyBook galaxyBook = (GalaxyBook) laptop; // 하위 클래스 타입으로 변환 + 캐스팅 생략 불가능
/*       Gram gram = (Gram) galaxy; incompatible types(변환할 수 없는 타입) 에러
                     그램과 갤럭시북은 부모-자식의 상속관계가 아니기 때문에 캐스팅(변환) 불가 --> 에러 */
    }
}

class Laptop{
    String color;
    int size;

    void On(){
        System.out.println("노트북을 켭니다.");
    }
    void Update(){
        System.out.println("노트북 업데이트를 합니다.");
    }
}

class GalaxyBook extends Laptop{
    void from(){
        System.out.println("삼성 제품 입니다.");
    }
}

class Gram extends Laptop{
    void made(){
        System.out.println("엘지 제품 입니다.");
    }
}

class MacBook extends Laptop{
    void brand(){
        System.out.println("애플 제품 입니다.");
    }
}​

 

3) instanceof 
     •참조 변수의 타입 변환(캐스팅)이 가능한지의 여부를 boolean 타입으로 확인할 수 있는 요소
// instanceof 예시

public class Test3 {
    public static void main(String[] args){
        Country country = new Country();

        System.out.println(country instanceof Object);
        System.out.println(country instanceof Country);
        System.out.println(country instanceof Korea);
        System.out.println(country instanceof America);

        System.out.println("-------------------------------");

        Country korea = new Korea();// 참조 변수 타입을 상위 클래스로 지정

        System.out.println(korea instanceof Object);
        System.out.println(korea instanceof Country);
        System.out.println(korea instanceof Korea);
        
        System.out.println(korea instanceof America);
        // korea 의 참조 변수 타입이 Country 이기에 오류가 발생하지 않고 출력 가능

        System.out.println("-------------------------------");

        America america = new America();

        System.out.println(america instanceof Object);
        System.out.println(america instanceof Country);
/*    System.out.println(america instanceof Korea);
		>> america 의 인스턴스를 생성할 때 참조 변수를 America()로 했기에 오류 발생
           	Country()로 했어도 false 가 출력 되었을 것. */
        System.out.println(america instanceof America);	
    }
}

class Country{}

class Korea extends Country{}

class America extends Country{}

/* 출력
true >> Object 클래스는 최상위 클래스, 자바의 모든 클래스는 Object 클래스로부터 상속
	Day 13 상속 참조.
true
false >> Country는 Korea보다 상위 타입의 클래스 + 변환 불가
false >> Country는 America보다 상위 타입의 클래스 + 변환 불가
-------------------------------
true  >> Object 클래스는 최상위 클래스, 자바의 모든 클래스는 Object 클래스로부터 상속
true
true
false >> Korea는 America의 상속 클래스가 아니기 때문에 false + 변환 불가
-------------------------------
true  >> Object 클래스는 최상위 클래스, 자바의 모든 클래스는 Object 클래스로부터 상속
true
true
*/


4) 다형성 예제 >> 두 예시의 차이를 살펴볼 것
// 다형성 활용 예제 1

public class Test4 {
    public static void main(String[] args){
        Customer customer = new Customer();
        customer.buyPhone(new GalaxyS22());
        customer.buyPhone(new iPhone13());

        System.out.println("현재 잔액은 " + customer.money + "달러 입니다.");
    }
}

class Phone{
    int price;
    public Phone(int price){this.price = price;}
}

class GalaxyS22 extends Phone{
    public GalaxyS22() {
        super(1200);}
}

class iPhone13 extends Phone{
    public iPhone13() {
        super(1400);}
}

class Customer{
    int money = 5000;
    void buyPhone(GalaxyS22 galaxy){
        money = money - galaxy.price;
    }
    void buyPhone(iPhone13 iphone){
        money = money - iphone.price;
    }
}​
// 다형성 활용 예제 2

public class Test5 {
    public static void main(String[] args){
        Customer2 customer = new Customer2();
        customer.buyPhone2(new GalaxyS23());
        customer.buyPhone2(new iPhone14());

        System.out.println("현재 잔액은 " + customer.money + "달러 입니다.");
    }
}

class Phone2{
    int price;
    public Phone2(int price){this.price = price;}
}

class GalaxyS23 extends Phone2{
    public GalaxyS23() {
        super(1200);}
}

class iPhone14 extends Phone2{
    public iPhone14() {
        super(1400);}
}

class Customer2{
    int money = 5000;
    void buyPhone2(Phone2 phone){ /* buyPhone2()으로 Phone2 타입 전달.
    			    	  상위 클래스인 Phone 으로 하위 클래스를 참조하면, 
    				  반복되는 코드를 줄일 수 있음 */
        if(money < phone.price){
            System.out.println("잔액이 부족합니다.");
            return;}
        money = money - phone.price;}
}


추상화(Abstraction)

1) 추상화란
     • 추상 : 사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것
     • 자바 ) 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
                  기존 클래스들의 공통적인 요소들을 뽑아서 상위클래스를 만들어 내는 것
                  방법에 있어서 상향과 하향이 상관이 없음

2) 추상 클래스와 추상 메서드
     • abstract 제어자 사용
     • 추상 메서드
           • 메서드의 시그니처만 존재 (바디는 없음)
           • abstract를 붙여 추상 메서드임을 나타냄 (예 : abstract void)
           • 미완성 메서드
     • 추상 클래스
           • 클래스 앞에 붙음추상 메서드를 1개 이상 가지고 있는 클래스
           • 메서드가 미완성이므로 메서드의 바디가 완성될 때까지 인스턴스 생성 불가능
     • 사용 이유
           1️⃣ 상속 관계에 있어 새로운 클래스를 생성하는 데 유용
                >> 상속을 받는 하위 클래스에서 메서드 오버라이딩이 유용해 상황에 맞는 메서드 구현 가능
           2️⃣ 추상화를 구현하는 데 핵심적
// 추상 메서드, 추상 클래스 예시

public class Example1 {
    public static void main(String[] args){
        Korean korean = new Korean();
        Person british = new British(); // 참조 타입을 상위 클래스로
/*      Person person = new Person(); >> 에러, 추상 클래스는 인스턴스 생성 불가.
         java: Person is abstract; cannot be instantiated */

        System.out.print(korean.from + ": ");
        korean.greeting();
        System.out.print(british.from + ": ");
        british.greeting(); // >> 상위 클래스에도 greeting 메서드가 있기에 출력 가능

    }
}

abstract class Person{ //추상 클래스 : 추상 메서드를 1개 이상 가지고 있는 클래스
    public String from;

    public abstract void greeting(); // 추상 메서드 >> 바디는 미완성이고, 메서드 시그니처만 존재
}

class Korean extends Person{
    public Korean(){this.from = "한국";}

    public void greeting(){
        System.out.println("안녕하세요.");
    }
}

class British extends Person{
    public British(){this.from = "영국";}

    public void greeting(){
        System.out.println("HELLO.");
    }
}

/* 출력
한국: 안녕하세요.
영국: HELLO.
*/​
인터페이스(Interface)

1) 인터페이스란
     • inter-(사이) + face(얼굴 / 면) = 두 개의 대상을 결합한다는 뜻
     • 프로그래밍  ) 서로 다른 두 시스템, 장치, 소프트웨어를 연결해주는 부분 혹은 그런 장치
                            예 : GUI (Window, Mac OS 등)

2) 자바에서 인터페이스 ❗️
     • like 밑그림
     • 추상 메서드와 상수만을 멤버로 가질 수 있다는 점에서 추상 클래스에 비해 추상화 정도가 더 높음
     • 추상 메서드의 집합
     •내부의 모든 필드가 public static final로 정의
     • static과 default메서드 이외의 모든 메서드가 public abstract로 정의

3) 인터페이스 구현
     • 인스턴스 생성 불가 >> 메서드의 바디를 정의하는 클래스를 따로 작성해야 함
     • 어떤 클래스가 인터페이스를 구현한다는 것
             • 그 클래스에 정의된 모든 추상메서드를 구현해야 함
             • 그 클래스에게 인터페이스의 추상 메서드를 반드시 구현하도록 강제하는 것을 의미
             • 모든 추상 메서드들을 해당 클래스 내에서 오버라이딩하여 바디를 완성한다라는 의미
4) 인터페이스의 다중 구현
     • 인터페이스는 다중적 구현 가능
       (cf : 일반적 클래스는 다중 상속 불가. 하위 클래스는 하나의 상위 클래스만 상속)
     • 인터페이스는 인터페이스로부터만 상속 가능
     • Object와 같은 최고 조상 클래스는 존재하지 않음
     • 이유?
            • 일반적인 클래스는 만약 부모 클래스에 동일한 이름의 필드 또는 메서드가 존재하는 경우 충돌이 발생하기 때문에 불가능
            • 애초에 미완성된 멤버를 가지고 있기 때문에 충돌이 발생 ❌ —> 안전하게 다중 구현이 가능

// 인터페이스 다중 구현 예시

public class Example2 {
    public static void main(String[] args){
        American american = new American();
        Italian italian = new Italian();

        american.language();
        american.greeting();

        italian.language();
        italian.greeting();
    }
}

abstract class  Human{
//interface Human{
    public abstract void greeting();
}


interface Nation{
    void language();
}

class American extends Human implements Nation{
//class American implements Human,Nation{
    public void greeting(){
        System.out.println("HELLO");
    }

    public void language(){
        System.out.println("ENGLISH");
    }
}

class Italian extends Human implements Nation{
//class Italian implements Human, Nation{
    public void greeting(){
        System.out.println("BOUNGIORNO");
    }

    public void language(){
        System.out.println("ITALIANO");
    }
}​​

 

 

 


3. 돌아보기

평소보다 이해하는 데 시간이 굉장히 오래 걸렸다. 아니 인터페이스는 진짜 거의 이해가 안되는 수준이었다. 그래서 끝나고도 다시 코드를 써보며 흐름을 읽으려고 하였다. 사실 완벽히 이해하고 설명하기에는 아직 자신이 없다. 그렇지만 복습을 하다보니 처음보다는 어떤 흐름으로 흘러가는 것인지, 어떻게 써야 하는지, 쓰여진 이유가 무엇인지 조금은 이해할 수 있었다. 진짜 이 개념들을 지금 모르고 넘어가면 나중에 엄청 헷갈릴거 같아서 여러번 복습하고 찾아보는데, 아직 모자란게 느껴진다. 아직 갈길이 9만리 인 듯.. 더 찾아보고, 더 알아보자. 내일 블로깅 시간이 있으니, 블로그를 정리하고, 복습하고, 더 알아보는데 열심히 해보자.

 

지금까지 배운 것들을 어떻게 하면 효율적이고 내가 나중에도 참고할 수 있도록 정리할 수 있을지 아직 고민이다. 노션으로 여러 방법을 시도 중인데, 아직도 100프로 최고의 상태라고 하기에는 어려움이 있다. 내용을 정리해 둔 것들을 다시 보며, 어떻게 해야 내가 효과적으로 정리할 수 있을 지 고민해봐야 할 것 같다.

 

 

 

 

 

 

 

댓글