JAVA - OOP(2) 상속, 캡슐화, 다형성

이상해씨·2022년 7월 24일
0

웹 풀스택(JAVA)

목록 보기
7/54

✔객체지향 프로그래밍(OOP)

0. OOP의 특징

◾ OOP is A P.I.E
1. Abstraction(추상화) : 현실의 객체를 추상화하여 클래스 구성.
2. Polymorphism(다형성) : 하나의 객체를 여러 가지 타입(형)으로 참조.
3. Inheritance(상속) : 부모 클래스의 자산을 물려받아 자식을 정의함으로 코드의 재사용 가능.
4. Encapsulation(데이터 은닉과 보호, 캡슐화) : 데이터를 외부에 직접 노출시키지 않고 메서드를 이용해 보호.

1. 상속(Inheritance)

  • 상속(Inheritance) : 기존 클래스의 자산(멤버, 필드)을 자식 클래스에 물려주어 재사용하는 기능.(생성자, 초기화 블록 제외)
    • is-a 관계 : (ex) 아파트는 건물이다.
    • UML Class Diagram : 실선 삼각형 (자식 -▷ 조상)
    • 적용 : extends 키워드 사용.
// 기본 상속.
// 부모 클래스.
class Parent {}

// 자식 클래스.
class Child extends Parent {}
  • 단일 상속(Single Inheritance) : 자바는 단일 상속만 지원.
    • 다중 상속의 경우 여러 클래스의 기능을 물려받을 수 있지만 관계가 복잡해진다.
    • interface와 포함 관계(has-a)로 다중 상속처럼 활용 가능하다.
  • 포함 관계(has-a) : 상속 이외의 클래스 재활용 방법.
    • 2개 이상의 클래스에서 특성을 가져올 때 하나는 상속. 나머지는 멤버 변수(필드)로 처리.
    • UML Class Diagram : 실선(-)
// 포함 관계 포함 상속.
// 부모 클래스1
class Parent1 {}
// 부모 클래스2
class Parent2 {}

// 자식 클래스
// Parent2는 포함 관계로 사용.
class Child extends Parent1 {
	Parent2 p;
}
  • 상속의 장점 : 부모 코드의 변경으로 모든 자식들에게 적용.
    • 코드 절감.
    • 유지 보수성 향상.
  • Object 클래스 : 모든 클래스의 조상 클래스.
    • 별도의 extends 선언이 없는 클래스들은 extends Object 생략.
    • 즉, Object의 멤버는 모든 클래스의 멤버.
    • Object의 hashCode(), equals(), toStirng() 등은 자주 재정의하여 사용.
    • notify(), wait() 등 멀티 스레드 프로그래밍에 사용하는 메서드도 존재.
  • 메서드 재정의(Overriding) : 조상 클래스에 정의된 메서드를 자식 클래스에서 적합하게 수정하는 것.
    • 오버라이딩의 조건.
      • 메서드 이름이 같아야 한다.
      • 매개 변수의 개수, 타입, 순서가 같아야 한다.
      • 리턴 타입이 같아야 한다.
      • 접근 제한자는 부모보다 범위가 넓거나 같아야 한다.
      • 조상보다 더 큰 예외를 던질 수 없다.
  • Annotation : 컴파일러, JVM, 프레임워크 등이 보는 주석
    • 소크 코드에 메타 데이터를 삽입하는 형태(소스 코드의 구조 변경, 환경 설정 정보 추가 등의 작업 담당.)
    • @Deprecated : 컴파일러에게 해당 메서드가 deprecated 되었다고 알려줌.
    • @Override : 컴파일러에게 해당 메서드는 override한 메서드임을 알려줌. 반드시 Super Class에 선언되어있는 메서드 여야 한다.
    • @SuppressWarnings : 경고를 생략하기 위해 사용.
  • super : 조상 클래스 객체를 의미.
    • 변수의 scope : 사용된 위치에서 점점 확장해가며 처음 만난 선언부에 연결.
      • method 내부 -> 해당 클래스 멤버 변수 -> 조상 클래스 멤버 변수.
    • super() : this()와 동일하게 조상 클래스의 생성자를 의미.
      • 조상 클래스에 선언된 멤버들은 조상 클래스의 생성자에서 초기화가 이뤄지므로 이를 재활용.
      • 자식 클래스에 선언된 멤버들만 자식 클래스 생성자에서 초기화.
      • 자식 클래스 생성자의 맨 첫 줄에서만 호출 가능.
      • 명시적으로 this() 또는 super()를 호출하지 않는 경우 컴파일러가 super() 삽입.
      • 따라서, 맨 상위의 Object까지 객체가 만들어지는 구조.
  • Object 메서드 오버라이딩
  1. toString() : 객체를 문자열로 변경하는 메서드.
    • 기본형은 객체의 해시 코드 전달.
  2. equals() : 두 객체가 같은지 비교하는 메서드.
    • 등가비교 연산자(==)로 객체 연산시 두 객체의 주소값 비교.
    • 자바는 연산자 재정의가 불가능하다.
    • 따라서, equals를 재정의하여 객체 비교에 사용한다.
    • 리터럴(Literal)들은 Class 메모리 영역의 Constant Pool에 저장된다.
      • Literal : 프로그램에서 사용하는 변하지 않는 모든 값.(숫자, 문자, 논리값 등)
        • 문자열도 리터럴.(단, new String()을 사용하면 리터럴이 아니다!!!!)
        • Constant Pool에 [정수 - int, 실수 - double]로 저장.
      • 하나의 값을 참조하는 형태이므로 비교 연산자로 비교 가능.
  3. hashCode() : 객체의 해시 코드. 시스템에서 객체를 구별하기 위해 사용하는 정수값.
    • HashSet, HashMap 등에서 객체의 동일성을 확인하기 위해 사용한다.
    • equals 메서드 재정의할 때 반드시 hashCode도 재정의해야 한다.(String, Number 등에서 재정의된 hashCode 활용 권장)

2. 캡슐화(데이터 은닉과 보호)

  • 제한자(Modifier) : 클래스, 변수, 메서드 선언부와 함께 사용되어 부가적인 의미 부여.
    • 하나의 대상에 여러 제한자 가능. 접근 제한자는 하나만 사용 가능.
    • 순서는 무관(일반적으로 접근 제한자를 맨 앞으로)
    • 접근 제한자 : public, protected, (default=package), private
    • 그 외 제한자
      • static : 클래스 레벨의 요소 설정.
      • final : 요소를 더 이상 수정할 수 없게 함.
        • final class : 더 이상 확장 할 수 없음. 상속 금지 -> 오버라이딩(overriding) 방지(이미 완벽한 클래스들).
        • final method : 더 이상 재정의 할 수 없음. 오버라이딩(overriding) 금지.
        • final variable : 더 이상 값을 바꿀 수 없음. 상수화.
      • abstract : 추상 메서드 및 루상 클래스 작성.
      • synchronized : 멀티 스레드에서의 동기화 처리.
  • 접근 제한자(Access Modifier) : 멤버 등에 사용되며 해당 요소를 외부에서 사용할 수 있는지 설정.
  • 데이터 은닉과 보호(Encapsulation)
    • 외부에서 변수에 직접 접근하면 정보(데이터) 보호되지 않는다.
      • private을 통해 외부 접근 차단
      • 공개되는(public) 메서드를 통한 접근 통로 마련. 메서드에 정보 보호 로직 구성.(setter/getter)
  • 객체의 생성 제어와 Singletone 디자인 패턴
    • 객체의 생성을 제한해야하는 경우 사용.
      • 여러 개의 객체가 필요없는 경우(Stateless한 객체) : 객체를 구별할 필요가 없는 경우(수정 가능한 멤버 변수가 없고 기능만 있는 경우)
      • 객체를 계속 생성/삭제 하는데 많은 비용이 들어 재사용이 유리한 경우.
    • Singleton 디자인 패턴
      • 외부에서 생성자 접근 금지 -> 생성자 private 설정.
      • 내부에서 private 접근 가능 -> 직접 객체 생성.(멤버 변수 private 설정.)
      • 외부에서 private 멤버에 접근 가능한 getter 생성 -> setter 불필요.
      • 객체없이 외부에서 접근할 수 있또록 getter와 객체 변수에 static 추가.
      • 외부에서 getter로 언제나 접근 가능. -> 하나의 객체 재사용.
class Singletone{
	private Singletone instance;
    private Singletone(){}
    // 객체가 생성되지 않았다면 생성. 객체 생성되었다면 객체 반환. 
    // => 하나의 객체로 접근.
    public Singletone getInstance(){
		if (this.instance == null){
        	this.instance = new Singletone();
        }
        return this.instance
	}
}

3. 다형성(Polymorphism)

  • 다형성(Polymorphism) : 하나의 객체가 많은 형(타입)을 가질 수 있는 성질(Heterogeneous, 헤테로 지니어스, 이질화)
    • 상속 관계에 있을 때 조상 클래스의 타입으로 자식 클래스 객체를 참조(Reference)할 수 있다.
  • 다형성의 활용
    1. 다른 타입의 객체를 다루는 배열
      • 배열은 같은 타입의 데이터를 묶음으로 관리(Homogeneous, 호모지니어스, 동질화)
      • 다형성으로 다른 타입의 데이터를 하나의 배열로 관리.
      • Object는 모든 클래스의 조상 : 어떤 타입의 '객체'라도 저장할 수 있음.
        • 기본적으로 기본형은 담을 수 없다. 참조형이 아니므로.
        • 하지만, autoboxing을 통해 Wrapping되어 저장 가능.
      • 이를 활용해 Collection API 등장.
    2. 매개 변수의 다형성
      • 조상을 파라미터로 처리한다면 객체의 타입에 따라 메서드를 만들 필요가 없어진다.
      • API에서 파라미터를 Obejct를 받는다는 것은 모든 객체를 처리한다는 의미.
      • 필요하다면 하위 클래스에서 오버라이딩 필요.
  • 다형성과 참조형 객체의 형 변환
    • 메모리에 있는 것과 사용할 수 있는 것의 차이.
    • 메모리에 있더라도 참조하는 변수의 타입에 따라 접근할 수 있는 내용 제한.
  • 참조형 객체의 형 변환
    • child(작은 집) -> super(큰 집) : 묵시적 형변환(캐스팅). 조상의 모든 내용이 자식에 있기 떄문에 가능.
    • super -> child : 명시적 형변환(캐스팅). 형변환 생략 불가.
    • 조상 클래스가 모든 자식 클래스에 변환될 수 없다. 확인 필요.
      • instanceof 연산자 : 실제 메모리에 있는 객체가 특정 클래스 타입인지 boolean으로 리턴.
  • 참조 변수의 레벨에 따른 객체의 멤버 연결
    • 상속 관계에서 객체의 멤버 변수가 중복될 때 : 참조 변수 타입에 따라 연결이 달라짐.
    • 상속 관계에서 객체의 메서드가 중복될 때(Override 되었을 때)
      • 무조건 자식 클래스의 메서드가 호출됨. (Virtual Method Invocation)
      • 최대한 메모리에 생성된 실제 객체에 최적화된 메서드가 동작.
    • Java API처럼 공통 기능인 경우 Object를 파라미터로 쓰겠지만 많은 경우 비즈니스 로직상 최상위 객체 사용 권장.
profile
후라이드 치킨

0개의 댓글