Blog Content

    티스토리 뷰

    객체 지향 프로그래밍 개념 정리

    <객체 지향 프로그래밍>
    1. 객체란?
    객체(Object)란 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른 것과 식별 가능한 것을 말한다.

    2. 객체 간의 관계
    객체는 개별적으로 사용될 수 있지만, 대부분 다른 객체와 관계를 맺고 있다. 이 관계의 종류에는 집합 관계, 사용 관계, 상속 관계가 있다.
    집합 관계 : 자동차 객체 <---> 엔진 객체, 타이어 객체, 핸들 객체

    사용 관계 : 객체 간의 상호작용. 사람은 자동차를 사용하므로 사람과 자동차는 사용의 관계

    상속 관계 : 상위(부모) 객체를 기반으로 하위(자식) 객체를 생성하는 관계. 자동차 객체 ---> 기계 객체

    3. 객체 지향 프로그래밍의 특징
    - 캡슐화(Encapsulation) : 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것. 외부 객체는 객체 내부의 구조를 알지 못하며 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있다.

    - 상속(Inheritance) : 상위 객체를 재사용해서 하위 객체를 쉽고 빨리 설계할 수 있도록 도와주고, 이미 잘 개발된 객체를 재사용해서 새로운 객체를 만들기 때문에 반복된 코드의 중복을 줄여줌

    - 다형성(Polymorphism) : 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질. 타이어 타입 --> 한국 타이어 객체, 금호 타이어 객체

    <객체와 클래스>

    객체를 생성하는 순서 : 개발자 --(설계)--> 클래스(설계도) --(인스턴스화)--> 인스턴스(객체)  

    <객체 생성과 클래스 변수>

    new 연산자를 사용해 클래스로부터 객체를 생성. new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성됨. new 연산자는 힙 영역에 객체를 생성시킨 후, 객체의 주소를 리턴하도록 되어 있음. 

    <클래스의 구성 멤버>
    - 필드: 객체의 데이터가 저장되는 곳
    - 생성자(Constructor): 객체 생성 시 초기화 역할 담당
    - 메소드: 객체 동작에 해당하는 실행 블록

    <생성자>
    1. 생성자 오버로딩 : 매개 변수를 달리하는 생성자를 여러개 선언하는 것. 생성자 오버로딩 시 주의할 점은 매개 변수의 타입과 개수 그리고 선언된 순서가 똑같을 경우 매개 변수 이름만 바꾸는 것은 생성자 오버로딩이라고 볼 수 없음.

    2. 다른 생성자 호출(this())
    생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드가 발생할 수 있다. 매개 변수의 수만 달리하고 필드 초기화 내용이 비슷한 생성자에서 이러한 현상을 많이 볼 수 있다.
    이 경우에는 필드 초기화 내용은 한 생성자에만 집중적으로 작성하고, 나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선할 수 있다. 생성자에서 다른 생성자를 호출할 때에는 다음과 같이 this() 코드를 사용한다.
    this()는 자신의 다른 생성자를 호출하는 코드로 반드시 생성자의 첫줄에서만 허용된다.

    <메소드>
    1. 매개 변수의 수를 모를 경우 : 해결책은 매개 변수를 배열 타입으로 선언하는 것이다.
    ex ) int sum1(int[] values) {    }
    But, 매개변수를 배열 타입으로 선언하면, 메소드를 호출하기 전에 배열을 생성해야 하는 불편한 점이 있다.
    그래서 배열을 생성하지 않고 갑의 리스트만 넘겨주는 방법도 있다.
    매개변수를 "..."를 사용해서 선언하면, 메소드 호출 시 넘겨준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용된다.
    ex ) int sum2(int ... values) {    }

    2. 메소드 오버로딩
    클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것.
    오버로딩의 사전적 의미는 많이 싣는 것.
    하나의 메소드 이름으로 여러 기능을 담는다 하여 붙여진 이름.
    메소드 오버로딩의 조건은 매개변수의 타입, 개수, 순서 중 하나가 달라야함.

    <인스턴스 멤버와 this>
    인스턴스 멤버란 객체(인스턴스)를 생성 후 사용할 수 있는 필드와 메소드를 말하는데, 이들을 각각 인스턴스 필드, 인스턴스 메소드라 부름
    여태까지 보았던 모든 필드와 메소드는 인스턴스 멤버였음

    객체 내부에서도 인스턴스 멤버에 접근하기 위해 this를 사용할 수 있음.
    this란, 우리가 자신을 "나"라고 하듯이 객체는 자신을 "this" 라고함.

    따라서 this.model은 자신이 가지고 있는 model 필드라는 뜻임.

    this는 주로 생성자와 메소드의 매개변수 이름이 필드와 동일한 경우, 인스턴스 멤버인 필드임을 명시하고자 할 때 사용됨.

    <정적 멤버와 static>
    정적(static)은 '고정된' 의미를 가지고 있음.
    정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말함.
    이들을 각각 정적 필드, 정적 메소드라고 부름.
    정적 멤버는 객체(인스턴스)에 소속된 멤버가 아니라 클래스에 소속된 멤버이기 때문에 클래스 멤버라고도 함.

    1. 정적 멤버 선언
    static 키워드를 추가로 붙여 사용한다.
    정적 필드와 정적 메소드는 클래스에 고정된 멤버이므로 클래스 로더가 클래스(바이트 코드)를 로딩해서
    메소드 메모리 영역에 적재할 때 클래스별로 관리된다. 따라서 클래스의 로딩이 끝나면 바로 사용할 수 있다.

    정적필드 선언 판단 기준은
    객체마다 가지고 있어야 할 데이터라면 인스턴스 필드로 선언하고,
    객체마다 가지고 있을 필요성이 없는 공용적인 데이터라면 정적 필드로 선언하는 것이 좋다.
    ex) 파이(3.14)는 객체마다 가지고 있을 필요가 없는 변하지 않는 공용적인 데이터이므로 정적 필드로 선언하는 것이 좋음

    정적메소드 선언 판단 기준은
    인스턴스 필드를 이용해서 실행해야 한다면 인스턴스 메소드로 선언하고,
    인스턴스 필드를 이용하지 않는다면 정적메소드로 선언한다.

    2. 정적 멤버 사용
    클래스가 메모리로 로딩되면 정적 멤버 바로 사용 가능.
    클래스 이름과 함께 도트(.) 연산자로 접근함
    클래스.필드;
    클래스.메소드(매개값);

    정적필드와 정적 메소드는 객체 참조 변수로도 접근이 가능하지만, 클래스 이름으로 접근하는 것이 좋다.

    3. 정적 초기화 블록
    정적 필드는 필드 선언과 동시에 초기값을 준다.
    계산이 필요한 초기화 작업이 있을 경우 정적 블록(static block)을 사용한다.
    static {
        ...
    }
    정적 블록은 클래스가 메모리로 로딩될 때 자동적으로 실행됨.
    정적블록은 클래스 내부에 여러 개가 선언되어도 상관없음.

    4. 정적 메소드와 블록 선언 시 주의할 점
    객체가 없어도 실행된다는 특징 때무에, 이들 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없음.
    또한 this 키워드도 사용 불가능
    정적 메소드와 정적 블록에서 인스턴스 멤버를 사용하고 싶다면 객체를 먼저 생성하고 참조 변수로 접근해야함.

    Comments