본문 바로가기

diary/codestates (be39)

05/13/22 java/ 다형성과 추상화

다형성 polymorphism

하나의 객체가 여러가지 형태를 가질 수 있는 것 “여러가지의 형태”
한 타입의 참조 변수를 통해 여러 타입의 객체를 참조할 수 있도록 하는 것 > 무슨 말?
상위 클래스 타입의 참조 변수를 통해 하위 클래스의 객체를 참조
*** 참조 변수가 사용할 수 있는 멤버의 개수는 실제 객체의 멤버 개수보다 같거나 적어야 한다

** 상위 클래스의 타입으로 하위 클래스 타입의 객체를 참조할 수 있지만, 반대는 불가능

→ 상위 클래스의 실제 객체 멤버 개수보다 하위 클래스의 참조 변수가 사용할 수 있는 멤버 개수가 더 많을 수 있기 때문에

???? 어려워요 왜요

*** 코드의 중복을 줄여 편리함 + 효과적으로 프로그래밍 수행하기
메서드 오버라이딩, 메서드 오버로딩 > 다형성! : 같은 이름의 메서드를 덮어쓰거나 다양하게 사용함으로써 매번 다른 이름의 메서드 명을 만드는 데 시간을 사용하지 않을 수 있고, 비슷한 보일러플레이트 코드(반복적으로 사용하는 비슷한 코드)를 최소화할 수 있다.


참조 변수의 타입 변환

사용할 수 있는 멤버의 개수를 조절하는 것

  1. 서로 상속 관계에 있는 상위-하위 클래스 사이에서만 타입 변환이 가능하다
  2. 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환(upcasting)은 형 변환 연산자를 생략할 수 있다 → 자동 타입 변환하위 클래스는 언제나 상위 클래스의 모든 멤버를 가지고 있다. 따라서, 하위 클래스의 객체를 참조하게 되면, 상위 클래스는 자신의 모든 멤버를 사용할 수 있다. 손실이 없다.상위 클래스에서 하위 클래스 타입으로의 타입 변환(downcasting)은 형 변환 연산자를 반드시 명시해야 한다 → 수동 타입 변환하위 클래스 타입에서 상위 클래스의 인스턴스를 참조할 경우 손실이 생긴다. 명시하자.

** 상속 관계에 있는 클래스 간에는 상호 타입 변환이 자유롭게 수행될 수 있다.

instanceof 연산자

참조 변수의 타입 변환(casting)이 가능한지 확인한다. boolean 타입으로, 타입 변환이 가능하면 true, 불가능하면 false를 반환한다.

참조변수 instanceof 클래스타입

 


추상화 Abstraction

추상” 사물이나 표상을 어떤 성질, 공통성, 본질에 착안하여 그것을 추출하여 파악하는 것
*공통성과 본질을 모아 추출하는 것
추상화: 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
상속은 하위 클래스를 정의하기 위해 상위 클래스를 사용했다
추상화는 반대로 기존 클래스들의 공통적인 요소들을 뽑아 상위 클래스를 만들어내는 것
상향식과 하향식 설계 모두 크게 상관없다.
공통적인 속성과 기능을 정의하고 하위 클래스들을 생성할 수도 있고(상속), 하위 클래스들의 공통성을 모아 상위 클래스를 정의(추상화)할 수 있다.
공통적인 속성 → 코드의 중복을 줄이고, 효과적으로 클래스 간의 관계를 설정, 유지보수가 용이


abstract 제어자

자바의 맥락에서 abstract 는 ‘미완성’을 의미한다고 볼 수 있다.
클래스와 메서드를 형용하는 키워드로 사용되어서, abstract method; 추상 메서드, abstract class; 추상 클래스 라고 부른다.
어떤 클래스에 추상 메서드가 포함되어 있는 경우, 해당 클래스는 자동으로 추상 클래스가 된다.

abstract class AbstractExample { //추상 메서드를 최소 한 개 이상 포함한 추상 클래스
	abstract void start(); //메서드 바디가 없는** 추상 메서드
}

“미완성”

추상 메서드: 메서드의 시그니처만 있고 바디가 없는 메서드
abstract를 메서드 이름 앞에 붙여 해당 메서드가 추상 메서드임을 명시한다
‘충분히 구체적이지 않다’ 뭐가 없다~~~
추상 메서드는 충분히 구체화되지 않은 미완성 메서드이며, 미완성 메서드를 포함하는 클래스는 당연히 미완성 클래스가 된다.
추상 클래스는 미완성된 클래스이기 때문에, 메서드 바디를 완성하기 전까지는 클래스의 인스턴스를 생성할 수 없다.
왜 사용할까?
abstract 붙어 있으면 반드시 완성해야 함 그래야 구현됨


추상 클래스

추상 클래스는 메서드 바디가 없는 추상 메서드, 즉 미완성 메서드를 포함하고 있어 외부에서 접근해 객체를 생성할 수 없다. 그런데 왜 사용하는 걸까욤?

1. 추상 클래스는 상속 관계에 있어서, 새로운 클래스를 작성하는 데 매우 유용하다.

  • 메서드의 내용이 상속을 받는 클래스에 따라서 달라지는 경우가 있기 때문에 상위 클래스에서는 선언부만을 작성하고, 실제 구체적인 내용은 상속을 받는 하위 클래스에서 구현하도록 비워둔다면 설계하는 상황이 변하더라도 보다 유연하게 대처할 수 있게 된다. → 오버라이딩
    • 오버라이딩을 통해 추상 클래스로부터 상속받은 추상 메서드의 내용을 구현해 메서드를 완성시키고, 클래스를 완성시켜 객체를 생성하게 한다.
  • 추상 클래스를 사용하면 상속을 받는 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드 구현이 가능하다

 

2. 추상화 구현의 핵심

  • 추상화: 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
    • eg) 동물이 가지는 공통적인 속성을 모아 추상 클래스로 선언 → 상속받아 하위 클래스에서 메서드 오버라이딩을 통해 클래스의 구체적인 내용을 결정한다.
    • 협업 시, 공통된 속성과 기능임에도 각각 다른 변수와 메서드로 정의되는 경우의 오류를 방지한다 → 어떻게? → 추상 클래스로 미리 선언해줬으니까! 앞으로 어떤 내용을 작성할지 몰라도, 일단 선언하고 묶어줬으므로 다르게 정의되는 일은 없다. 또한 정의만 미리 해놓은 것이므로 각각 구현될 기능에 따라 내용을 다르게 작성하는 것이 가능하므로 유용하다.


추상화 ↔ 구체화
상속 계층도의 상층부에 위치할수록 추상화의 정도가 높고, 아래로 내려갈수록 구체화된다.
다른 말로, 상층부에 가까울수록 더 공통적인 속성과 기능들이 정의되어 있다


final 제어자

필드, 지역 변수, 클래스 앞에 위치할 수 있으며, 위치에 따라 의미가 조금씩 달라진다.

  • final 클래스: 변경 또는 확장이 불가능한 클래스로 상속이 불가능하다
  • final 메서드: 오버라이딩을 할 수 없다
  • final 변수: 값 변경이 불가능하다

→ 공통적으로, final 제어자가 추가되면 해당 대상은 변경이 불가능하거나 확장될 수 없는 성질을 가진다.


인터페이스

사전적 의미) 서로 다른 두 시스템, 장치, 소프트웨어 따위를 서로 이어주는 부분 또는 그런 접속 장치
→ 어떤 두 대상 간의 연결 내지 소통을 돕는 중간 다리 역할을 수행
객체 지향의 추상화를 구현한다는 점에서 추상 클래스와 비슷한 역할을 하지만, 추상클래스보다 더 높은 추상성을 지닌다.

  • 추상 클래스: 메서드 바디가 없는 추상 메서드와 멤버 변수를 포함한다
    • 멤버 변수 ㅠ ㅠ 포함 예시 보여줘요 ㅠ ㅠ
  • 인터페이스: “ONLY 추상 메서드 + 상수” 다른 어떤 요소도 포함될 수 없다. 가장 기초적인 밑그림

 


인터페이스의 구조

  • 작성: class 대신 interface
  • 내부의 모든 필드는 public static final
  • staticdefault 메서드 외의 모든 메서드는 public abstract
    • 모든 인터페이스의 필드와 메서드는 위의 요소를 내포하므로 생략이 가능하다 //??? ㅠㅠ 

구현부가 완성되지 않은 추상 메서드와 상수

review)

 

[Java] static, final, static final의 차이

static = 고정된 final = 최종적인 final static = 상수? 이론을 공부하면서 세 가지 개념에 대해 모호했던 기억이 있다. 이번에 학습한 내용을 바탕으로 정리하였다. 1. Static static은 "고정된" 이라는 의미

gobae.tistory.com

  • static

객체 생성 없이 사용 가능한 필드와 메소드 생성 시
공용 데이터 / 인스턴스 필드를 포함하지 않는 메서드 선언에 사용

  • final

한번 저장되면 최종적인 값이 되어 수정이 불가능하다

  • static final

상수!!!!!!! 모든 영역에서 고정된 값으로 사용한다.


인터페이스의 구현

어떤 클래스가 어떤 인터페이스를 구현한다? = 인터페이스가 가진 모든 추상 메서드를 해당 클래스 내에서 모두 오버라이딩해 구현한다

  • 인터페이스를 구현하는 클래스 만들기
class ExampleClass implements ExampleInterface {...}
class ExampleClass implements ExampleInterface, ExampleInterface2, ExampleInterface3 {...}

하나의 클래스가 여러 개의 인터페이스를 구현하는 것이 가능하다!

다중 상속은 막으면서, 인터페이스 여러 개를 구현하는 게 가능한 이유는?

  • 상위 클래스를 여러 개 상속 받으면 무슨 문제점이 생길까? 상속 받은 상위 클래스끼리 동일한 이름의 필드나 메서드가 존재할 경우에 충돌이 발생한다!
  • 인터페이스는 모든 멤버가 미완성이다. (추상적이다)
    • 추상 클래스는 추상 메서드를 포함하는 클래스이다.
    • 반면 인터페이스는 모든 멤버가 상수와(<절대 변할 수 없다) 추상 메서드로 구성되므로 중복될 일이 전혀 존재하지 않으므로 다중 구현을 허용한다.
    • 포함 vs 모든 의 차이로 이해하면 될 것 같다! 인터페이스가 훠얼씬 미완성임(추상적임)

 


🐑 Daily 회고

더보기

1. 금주 실패

  • 금연도요
  • 그런 이유로 오늘은 노션 그대로 복붙

2. 그래도 자책하지 맙시다

  • 구박받을수록 삐뚤어지는 타입
  • 내일은 내일의 해가 뜨겠죠 하루 놀았다고 죽는 거 아니다 쉬고 다시 열심히 해서 나아갑니다 총총총총

2. 이 와중에 티스토리 어렵다

  • 백업을.... ^^ 생활화하자

총평