<TIL> 19. 객체지향 part 2

YUJIN LEE·2023년 2월 22일
0

개발log

목록 보기
15/149

상속

기존의 클래스로 새로운 클래스를 작성하는 것.
두 클래스를 부모와 자식으로 관계를 맺어주는 것
extends키워드를 사용해 관계를 맺음.

상속의 조건

  • 자손은 조상의 모든 멤버를 상속.
    - 생성자와 초기화 블럭 제외
  • 자손의 멤버 개수는 조상보다 적을 수 없다.
    - 항상 같거나 많음
  • 자손의 변경은 조상에게 영향을 미치지 않음.

포함 관계

클래스의 멤버로 참조변수를 선언.
작은 단위의 클래스를 만들고, 이 들을 조합해서 클래스를 만듬

관계 결정

상속관계: ~은 ~이다. (is-a)
포함관계: ~은 ~을 가지고 있다. (has - a)

단일 상속

Java는 단일 상속 만을 허용

  • 비중이 높은 클래스 하나만 상속관계로 하고 나머지는 포함관계를 사용하는 방법으로 풀어낼 수 있다.
    왜냐면 Diamond Problem의 문제가 생길수도 있기 때문에.

Object 클래스

모든 클래스의 조상.

  • 부모가 없는 클래스는 컴파일러에 의해 자동으로 Object 클래스를 상속받게 된다.
  • 모든 클래스는 Object 클래스에 정의된 11개의 메서드를 상속.

오버라이딩

부모가 가진 메서드와 똑같은 모양의 메서드를 자식이 가지는 것.
부모가 물려준 메서드를 자식 클래스에서 재정의해 사용하는 것.
상속받은 조상의 메서드를 자신에게 맞게 변경하는 것.

  • 선언부는 변경 불가능
  • 메서드 내부의 내용만 변경 가능

오버라이딩의 조건

  • 선언부가 조상 클래스의 메서드와 일치해야 한다.
  • 접근 제어자를 조상 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.
  • 예외는 조상 클래스의 메서드보다 많이 선언할 수 없다.

오버로딩과 오버라이딩 비교

오버로딩: 기존에 없는 새로운 메서드를 정의
오버라이딩: 상속받은 메서드의 내용을 변경

super와 super()

객체가 생성될 때 부모클래스가 먼저 생성..
super.필드명, super.메서드명()으로 부모의 필드나 부모의 메서드에 접근 가능
super()로 부모의 생성자에 접근 가능

super

객체 자신을 가리키는 참조변수.
인스턴스 메서드(생성자) 내에서만 존재.
조상의 멤버를 자신의 멤버와 구별할 때 사용

super()

조상의 생성자를 호출할 때 사용
조상의 멤버는 조상의 생성자를 호출해서 초기화
생성자의 첫 줄에 반드시 생성자를 호출해야 함.
-> 그렇지 않으면 컴파일러가 생성자의 첫 줄에 super();를 자동으로 삽입

package와 import

package

서로 관련된 클래스의 묶음.
패키지를 하나의 폴더라고 생각.
클래스의 실제 이름은 패키지를 포함(java.lang.String)

package 선언

패키지는 소스파일의 첫 번째 문장으로 단 한번만 선언
같은 소스 파일의 클래스들은 모두 같은 패키지에 속함
패키지 선언이 없으면 default 패키지에 속하게 됨

클래스 패스(classpath)

클래스 파일(.class)의 위치를 알려주는 경로
classpath(환경변수)로 관리하며 경로간의 구분자는 ';'를 사용
classpath에 패키지의 루트를 등록해줘야 함

import

클래스를 사용할 때 패키지 이름을 생략할 수 있게 해줌.
컴파일러에게 클래스가 속한 패키지를 알려줌
java.lang 패키지는 중요한 클래스들이 모여있는 패키지, import를 생략할 수 있게 되어있다.

  • String, Object, System....
    선언 방법: import 패키지명.클래스명;
    import는 패키지와 클래스 선언 사이에 존재한다.

static import

static 멤버를 사용할 때 클래스 이름을 생략할 수 있게 해줌

  • import static java.lang.System.out;
  • 위처럼 선언 해주면 out.println("출력!"); 이렇게 사용할 수 있다.

접근 제어자

제어자

클래스와 클래스의 멤버(변수, 메서드)에 부가적인 의미를 부여.

  • 접근 제어자: public, protected, (default), private
  • 그 외: static, final, abstract ...
    하나의 대상에 여러 제어자를 같이 사용 가능(접근 제어자는 하나만 가능)
  • 순서는 상관없지만 주로 접근 제어자를 제일 왼쪽에 선언
  • public static void main(String[] args) {}

static

멤버변수, 메서드, 초기화 블럭에 static이 사용될 수 있습니다

final

클래스, 메서드, 멤버변수, 지역변수에 final이 사용될 수 있습니다.

생성자를 이용하여 final 멤버변수를 초기화 할 수 있다.

  • final 이 붙은 변수는 상수이기 때문에 보통은 선언과 동시에 초기화를 진행해야 하지만 인스턴스 변수의 경우 생성자에 의해서 초기화 할 수 있습니다.

abstract

클래스, 메서드에 abstract이 사용될 수 있습니다.

접근 제어자

private: 같은 클래스 내에서만 접근이 가능합니다.
(default): 같은 패키지 내에서만 접근이 가능합니다.(생략가능)
protected: 같은 패키지 내에서, 그리고 다른 패키지의 자손 클래스에서 접근이 가능.
public: 접근 제한이 전혀 없다.

접근 제어자의 조합 주의!

대상 사용가능한 접근 제어자

클래스 public, (default), final, abstract
메서드 모든 접근제어자, final, abstract, static
멤버변수 모든 접근제어자, final, static
지역변수 final

  • 메서드에 static과 abstract를 함께 사용할 수 없습니다.
    - static 메서드는 몸통이 있는 메서드에만 사용할 수 있기 때문
  • 클래스에 abstract와 final을 동시에 사용할 수 없습니다.
    - 클래스에 사용 되는 final은 클래스를 확장할 수 없다는 의미,
    abstract는 상속을 통해서 완성되어야 한다는 의미이므로 서로 모순되기 때문.
  • abstract 메서드의 접근 제어자가 private 일 수 없음.
    - abstract 메소드는 자손 클래스에서 구현하기 위해 접근해야하기 때문.
  • 메서드에 private와 final을 같이 사용할 필요 X
    - 접근 제어자가 private인 메서드는 오버라이딩될 수 없기 때문입니다.
    • 이 둘 중 하나만 사용해도 의미가 충분

캡슐화

접근 제어자를 사용하는 이유?

  • 외부로부터 데이터를 보호하기 위해 사용
  • 내부적으로만 사용되는 것을 외부로 노출시키지 않고 감추기 위해서 사용.
  • 이렇게 데이터를 보호하는 것을 캡슐화라고 부름

다형성

여러 가지 형태를 가질 수 있는 능력
조상 타입의 참조변수로 자손 타입의 객체를 다루는 것.

  • 조상 타입의 참조변수로 자손 타입의 객체를 다룰 수는 있다.
  • 하지만, 조상 타입에는 없는, 자손 타입만 가지고 있는 기능 및 속성들은 사용할 수 없다.

참조변수의 형변환

사용할 수 있는 멤버의 개수를 조절하는 것.
조상, 자손 관계의 참조변수는 서로 형변환이 가능.

A(객체) instanceof B(클래스) 연산

A 객체가 B 클래스로 부터 상속을 받았는지 확인할 수 있다
참조변수를 형변환 하기 전에 형변환 가능여부를 확인하기 위해 사용.
형변환 전에 반드시 instanceof로 확인해야함!

매개변수 다형성

참조형 매개변수는 메서드 호출시, 자신과 같은 타입 또는 자손타입의 인스턴스를 넘겨 줄 수 있습니다.

추상 클래스

추상 클래스의 형태

일반 클래스와 똑같은데 추상 메서드가 추가된 미완성된 클래스

추상클래스 정의

  • 추상클래스는 클래스 앞에 abstract 키워드를 넣어 정의
  • 추상클래스는 미완성의 추상 메서드를 포함할 수 있다.
    - 추상 메서드란 내용이 없는 메서드. 즉, 구현되지 않은 메서드
    • 추상 메서드는 리턴형 앞에 abstract 키워드를 붙여야한다.
  • 추상 메서드는 객체를 생성할 수 없다.

인터페이스

인터페이스는 객체를 선언하기 저에 이 객체가 가지고 있어야 할 기능들을 모아놓은 것.
인터페이스는 반드시 해당 인터페이스를 구현하는 구현하는 클래스가 있어야 사용가능.

추상 메서드의 집합
구현된 것이 전혀 없는 설계도
모든 멤버가 public
상수 이외의 인스턴스 변수, 클래스 변수는 가질 수 없다.

인터페이스에 선언한 변수는 무조건 상수로 처리!!

인터페이스의 상속

인터페이스의 조상은 인터페이스만 가능
인터페이스는 클래스처럼 Object가 최고 조상이 아님.
추상 메서드는 어차피 상속 받으면서 구현부를 작성하기 때문에 충돌해도 상관없다.
따라서 다중 상속 가능

인터페이스의 구현

인터페이스에 정의된 추상 메서드를 완성하는 것
class 클래스이름 implements 인터페이스 이름 {}
클래스에서 implements 라는 키워드를 사용하여 인터페이스 구현

  • 추상 클래스 때와 마찬가지로 구현을 다 못한 클래스는 아직 미완성된 클래스로 취급하기 때문에 abstract 제어자를 클래스에 추가해야함.

인터페이스의 다형성

인터페이스 return 타입

인터페이스 메서드를 반환 타입으로 지정할 수 있다.

인터페이스의 장점

두 객체 간의 '연결, 대화, 소통'을 돕는 '중간 다리 역할'을 한다.
선언(설계)과 구현을 분리시킬 수 있게 해준다.

인터페이스를 사용하면 클래스 하나로 기능들을 바로 구현할 수 있다.
호출하는 클래스만 변경해서.
인터페이스를 사용하지 않으면 중복 기능들을 각 모델(클래스)마다 구현해야한다.
그렇기 때문에 인터페이스를 사용한다.

인터페이스에 정의한 static 메서드

반드시 인터페이스명.메서드명(); 형식으로 사용해야함

profile
인정받는 개발자가 되고싶습니다.

0개의 댓글