11. 객체지향프로그래밍의 이해 / 20230426
🧑🏻💻 TIL(Today I Learned)
객체지향 프로그래밍에서 핵심을 담당하는 네 가지 중 두 가지 "다형성과 추상화"
1. 다형성(Polymorphsim)
➡️ 하나의 객체가 여러 가지 형태를 가질 수 있는 성질
➡️ 상위 클래스 타입 참조 변수로 하위 클래스 타입 객체를 다루는 것
즉 상위 클래스 타입의 참조 변수를 통해서 하위 클래스의 객체를 참조할 수 있도록 허용한 것
➡️ 하위 클래스의 참조 변수로 상위 클래스 타입의 객체를 가리킬 수 없음
class Tv {
}
class SmartTv extends Tv {
}
Tv t = new Tv();
SmartTv s = new SmartTv(); // 원래는 이렇게 타입이 일치해야함
Tv t = new SmartTv();
// 다형성에서는 타입불일치도 오케이
// 부모 클래스의 참조 변수로 자식 클래스 객체 다루는 것
// 참조변수가 사용할 수 있는 멤버의 개수는 상위 클래스의 멤버의 수 --> 사용할 수 있는 멤버가 줄어든다
📍 객체와 참조변수 타입이 일치할 때와 일치하지 않을 때의 차이?
- 타입이 일치하지 않는 경우 참조 변수가 사용할 수 있는 멤버의 개수는 상위 클래스의 멤버의 수로 제한된다.
- > 서로 사용할 수 있는 멤버의 수가 달라짐
🔎 참조 변수의 타입 변환
➡️ 사용할 수 있는 멤버의 개수를 조절하는 것
➡️ 조건
- 서로 상속 관계에 있는 상속 클래스 - 하위 클래스 사이에서만 타입 변환 가능
- 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환(업캐스팅)은 형변환 연산자(괄호) 생략 가능
- 상위 클래스에서 하위 클래스 타입으로 변환(다운캐스팅)은 형변환 연산자(괄호) 반드시 명시해야 함
→ 다운 캐스팅은 업 캐스팅이 되어 있는 참조 변수에 한해서만 가능
⭐️ 형변환을 하는 것은 좋지만 실제 인스턴스가 무엇인지 확인해야 함 그 인스턴스 수가 넘어가면 에러가 남! ⭐️
🔎 instanceof 연산자
➡️ 참조 변수의 타입 변환 즉, 캐스팅이 가능한지 여부를 boolean 타입으로 확인할 수 있는 것(가능하면 true 반환)
→ 형변환 전에 반드시 확인해야 함!
➡️ 캐스팅 가능 여부를 판단하기 위해서는
- 객체를 어떤 생성자로 만들었는가
- 클랫 사이에 상속 관계가 존재하는가
참조_변수 instanceof 타입
// 결과값이 true : 참조 변수가 검사한 타입으로 타입 변환 가능
// 결과값이 false : 타입 변환 불가능
// 참조변수가 null 인 경우 : false 반환
➡️ 코드 규모가 커지면 확인하기가 어려우니 instanceof 연산자 제공함
🔎 매개변수의 다형성
➡️ 참조형 매개변수는 메서드 호출시 자신과 같은 타입 또는 자손 타입의 인스턴스를 넘겨줄 수 있음
➡️ 다형성의 장점
- 다형적 매개 변수
- 하나의 배열로 여러 종류 객체 다루기
public class PolymorphismEx {
public static void main(String[] args) {
Customer customer = new Customer();
customer.buyCoffee(new Americano()); // 매개변수 호출시 하위 타입의 인스턴스 넣어주기
customer.buyCoffee(new CaffeLatte());
System.out.println("현재 잔액은 " + customer.money + "원 입니다.");
}
}
2. 추상화(Abstract)
➡️ 자바에서 추상화는 객체의 공통적인 속성과 기능을 추출하여 정의하는 것
➡️ 기존 클래스들의 공통적인 요소를 뽑아서 상위 클래스를 만들어내는 것
➡️ 코드의 중복을 줄이고 효과적으로 클래스 간의 관계 설정 가능, 유지보수 용이
➡️ ⭐️추상 클래스와 인터페이스로 추상화 구현
🔎 abstract 제어자
➡️ 사전적 '추상적인' / 자바에서는 '미완성'
➡️ 메서드 앞에 붙으면 추상메서드, 클래스 앞에 붙은 경우 추상 클래스
어떤 클래스에 추상 메서드가 포함되어 있다면 자동으로 추상 클래스가 됨
abstract class AbstractExample { // 추상 메서드가 최소 하나 이상 포함돼있는 추상 클래스
abstract void start();
// 메서드 바디가 없는 추상메서드
// 메서드 시그니처만 존재하고 바디가 선언되어있지 않음 -> 추상메서드
}
📍추상 클래스는 미완성 설계도이기 때문에 메서드 바디가 완성되기 전까지 객체 생성 불가
AbstractExample abstractExample = new AbstractExample(); // 에러발생.
- 추상 클래스를 사용하면 상속을 받는 하위 클래스에서 오버라이딩을 통해 각각 상황에 맞는 메서드 구현이 가능해짐
- 상속계층도 상층부에 위치할수록 추상화의 정도가 높고, 그 아래로 내려갈수록 구체화됨
🔎 fianl 키워드
➡️ 최종의/마지막의 뜻을 가짐, 변경이 불가능하고 확장할 수 없음
➡️ 필드, 지역변수, 클래스 앞에 위치 가능하며 위치에 따라 의미가 달라짐
- 클래스 : 변경 또는 확장 불가능한 클래스, 상속 불가
- 메서드 : 오버라이딩 불가
- 변수 : 값 변경이 불가한 상수
final class FinalEx { // 확장/상속 불가능한 클래스
final int x = 1; // 변경되지 않는 상수
final int getNum() { // 오버라이딩 불가한 메서드
final int localVar = x; // 상수
return x;
}
}
🔎 인터페이스(Interface)
➡️ 서로 다른 두 시스템, 장치, 소프트웨어 따위를 서로 이어주는 부분 또는 그런 접속 장치
➡️ 추상화를 구현한다는 점에서는 추상 클래스와 비슷하지만 그에 비해 더 높은 추상성을 가짐
- 추상 클래스 : 바디가 없는 추상 메서드를 하나 이상 포함
- 인터페이스 : 기본적으로 추상 메서드와 상수만을 멤버로 가짐 → 추상 메서드의 집합
✍🏻 인터페이스의 기본 구조
➡️ 기본적인 클래스를 작성하는 것과 유사하지만 class 키워드 대신에 interface 키워드 사용
➡️ 내부의 모든 필드가 public static final로 정의 되고, static/default 메서드 이외의 모든 메서드가 public abstract 로 정의됨
public interface InterfaceEx {
public static final int rock = 1; // 인터페이스 인스턴스 변수 정의
final int scissors = 2; // public static 생략
static int paper = 3; // public & final 생략
public abstract String getPlayingNum();
void call() //public abstract 생략
}
// 생략된 부분은 컴파일러가 자동 추가
// 추상메서드와 상수만으로 구성
✍🏻 인터페이스의 구현
➡️ 인터페이스 그 자체로 인스턴스를 생성할 수 없고, 메서드 바디를 정의하는 클래스를 따로 작성해야 함
class 클래스명 implements 인터페이스명 {
... // 인터페이스에 정의된 모든 추상메서드 구현
}
// 특정 인터페이스를 구현한 클래스는 해당 인터페이스에 정의된 모든 추상 메서드를 구현해야 함
// 어떤 클래스가 특정 인터페이스를 구현한다는 것은 그 클래스에게 인터페이스의 추상 메서드를 반드시 구현하도록 강제하는 것
// 즉, 그 인터페이스가 가진 추상 메서드를 해당 클래스 내에서 오버라이딩한다는 것
✍🏻 인터페이스의 다중 구현
➡️ 클래스 간의 다중 상속은 허용되지 않으나 인터페이스는 다중적 구현 가능
→ 하나의 클래스가 여러 개의 인터페이스를 구현할 수 있음
➡️ 인터페이스는 인터페이스로만 상속 가능, 클래스와 달리 Object와 같은 최고 조상 존재하지 않음
➡️ 인터페이스는 애초에 미완성된 멤버를 가지고 있기 떄문에 충돌이 발생할 여지 없고 안전하게 다중 구현 가능
⭐️ 특정 클래스는 다른 클래스로부터의 상속을 받으면서 동시에 인터페이스를 구현할 수 있음
용어의 늪에 빠졌음... 머릿속으로는 이해가 됐다 싶으면서도 막상 코드로 살펴보면 적용이 바로바로 되지 않는다. 몇 번이고 분석만이 살 길임을 새삼 깨달았다. 객체 지향의 핵심 원리 네 가지는 몇 번이고 정리한 것을 다시 살펴봐야겠다. 튼튼한 기초가 준비되지 않으면 결국에는 가다가 흔들리기 마련이다. 오늘도 마지막 세션 때 같이 코드를 짜는 시간에 자꾸 얘가 어디서 왔더라? 어떻게 호출됐지? 하면서 굉장히 헷갈렸다. 다시 어제처럼 코드의 흐름을 천천히 따라가 봐야겠다.
'SEB_BE_45 > 공부 정리' 카테고리의 다른 글
13. 객체지향프로그래밍의 심화 / 20230428 (0) | 2023.04.29 |
---|---|
12. 객체지향프로그래밍의 심화 / 20230427 (0) | 2023.04.27 |
10. [Java] 객체지향프로그래밍의 이해 /20230425 (0) | 2023.04.25 |
09. [Java] 객체지향프로그래밍의 이해 /20230424 (0) | 2023.04.24 |
08. [Java] 객체지향프로그래밍의 이해 / 20230421 (0) | 2023.04.21 |