객체 지향 기본개념

김설영·2022년 3월 26일
0

코드의 재사용성이 높고, 유지보수가 용이하며, 중복 코드도 제거한다.
-> 빠른 변화를 쫓아갈 수 있다.

객체 지향 프로그래밍 : OOP (Object-Oriented Programing)

객체지향 언어 = 프로그래밍 언어 + 객체지향개념(규칙)

객체지향개념(규칙)은 반드시 외워두어야 한다.

4가지 핵심 개념

  1. 캡슐화
  2. 상속
  3. 추상화
  4. 다형성 (가장 중요!)

객체지향개념은 반복해서 공부할 수록 쉬워진다. -> 요약
자바의 정석 3판 보고, (핵심 + 응용)
바로 JSP, Spring을 배우자. (이해보다는 실습 먼저 하고, 만들어보고, 흉내내보고, 모든걸 해보자)
코딩 경험이 어느정도 쌓인 다음, 디자인패턴 / 객체지향 개념 기본서를 보자.
설계를 잘하려면 코딩 경험이 많아야 한다!


클래스와 객체

  • 실제 세계를 컴퓨터 안에 들여놓으려고 시도
  • Hard Ware의 Soft Ware화 (프로그램 = 코드)

클래스

  • 정의 : 객체를 정의해 놓은 것
  • 용도 : 객체를 생성하는 데 사용
  • 객체를 생성하기 위해서 필요하다.
  • "설계도" or "데이터 + 함수" or "사용자 정의 타입"

데이터 + 함수 결합 클래스

  • 변수 : 하나의 데이터를 저장할 수 있는 공간
  • 배열 : "같은 종류"의 여러 데이터를 하나로 저장할 수 있는 공간
  • 구조체 : 서로 관련된 여러 데이터를 종류에 상관 없이 하나로 저장할 수 있는 공간
  • 클래스 : 서로 관련된 데이터와 함수의 결합 (구조체 + 함수)

사용자 정의 타입

  • 원하는 데이터 타입을 직접 만들 수 있다.

객체

  • 정의 : 실제로 존재하는 것. 사물 or 개념.
  • 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름.
  • 객체 = 속성(변수) & 기능(메서드)
  • 객체는, 객체를 사용하기 위해서 필요하다.
  • 객체를 사용한다는 것 = 객체가 가진 속성과 기능을 사용하는 것.

Tv를 예로 들면...

class Tv {
	// 속성(변수)
	String color;
    boolean power;
    int channel;
    
    // 기능(메서드)
    void power()		{power = !power;}
    void channelUp()	{channel++;}
    void channelDown()	{channel--;}
}

위 코드를 통해 아래와 같은 객체가 생성됨
출처 : 자바의정석 남궁성님 유튜브


인스턴스

  • 객체 : 모든 인스턴스를 대표하는 일반적 용어
  • 인스턴스 : 특정 클래스로부터 생성된 객체
  • 클래스 -> 인스턴스화(객체 생성) -> 인스턴스(객체)

변수

선언 위치에 따른 변수의 종류

출처 : 자바의정석 남궁성님 유튜브

클래스 영역

  • 인스턴스 변수 : 인스턴스(객체)가 생성되었을 때 생성 -> 참조변수 혹은 객체가 사라지면 GC에 의해 제거 됨.
  • 클래스 변수 : 클래스가 메모리에 올라갈 때 생성 (객체가 생성 안되어도 됨!)
  • 클래스 영역 전체에서 사용 가능.

클래스 영역 이외의 영역 - 메서드, 생성자, 초기화블럭 내부

  • 지역 변수 : 메서드, 생성자, 초기화 블럭 내부의 변수 선언문이 수행되었을 때 생성.
  • 메서드 내부에서만 사용 가능.
  • 메서드 종료 시 자동 제거.
class Variables
{
	// 클래스 영역 -> 선언문만 가능 (변수 선언, 메서드 선언)
    // 순서는 딱히 정해진 게 없다.
	int iv;  // 인스턴스 변수 "선언"
    static int cv;  // 클래스 변수 (static 변수, 공유 변수) "선언"
	
    // 메서드 영역
    void method(){ // 메서드 "선언" 및 정의
    	int lv = 0;  // 지역 변수 
    }
}

클래스 변수 vs 인스턴스 변수

  • 개별 속성 -> 인스턴스 변수
  • 공통 속성 -> 클래스 변수
class Card{
	// iv : 개별 속성에 대해 사용
	String kind;  // 카드 무늬 (개별)
    int number;  // 카드 숫자 (개별)
	
    // cv : 공통 속성에 대해 사용
    static int width = 100;  // 카드 폭 (공통)
    static int height = 250;  // 카드 높이 (공통)
}
  • cv 호출 시, 아래와 같이 사용해야 한다.
Card c = new Card();
c.kind = "HEART";
c.number = 5;

// cv를 사용 할 때는, 참조 변수를 쓰기보다, 
// 클래스 이름을 붙여주는게 일반적이다.
c.width = 200;  ->  Card.width = 200;
c.height = 300;  -> Card.height = 300;

변수의 초기화

  • 지역 변수(lv)는 반드시 수동 초기화 필수!! -> 0으로 자동 초기화 하게 두면, 메모리의 효율이 떨어짐. 지역 변수는 빨리 쓰고 빨리 버려서 없애야됨. 유지 기간이 짧음

  • 멤버 변수(인스턴스 변수(iv), 클래스 변수(cv))는 유지기간이 비교적 길다. -> 자동 초기화가 된다.

멤버변수의(iv, cv) 초기화

  1. 자동 초기화

    • 초기화를 해주지 않아도, 0, false.. 등 각 타입에 맞는 기본 값으로 자동으로 초기화 함
    • 멤버 변수(iv, cv)만 자동 초기화 가능
  2. 명시적 초기화 (=, 대입연산자 이용) : 간단한 초기화
    ex-기본형 초기화) int door = 4;
    ex-참조형 초기화) Engine e = new Engine(); // 객체 주소를 넣어주는 것이 초기화다

  3. 초기화 블럭 ({} 이용) : 복잡한 초기화

    • iv 초기화 -> 인스턴스 초기화 블럭 : {} -> iv는 이 방식 보다는, 생성자를 사용하여 초기화함.
    • cv 초기화 -> 클래스 초기화 블럭 : static {}
  4. 생성자 : 복잡한 초기화

    • iv 초기화에 사용
    • 기본 생성자, 매개변수 있는 생성자
  • 클래스 변수 초기화 시점 : 클래스가 처음 로딩될 때(메모리에 올라갈 때) "단 한번"

  • 인스턴스 변수 초기화 시점 : 인스턴스가 생성될 때 마다 (인스턴스가 만들어 질 때마다 iv가 새로 만들어지기 때문!)

  • InitTest it = new InitTest();
    초기화 순서 (cv -> iv / 자동 -> 간단 -> 복잡)
    1. 클래스 초기화 (자동 초기화 후, 간단 -> 복잡 초기화 진행)
    2. 인스턴스 초기화 (자동 초기화 후, 간단 -> 복잡 초기화 진행)
    3. 새로운 객체를 또 만들면, 클래스 초기화는 발생하지 않고, 새로운 객체만 초기화 된다


메서드

  • 함수와 메서드의 근본적인 의미는 같다.
  • 함수는 제약이 없으나, 메서드는 반드시 클래스 안에 있어야 한다.
  • 문장들을 묶어놓은 것
  • 작업 단위로 문장들을 묶어서 이름을 붙인 것
  • 값(입력)을 받아서 처리하고, 결과를 반환(출력) 할 수 있음.
  • 하나의 메서드는 "한가지 기능만 수행"하도록 작성한다.
  • 반환할 것이 없을 땐, 반환 타입에 "void"를 적어준다.
반환 타입 + 메서드 이름 ( 매개변수 선언 )
int add (int x, int y) {  // 선언부
	int result = x + y;  // 구현부
    
    return result;
}

// 매개변수 int x, int y와 메서드 내부의 int result는 지역변수(lv)다.

장점

  • 코드 중복을 줄일 수 있다.
  • 코드 관리가 쉽다. (유지 및 보수가 쉽다.)
  • 코드를 재사용 할 수 있다.
  • 코드가 간결해서 이해하기 쉬워진다.
// 메서드 호출
public static void main (String[] args) {
	int result = add(3, 5);  // 메서드 호출
    
    // 이 때, 넘겨주는 3, 5를 argument라고 한다.
    // 3, 5가 add 메서드의 int x, int y로 넘어가게(대입) 되고, 계산이 처리된다.
	// Argument는 "원본" 이고, Parameter는 "복사본"이다.
}
  • 메서드를 호출할 때 사용한 Argument는 중간 매개체를 통해 전달되어야 하는데, 그 매개체가 "매개 변수"이다.

메서드 타입

  • Static method : 메서드 앞에 "static"이 붙은 메서드
    - 인스턴스 생성 없이, 항상 클래스이름.메서드이름() 으로 호출 가능
    - ex : Math.random(), Math.round()
    - 인스턴스 멤버와 관련 없는 작업을 하는 메서드
    - 메서드 내에서 iv 사용 불가 (메서드를 호출했을 때, 객체가 있다는 보장이 없기 때문에 사용할 수 없다.)
    - iv를 사용하지 않을 때, static을 붙이면 된다.
    - 작업에 필요한 값을 parameter를 통해 전달받은 local variable로 해결하기 때문에, iv가 필요없다. iv가 필요 없기 때문에, 객체(인스턴스)의 생성이 필요가 없다.
    - static 메서드는 인스턴스 메서드를 호출할 수 없다. (객체가 있다는 보장이 없음)

  • Instance method : 메서드 앞에 static이 "안"붙은 메서드
    - 인스턴스 생성 후, 참조변수.메서드이름() 으로 호출
    - 인스턴스 멤버(instance variable, instance method)와 관련된 작업을 하는 메서드
    - 메서드 내에서 iv 사용 가능
    - iv를 사용해야 하면, static을 붙이면 안된다.
    - 작업에 필요한 값을 iv를 사용하기 때문에, 파라미터를 굳이 안 넘겨줘도 된다. 또한, iv를 사용해야 하므로 필수적으로 인스턴스가 생성 되어야 한다.
    - 인스턴스 메서드는, 다른 인스턴스 메서드와 static 메서드를 호출할 수 있다.

  • 위 두 메서드는 "인스턴스 변수(iv)" 사용 여부에 따라 분류됨.

  • 객체, 인스턴스 = iv 묶음

오버로딩(Overloading)

  • 한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것

  • 대표적 예시
    void println()
    void println(boolean x)
    void println(char x)
    void println(char[] x)
    void println(double x) .... 등등

  • 오버로딩 성립 조건
    1. 메서드 이름이 같아야 한다.
    2. 매개변수의 갯수 또는 타입이 달라야 한다.
    3. 반환 타입은 오버로딩에 영향을 미치지 않는다.

    - 오버로딩 예시
    long add (int a, long b) { return a + b; }
    long add (long a, int b) { return a + b; }
    -> add(3, 3); 으로 실행하면, 사용해야 할 메서드가 1번인지, 2번인지 알 수가 없기 때문에 에러 남. (불명확. ambiguous)

생성자(constructor)

  • 인스턴스가 생성될 때마다 호출되는 "인스턴스 초기화 메서드" == iv 초기화 메서드

  • 인스턴스 생성 시 수행할 작업(iv 초기화)에 사용

  • iv를 편리하게 초기화하려고 만듬

class Card {
	// 생성자 오버로딩
    
	Card() { // 매개변수 없는 생성자
		// 인스턴스 초기화 작업
	} 
            
	Card(String kind, int number) { // 매개변수 있는 생성자
		// 인스턴스 초기화 작업
	}
}
  • 규칙
    1. 생성자의 이름이 클래스 이름과 같아야 한다.
    2. 초기화 메서드는 "대입"작업을 하는 대입문이기 때문에, 리턴 값이 없다. (void 안 붙임)
    -> 항상 반환 값이 없기 떄문에 void를 붙이지 않음
    3. 모든 클래스는 반드시 1개 이상의 생성자가 있어야 한다.
    -> Card c = new Card(); 이 구문은 사실 "생성자 호출" 이었던 것!
    -> 이는 "기본 생성자"라고 부른다. 컴파일러가 생성자가 없을 때 추가를 해줌!

  • 기본 생성자 (Default constructor)
    - 매개 변수가 없는 생성자
    ex) Card() {}; // Card 클래스의 기본 생성자
    - 생성자가 하나도 없을 때만, 컴파일러가 자동으로 추가 함.
    - 왠만하면, 기본생성자를 "반드시" 만들어주자!

  • 매개변수가 있는 생성자
    - 초기화를 편리하게 하기 위해서 사용
    - 코드를 간결하게 사용하기 위해서 사용

  • Car c = new Car("White", "auto", 4); 구현 순서
    1. 참조변수 c 생성
    2. new 연산자가 클래스를 보고, 객체를 생성
    3. Car("White", "auto", 4) 생성자 호출 및 객체 초기화
    4. 참조변수 c에 객체 주소 대입

생성자 this()

  • 생성자에서 다른 생성자를 호출할 때 사용
  • 다른 생성자 호출 시, 반드시 첫 줄에서만 사용 해야 한다.
  • 코드의 중복을 제거하기 위해 생성자들끼리 this()를 사용하여 호출.

생성자 this()와 참조변수 this는 서로 연관이 없음!

참조변수 this

  • 인스턴스 자신을 가리키는 참조변수. 인스턴스의 주소가 저장되어 있음.
  • 모든 인스턴스 메서드에 지역 변수로써 숨겨진 채로 존재한다. (선언 안해도 사용 가능)
  • 인스턴스 메서드(생성자 포함)에서만 사용 가능
  • 지역 변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용
  • iv는 원래 참조변수가 있어야 된다. (참조변수.변수이름) -> 같은 클래스 안에서는 생략이 가능하다.
  • static 메서드는 iv가 사용 불가이므로, this도 사용 불가임!
profile
블로그 이동하였습니당! -> https://kimsy8979.tistory.com/

0개의 댓글