본문 바로가기
클라우드 활용 자바개발자 양성과정/01. JAVA 프로그래밍 언어 활용

06. 객체

by moca7 2024. 6. 27.

 

ㅁ 자바에서 힙 영역에 올라가는 모든 것들을 객체라고 함. 

 

ㅁ 객체

- 사전적 정의 : 현실 세계에 존재하는 독립적인 존재 (유형, 무형, 개념, 감정, ...)

객체간의 상호작용으로 현실세계는 돌아감

- 자바에서의 정의 : Heap 메모리에 올라가는 모든 것들

 

ㅁ 객체지향 프로그래밍

- 현실세계에서 객체들간의 상호작용을 프로그래밍을 통해서 가상세계로 구현하는 과정

ex) 인터넷 쇼핑몰 ( 객체 == 회원, 상품, ... / 상호작용 == 구매한다)

 

ㅁ 구현하고자 하는 프로그램 상의 필요한 객체들을 만들기 위해서 (즉, 생성하기 위해)

- 클래스라는 틀을 먼저 작성할 수 있어야 함.

(클래스 : 각 객체들의 정보(속성, 기능)들을 담아낼 그릇같은 존재)

- 클래스를 만들기 위해 추상화 과정과 캡슐화 과정을 거친다.

 

ㅁ 추상화 과정

- 구현하고자하는 프로그램상에 필요한 객체들을 생각

- 그 객체들이 가지는 공통적인 속성, 기능들을 모두 추출

- 추출한 것들을 가지고 내가 구현하고자 했던 프로그램의 "실질적인 목적"에 맞춰서 추려줌

(추상화 과정은 불필요한 것들을 제거하는 과정)

- 추려진 것들을 가지고 어떤 자료형, 어떤 변수명으로 사용할 건지 생각

 

ex) 학생 관리 프로그램

- 학생 객체(홍길동, 김영희, 김말똥, ...)

- 이름, 나이, 주소, 전화번호, 머리색깔, 발사이즈, ...

- 학생 "인적사항"을 관리하는 프로그램 : 이름, 나이, 주소, 전화번호, 학년, 반

  학생 "성적"을 관리하는 프로그램 : 이름, 학년, 반, 국어점수, 영어점수, ..

  학생 "건강"을 관리하는 프로그램 : 이름, 학년, 반, 몸무게, 키, ...

 

내가 어떤 프로그램을 만들지 생각해보고 그때 필요한 것들만 추려낸다.

결국 추려진게 이름, 나이, 키 라는 가정 하에

이름 : String name, 나이 : int age, 키 : double height

 

ㅁ 본격적인 프로그래밍

(1) 변수만을 가지고 프로그래밍

(변수 : 하나의 자료형에 하나의 값을 보관할 수 있음)

- 홍길동이라는 학생 객체, 김말똥이라는 학생 객체, 강개순 이라는 학생 객체에 각각 이름, 나이, 키 변수에 값을 저장.

- 문제점 : 다수의 변수를 관리해야 하는 번거로움. 반복문 활용도 불가.

 

(2) 배열을 가지고 프로그래밍

- 그럼 여러 값을 담을 수 있는 배열을 사용.

(배열 : 하나의 자료형의 여러개의 값을 보관할 수 있음)

[생략된것 있음]

- 문제점 : 실수로 데이터를 덜 지우게 되면 학생 데이터가 변질될 수 있음

새로운 데이터를 추가하고자 할 경우 배열의 크기를 늘릴 수가 없어서 새로운 배열을 만들고 이관하는 작업을 매번 해야 함.

 

(3) 구조체

- 자바에서 구조체를 제공하진 않음.

- 구조체 : 여러 개의 자료형의 여러 개의 값들을 보관할 수 있는 개념.

String도 보관, int도 보관, double도 보관하는 나만의 자료형(구조체 개념)을 만든게 클래스다.

(이를 사용자 정의 자료형이라고도 함)

 

- 객체의 정보들을 담아낼 수 있는 클래스를 model.vo 패키지에 보관하곤 함.

value object의 약자. 객체의 값을 담아낼수 있는 클래스를 보관하는 패키지.

 

- VO (Value Object) : 객체의 값(속성/정보)들을 담아낼 그릇과도 같은 존재의 클래스 

 

 

 

 

ㅁ < 클래스 구조 >

 

public class 클래스명 {

 

    // 필드부 (필드 = 멤버변수 = 인스턴스 변수)

 

    // 생성자부

 

    // 메소드부 (메소드 = 멤버메소드)

 

}

 

 

(1) 필드부

- 데이터를 저장할 수 있는 변수 선언부분

- 변수 선언할 때 메소드 영역에 들어가서 하는게 아니고,

클래스 영역 안에 무언가(필드, 생성자, 메소드)를 작성할 때는 항상 접근제한자를 붙여줘야 한다.

 

접근제한자 자료형 변수명;

 

 

/*
 * < 필드 >
 * 
 * 1. 표현법
 *    접근제한자 [예약어] 자료형 변수명 [= 값];
 *    
 * 2. 변수 종류
 *  ㄴ멤버변수 | 인스턴스변수 : 객체생성시 메모리에 할당 / 객체 소멸시 함께 소멸
 *  ㄴ클래스변수 | static변수 : 프로그램 실행시 메모리에 할당 / 프로그램 종료시 소멸
 * 
 * 3. 접근제한자
 *    public > protected > default > private
 *    
 * 4. 예약어
 *  ㄴstatic : 공유의 개념 (쉐어할 변수)
 *  ㄴfinal  : 상수의 개념 (상수 변수)
 *  ㄴstatic final : 상수필드 (공유도 하는데 변경은 불가하도록)
 */

 

/*
 * < 생성자 >
 * 
 * 1. 표현법
 *    public 생성자명([매개변수, 매개변수, ..]) {
 *     [실행내용;]
 *    }
 *    
 * 2. 생성자 목적
 *  ㄴ객체 생성을 위해
 *  ㄴ객체 생성과 동시에 각 필드에 값을 대입(초기화)하기 위해
 * 
 * 3. 유의사항
 *  ㄴ생성자명은 클래스명과 동일하게 작성
 *  ㄴ반환형 기술 x 
 *  ㄴ매개변수 생성자 작성시 기본생성자를 JVM이 만들어주지 않음
 * 
 * 4. 추가
 *  ㄴ생성자 내에서 또다른 생성자 호출시 this() 이용해서 호출 
 *    단, 해당 구문은 첫문장으로 작성
 * 
 */

 

/*
 * < 메소드 >
 * 
 * 1. 표현법
 *    접근제한자 [예약어] 반환형 메소드명([매개변수, 매개변수, ..]) {
 *     실행내용
 *    }
 *    
 * 2. 멤버변수 관리하는 메소드
 *  ㄴgetter메소드 : 멤버변수에 담긴 값을 반환하는 목적의 메소드
 *  ㄴsetter메소드 : 멤버변수에 값을 대입하기 위한 목적의 메소드
 * 
 * > 추가적인 메소드 더 작성 가능
 *   단, 멤버변수와 밀접하게 연관되어있는 코드를 작성
 * 
 */

 

 

 

 

 

 

- 필드라고도 얘기하고 멤버변수라고도 함. 인스턴스 변수라고도 함. 보통은 앞 2개를 씀. 

- 인스턴스 변수가 뭐냐면 자바에서 생성된 객체를 인스턴스라고 한다.

Student 클래스는 객체생성을 해야만 메모리상에 할당이 되죠.

그래서 객체 생성된 후에 만들어진 변수다 해서 인스턴스 변수라고 얘기한다.

 

- 필드부에서는 변수 선언하듯이 하면 되는데, 자료형 변수명;이 아니라 접근제한자를 써줘야 함.

접근제한자 String name;

- 변수는 값을 초기화하는 습관을 가지라했는데, 멤버변수(필드)는 오히려 초기화를 안하고 씀.

 

 

- 자바에서 객체는 힙이라는 메모리 영역에 올라간다.

객체를 만들기 위해서는 힙이라는 메모리 영역에 공간을 만들어줘야 한다.

 

 

- 기본 자료형이 아닌 형태로 선언된 변수에는 전부 참조값이 담긴다. 

- 힙이라는 영역의 특성상 빈공간이 없다. 전부 초기화가 되어있다.

 

 

ㅁ 객체 생성 과정

- 스택 영역은 변수들이 쌓이는 영역. 힙 영역은 객체들이 올라가는 영역.

- Student hong = new Student();

           (1)         (3)        (2)

 

 

(1) 스택 영역에 hong이라는 박스 하나가 생긴다. 얘의 타입이 Student이다.

기본자료형을 제외한 나머지 자료형으로 선언된 변수는 주소값이 담긴다고 했죠. 즉 얘는 참조변수(레퍼런스 변수)다.

 

(2) new를 만나는 순간 힙이라는 영역에 공간이 만들어 진다.

정의되어 있는 필드 만큼의 공간이 만들어 진다. 

Student 클래스에는 String 필드, int 필드, double 필드가 있다.

그럼 세칸짜리 공간이 만들어진다. 그런데 칸 크기는 다르다. 배열처럼 똑같진 않다. 배열이 아니니 인덱스 개념은 없다.

대신 각각의 방을 구분할 수 있는게 필드명이다. 인덱스 개념없이 필드명으로 각각의 방을 구분한다.

 

 

 

- 클래스를 만들고 객체화하면 마치 배열의형태처럼 생성이된다.

다양한 자료형의 다양한 값들을 담을 수 있다. 그래서 사용자 정의 자료형이라고 한다.

- 그리고 힙이라는 영역 특성상 절대 빈공간은 없다. 

그래서 개발자가 초기화하지 않는 이상 jvm이 직접 초기화까지 진행을 해준다.

그때 각각의 타입에 맞춰서 초기화한다. String이니까 null, int니까 0, double이니까 0.0으로 초기화한다.

- 그리고 힙영역에 생성된 객체는 얘를 찾을 수 있는 주소지 하나가 부여된다. 0x123

 

 

(3) 대입연산자 수행

- (2)번에서 만들어진 게 통째로 대입되는게 아니고, 주소값이 (1)에 대입된다.

hong에는 0x123이라는 주소값이 담기게 된다. 

그럼 hong이 힙영역의 객체를 참조한다고 표현할 수 있다.

- hong이라는 변수 하나만으로 학생 정보를 다 관리할 수 있다.

 

 

 

ㅁ 객체와 배열의 차이점

- 객체는 다양한 자료형의 다양한 데이터를 담을 수 있다.

- 인덱스 개념이 없다.

 

 

 

 

 

 

 

 

 

 

ㅁ 다른 패키지의 클래스 쓸 때, import하기 싫으면 com.br.~~.클래스명 쓰면 된다.

클래스의 전체 이름을 사용하여 해당 클래스를 참조할 수 있습니다.

전체 이름은 패키지명.클래스명의 형식으로 작성됩니다.

 

이 프로젝트 내에서는 다른 패키지의 클래스를 이렇게 사용할 수 있다.

 

 

 

 

 

 

 

 

 

ㅁ 이클립스에서 print문으로 객체를 출력하면 아래와 같이 출력된다.

 

com.br.chap01_abstarction.model.vo.Student@7a81197d

 

자료형@주소값의16진수형태

 

 

 

 

ㅁ 메소드도 멤버 메소드라고함.

ㅁ 메소드의 표현법

- 접근제한자 [예약어(생략가능)] 반환형 메소드명([매개변수]) { //기능 구현 }

ㅁ setter 메소드 이름 setName으로 해야 협업에도 좋고, 프레임워크에서 자동호출할때도 이 이름이어야 잘된다. 

보통 setXXX로 쓴다.

 

ㅁ 필드(멤버변수) 수만큼 게터 세터 메서드들 만들어야 한다. 

필드는 private으로 선언해야 한다.

필드가 7개라면 전부 private으로 선언하고, 게터7개 세터7개 만드는게 기본이다.

 

ㅁ 인스턴스화할 때 필드의 개수만큼 힙영역에 공간이 생김.

 

ㅁ 변수명이 pName인 경우, getter setter 메서드 명을 어떻게 하냐면, setpName 이렇게 그대로 써야 한다. 꼭.

이 메서드명 하나때문에 프로그램이 제대로 동작안할 수 있다. 특히 나중에 프레임워크하면 대신 해주는게 많기 때문에. 자동으로 값이 대입되는 경우가 많다. 우리가 메소드를 호출하지 않아도.

ㅁ 매개변수는 보통 초기화하고자하는 변수 이름이랑 같게 한다.

 

public String information() {

return "pName : " + pName + " , price : " + price + ", brand : " + brand;

 

- 이렇게 한번에 다 가져올 수도 있다.

그런데 이렇게 메소드를 정의했다 하더라도 getter 메소드는 꼭 만들어야 한다.

나중에 변수 하나만 궁금할 수도 있으니까.

- 이게 하나의 문자열을 반환하는거다.

 

ㅁ 객체 생성을 해야 해당 객체의 멤버(메ㅔㅁ버 변수, 멤버 메서드)에 접근 가능하다.

물론 접근제한자에 따라 직접접근이냐 간접접근이냐 다름. 

ㅁ 멤버 변수는 초기화안해도 JVM이 기본값초기화해준다. 

  • 변수 초기화: 변수를 선언할 때 바로 초기화하는 것이 좋습니다.
  • 멤버 변수: 클래스 내부에 선언된 변수는 멤버 변수로, 보통 선언만 하고 생성자나 초기화 블록에서 초기화합니다.

 

변수를 선언할 때 초기화하는 것이 좋습니다. 이는 코드를 더 읽기 쉽고 유지보수하기 쉽게 만들어줍니다. 변수를 선언하고 초기화하는 방법은 다음과 같습니다:

 

클래스 내부에서 선언된 변수는 멤버 변수라고 부릅니다. 이러한 변수들은 클래스의 인스턴스(객체)가 생성될 때 초기화됩니다. 멤버 변수는 보통 선언할 때 초기화하지 않고, 객체가 생성될 때 생성자나 초기화 블록에서 초기화하는 것이 일반적입니다. 

 

ㅁ 매개변수는 영어로 parameter. 영어로 말하느 ㄴ사람도 많다. 

 

ㅁ 멤버변수(인스턴스 변수)랑 매개변수는 초기화 안해도 기본값으로 사용 가능.

지역변수는 사용 안됨.

 

객체생성을 하는 순간 전역변수는 jvm이 초기화함. 

메소드를 호출하는 순간 매개변수도 메소드에 전달된 값으로 초기화 됨.

지역변수는 내가 직접 값을 대입하지 않는이상 초기화가 안 됨.

그래서 지역변수는 내가 값을 초기화하는 습관을 가져야 함.

( println으로 위 둘은 되는데 마지막 하나느 안됌)

 

멤버변수 출력: 해당 객체 생성시 jvm이 초기화를 진행해줌.

매개변수 출력: 해당 메소드 호출시 전달된 값으로 초기화가 진행되어있을 것

지역변수 출력: 직접 초기화를 진행해둬야함.

 

ㅁ 필드 및 메소드에서는 4개의 접근제한자가 있음.

클래스 선언에는 public과 default만 있다. 

 

ㅁ 클래스 변수 == static 변수

- 클래스 영역(static 영역)에 저장되는 변수

- 인스턴스를 생서하지 않아도 메모리 상에 이미 할당되어 있음

 

ㅁ 상수 필드

- 초기화 구문을 같이 기술해야 한다.

- 그리고 상수는 static final이다

- 그냥 final은 final 필드인거지 상수 필드는 아니다. https://kephilab.tistory.com/51

 

- 메소드 내부에 static 변수 선언 불가.

static 변수는 클래스 레벨에서 정의되며, 메소드 내부에서 사용할 수 없습니다.

- 만약 상수를 메소드 내에서 사용하고 싶다면, 일반적으로 메소드 내부에서는 final 키워드를 사용하여 지역 변수로 선언하고 초기화하는 방법이 있습니다. 이는 해당 변수가 한 번 초기화되면 다시 할당되지 않음을 보장합니다.

 

ㅁ 생성자의 작성목적

- 객체를 생성하기 위한 목적 - 기본생성자 작성 (그냥 객체를 생성하기만 하는 목적이면 기본생성자 작성ㅎ아면 됨)

- 객체[ 생성과 동시에 각 필드에 초기화할 목적 - 매개변수생성자 작성

 

ㅁ 생성자 내에서 또다른 생성자를 호출하고자 한다면 그 문장을 반드시 첫 문장으로 기술해야 한다. 

 

ㅁ 언제 매개변수 있는 생성자를 만들지 모르니 습관적으로 기본생성자를 항상 작성하는 습관을 들이자.

매개 변수 있는 생성자를 명시적으로 작성하면 기본생성자를 jvm이 자동으로 만들어주지 않음. 

 

ㅁ 필드

- 변수 종류에는 멤버변수(인스턴스변수)랑 클래스변수(static변수)가 있다.

 

ㅁ 예약어

- static

- fianl 

 

ㅁ 클래스 다이어그램

- static 메소드는ㄴ 밑줄이 그어져있음

 

ㅁ 

- 클래스 구조는 필드부, 생성자부, 메서드부로 나뉘어짐.

- 필드부에 쓸수있는 변수는 2가지. 멤버변수와 클래스변수.

 

ㅁ static변수는 쉐어할 목적으로 만든거기때문에 객체를 만들 필요 없이 그냥 쓰면 된다.

 

ㅁ 예약어

- static 공유의 개념 쉐어할 변수

- final 상수의 개념 상수 변수

- static final 상수필드로 선언하는것 공유도 하나ㅡㄴ 데변경은 불가

 

ㅁ 

- 추가로 메서드를 준다면 최대한 멤ㅁ버변수를 활용하는 메서등여야 한다.

 

ㅁ private String[] ingredient;

- public String[] getIngredient() { return ingredient; } <- 게터메소드

- 배열 객체가 통째로 넘어가는게 아니고, 배열 객체의 주소값을 반환

- public void setIngredient(String[] ingredient){    <- 세터메소드

this.ingredient = ingredient; }

- 이것도 주소값이 넘어가는거.

 

ㅁ 필드르 ㄹ추가하면 항상 게터세터도 같이 추가해주셔야 함. 

 

ㅁ 생성자로 배열을 만들고 전달하는게 아니고, 곧바로 배열을 생성해서 전달하는 법.

- String[] ingredient =  {"알코올", "정제수", "색소"};

Cosmetic cos = new Cosmetic("스킨", 15000, "아벤느", "기초", ingredient);

대신

- Cosmetic cos = new Cosmetic("스킨", 15000, "아벤느", "기초", {"알코올", "정제수", "색소"} };

이건 안됨.  

Cosmetic cos = new Cosmetic("스킨", 15000, "아벤느", "기초", new String[] {"알코올", "정제수", "색소"} };

생성과 동시에 초기화한 배열 객체를 전달하고 한다면 중괄호만 쓰면 안되고, 생성하느 ㄴ구문과 함께 전달해야 함.

 

ㅁ information메소드 만들때 참조자료형이 있다면 널포인터익셉션 발생할 수 있으므로,

public String information() {

    return "bakeryName : "+bakeryName+", bakeryAddr : "+bakeryAddr+"bread : "+bread;

}

이 아닌

 

public String information() {

    String str = "bakeryName : "+bakeryName+", bakeryAddr : "+bakeryAddr;

    if(bread != null) {

         str += ", 판매하는 빵 : "+bread.information();

    }

    return str;

}

 

ㅁ 

System.out.println(bakery4.getBread().information());

System.out.println(bakery4.getBread().getPrice());

System.out.println(bakery4.getBread().getName());

- bakery가 가진 bread가 private임. bread의 price와 name도 private임.

그래서 get이 두번들어감. 

 

ㅁ 클래스마다 각각의 기능별로 독립시켜야 함. 유지보수하기 힘들어져서.

- 패키지 controller가 mvc패턴 중 하나.

 

 

ㅁ 메소드

ㅁ 가변 매개변수

- 전달되는 값의 갯수가 정해져있지 않을 경우

 

public void method5(int... params){    // params는 사실 int[]배열임

    System.out.println("method 5: "+params);           //          배열이라 주소값이 나온다.

}

외부에서 호출할 때 

method5(3);

method5(3, 4, 5); 도 가능. 

 

- 가변인자는 메서드 정의에서 마지막 매개변수로 선언될 수 있으며, 배열 형태로 인자들을 전달받습니다.

숫자 하나만 전달받으면 숫자 하나가 담긴 배열이 만들어지는 것.
여러개 받으면 여러개가 담긴 배열이고. 

 

ㅁ /** 하고 엔터(혹은 shift alt j)

- 자동으로 현재 메서드에 맞춰서 파라미터에 대한 정보와 리턴에 대한 정보가 주석문으로 만들어짐.

- 파란 블럭 주석생김. 습관을 들이는 것이 좋습니다.

- 미리 등록해놔야되는듯. 

- 또 자동완성으로 볼 때 주석내용이 보인다고 함. 

 

ㅁ static이 붙은 메서드는 프로그램 실행과 동시에 메모리에 올라가 있기 때문에 객체를 생성할 필요가 없음. 

- static 메서드는 이클립스에서 살짝 기울여져있음. 

 

ㅁ 오버로딩

- 반환형, 접근제한자는 상관없음. 메소드명은 같은데 매개변수의 자료형이나 개수가 다른 경우만. (순서도 다른경우도 포함)