객체 지향 프로그래밍 OOP

  • OOP: Object Oriented Programing
    객체를 파악하고 객체들 간의 상호작용을 통해 프로그램을 만드는 것
  • 직관적인 방식
  • 컴퓨터에 맞춰 사고하던 방식의 프로그래밍(절차적/구조적)
    -> 현실세계를 인지하는 방식의 프로그래밍(객체 지향)

객체 지향의 4대 특성

  • 객체 지향의 4대 특성: 캡슐화, 상속, 추상화, 다형성 (캡! 상추다)
  • 캡슐화(Encapsulation): 정보 은닉
    • 정보 은닉 - 접근 제어자: private, default, protected, public
      • private: 같은 클래스에서 접근 가능
      • protected: 같은 패키지 & 상속 관계에 있는 클래스에서 접근 가능
      • default: 같은 패키지에서 접근 가능
      • public: 접근 제한 없음
    • 접근 제어자 UML 표기법
      • -표시: private 접근 제어자
      • ~표시: default 접근 제어자
      • #표시: protected 접근 제어자
      • +표시: public 접근 제어자

image

  • 상속(Inheritance): 재사용
    • 객체지향에서의 상속 = 확장 + 재사용
      • 상위 클래스의 특성을 하위 클래스에서 상속하고 필요한 특성을 추가(확장)
      • 상위 클래스쪽으로 갈수록 추상화/일반화
      • 하위 클래스쪽으로 갈수록 구체화/특수화
    • 상속에서는 "하위 클래스는 상위 클래스다"관계가 성립되어야함
    • => is a / is a kind of 관계를 만족
      • 동물은 포유류다 (x)
      • 포유류는 동물이다 (o)
    • extends 키워드 사용
    • 자바에서는 다중상속을 지원하지 않음
      • 다중 상속의 다이아몬드 문제 발생
        • 컴파일러가 정확한 상속관계를 파악할 수 없음
          => 호출이 모호해서 컴파일러의 정상적인 수행이 어려움
      • 다중 상속의 장점을 가져오기 위해 인터페이스 도입
      • "구현 클래스 is able to 인터페이스" 관계 성립
    • 상위 클래스는 물려줄 특성이 많을수록 좋음
      => 객체지향 설계 5원칙 중 LSP(리스코프 치환 원칙)
    • 인터페이스는 메서드가 적을수록 좋음
      => 객체지향 설계 5원칙 중 ISP(인터페이스 분리 원칙)

image

public class Inheritance {
    public static void main(String [] args) {
        // 상위 클래스 - Animal, 하위 클래스 - Mammalia, Bird라 가정
        Animal animal = new Animal;
        
        // "하위 클래스 is a kind of 상위클래스" 관계 성립
        Animal mammalia = new Mammalia();
        Animal bird = new Bird();
    }
}
  • 상속관계 UML 표기법
    • 두 클래스 간 상속은 하위 클래스에서 상위 클래스 쪽으로 실선 삼각형 화살표로 표시
    • 클래스가 인터페이스를 구현할 경우 클래스에서 인터페이스 쪽으로
      점선 삼각형 화살표로 표시, 약식으로 막대 사탕처럼 표시하기도 함

image

  • 추상화(Abstraction): 모델링
    • 추상: 여러가지 사물, 개념에서 공통되는 특성/속성을 추출해 파악
    • 모델: 실제 사물을 정확히 복제하는 것이 아닌 목적에 맞게 관심있는 특성만 추출하고 표현 => 추상화를 통한 실제 사물을 단순하게 묘사
    • 상속, 인터페이스, 다형성을 통한 추상화
    • 객체지향에서 추상화의 결과는 클래스
  • 다형성(Polymorphism): 사용편의성
    • 객체 지향에서의 다형성: overriding, overloading
      • overriding: 같은 메서드 이름, 같은 인자로 상위 클래스의 메서드 재정의
      • overloading: 같은 메서드 이름, 다른 인자로 다수의 메서드를
        중복 정의
        • 상위 클래스 타입의 객체 참조 변수를 사용해도 하위 클래스에서 overriding한 메서드가 호출
// method overriding & overloading ex)
public class Person {
    public String name;

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

public class Korean extends Person {    
    public void hi() { // method overriding
        System.out.println("안녕"); 
    }

    public void hi(String name) { // method overloading
        System.out.println("안녕하세요 저는 " + name + "입니다.");
    }
}

클래스(추상화)와 객체

  • 클래스(class): 분류, 집합, 같은 특성(속성/기능)을 가진 객체를 총칭
    • 키, 몸무게 => 명사로 표현되는 특성을 속성
    • 속성은 값을 가질 수 있다.
    • 먹다, 자다 => 동사로 표현되는 특성을 기능/행위(메서드)
    • 기능/행위는 수행 절차, 로직을 갖는다.
    • 애플리케이션 경계(context)에 따라 클래스 설계가 달라진다.
<클래스와 객체의 관계>
클래스 객체참조변수 = new 클래스();
=> 새로운 객체를 하나 생성해  객체의 주소값을 객체참조변수에 할당
  • 객체(object = class instance):실체, 유일무이한 사물
  • 클래스 멤버와 객체 멤버의 차이는 static 키워드의 유무
    => static 키워드가 있으면 클래스 멤버
  • 클래스 멤버 = static 멤버 = 정적 멤버
    • 정적 속성은 해당 클래스의 모든 객체가 같은 값을 가질 때 사용함
    • 정적 메서드는 객체 존재 여부와 관계없이 쓸 수 있는 메서드
      • 메모리가 초기화된 순간 객체가 하나도 존재하지 않기에 main()
        메서드는 정적 메서드여야 한다.
    • 정적 멤버는 UML 표기법에서 밑줄을 사용해 표시
    • 정적 멤버는 클래스 내부에 메모리 공간이 확보
    • 정적 멤버는 클래스명.정적멤버 형태로 접근하는 것을 권장
  • 객체 멤버 = 인스턴스 멤버
    • 객체 멤버는 클래스 내부에 실제 메모리 공간을 확보하지 않는다
  • 클래스, 객체 멤버는 별도로 초기화 해주지 않아도 default 값으로 초기화됨
    • int(0), double(0.0), boolean(false), 객체(null)
세가지 변수 유형
이름호칭메모리 공간
static 변수클래스 멤버, 정적 멤버static 영역
instance 변수객체 멤버heap 영역
local 변수지역 변수stack 영역
public class Person {
    // 객체(인스턴스) 멤버
    public String name;
    public int age;

    // 클래스 멤버 => static 키워드
    public static int countOfEyes;
}

public class Main {
    // main() 메서드도 클래스의 멤버 메서드
    public static void main(String [] args){
        // 클래스 멤버는 클래스명, 객체명으로 모두 접근 가능 
        // 클래스명.멤버
        Person.countOfEyes = 2;
        
        Person person = new Person();
        
        // 객체명.멤버        
        System.out.println(person.countOfEyes);
    }
}

출처: 김종민, ⌜스프링 입문을 위한 자바 객체 지향의 원리와 이해⌟ 위키북스

Leave a comment