728x90
230720 객체지향 프로그래밍 - 객체
JVM 메모리 구조
JVM 메모리 구조
- Java 언어는 메모리 관리를 개발자가 하지 않음
- GC (Garbage Collection) 가 메모리 관리
Garbage Collection
- Heap 영역 (class 영역 포함) 에 생성된 메모리 관리 담당
- 더이상 사용되지 않는 객체들을 점검하여 제거
- 자동적 실행/CPU가 한가 or 메모리 부족
- JVM에 의해서 실행
System.gc()
를 통해 호출 (시스템 영향을 줘서 하지 않기…)
객체 생성과 메모리 할당
Person p1 = new Person();
p1.name = "Yang";
p1.age = 45;
p1.hobby = "유튜브";
클래스 영역 = 메소드 영역: 클래스 안에 있는 메소드가 들어가기 때문에 메소드 영역이라고도 함
static 특징
대체 미리 쓸 수 있다는 게 무슨 말임?????? static으로 선언하면 설계도에 같이 넣어서 이전에~~ non-static은 그때그때 선언할 때마다 할당된다.
- 로딩 시점
- static: 클래스 로딩 시…
- non-static: 객체 생성 시
- 메모리 상의 차이
- static: 클래스당 하나의 메모리 공간만 할당 → 미리 class를 선언하기 때문에 class 안에 인스턴스들을 할당해서 메모리 공간 차지가 적음
- non-static: 인스턴스 당 메모리가 별도로 할당 → 인스턴스 하나마다 메모리 각각 할당
- 문법적 특징
- static: 클래스 이름으로 접근
- non-static: 객체 생성 후 접근
왜 인스턴스가 아니라 클래스 이름으로 접근하는 것을 권장할까?public class PersonTest { public static void main(String[] args) { Person p new Person(); p.name = "Kim"; Person.pCount ++; p.pCount++; //오류는 나지 않지만 경고... 무슨 말임?? }
static → 인스턴스 생성 없이 접근할 수 있는 공유 메모리여서?
여러개의 인스턴스가 생성되어 있을 때는 어떻게 할까? 인스턴스로 접근해도 노란 줄 없음~~ public class Person { static int pCount; String name; int age; String hobby; }
- static 영역에서는 non-static 영역을 직접 접근이 불가능static: 미리 메모리에 올라가 있어서 인스턴스 생성 여부 관계 X
- non-static: 인스턴스가 만들어져야 쓸 수 있는 것, 만들어지기 전까지 메모리에 올라가지 않기 때문에 static에서는 접근할 수 없음 (당연한 말..)
public class Main { String str = "문장"; public static void main(String[] args) { System.out.println(str); } }
- non-static 영역에서는 static 영역에 대한 접근이 가능non-static을 실행할 때 static 영역에 해당하는 것들은 이미 올라가 있기 때문에 접근할 수 있음
public class Main { static String str = "문장"; public void print() { System.out.println(str); } }
접근 제한자
패키지
패키지
- PC의 많은 파일을 관리하기 위해서 폴더를 이용한다
- 프로그램의 많은 클래스를 관리하기 위해서 패키지를 이용한다
- 패키지는 클래스와 관련 있는 인터페이스들을 모아두기 위한 이름 공간
- 패키지의 구분은 .(dot) 연산자를 이용한다
pkg1.pkg2.pkg3
: pkg1 안에 pkg2 안에 pkg3
pkg1 에서 main을 실행하더라도import pkg1.pkg2.Person;
해서 pkg1의 Person을 사용하는 것이 아닌 pkg2의 Person을 사용할 수 있다
만약 둘 다 쓰고 싶다면?
내부적으로 같은 이름의 클래스이지만 다른 친구를 사용할 수는 없을까?import pkg1.pkg2.Person; import pkg1.Person;
→ 풀패키지명으로 자료형을 적어주면 된다.
하지만 이렇게 하기 너무 불편하기 때문에…pkg1.Person p1 = new pkg.Person; pkg1.pkg2.Person p2 = new pkg1.pkg2.Person(); pkg1.pkg2.pkg3.Person p1 = new pkg1.pkg2.pkg3.Person();
**같은 이름을 쓰는 것을 지양합시다~!**
- 패키지의 이름은 시중에 나와 있는 패키지들과 구분되게 지어야 한다
- 일반적으로 소속이나 회사의 도메인을 사용한다.
com.ssafy.project_이름.module_이름
임포트
임포트
- 다른 패키지에 있는 클래스를 사용하기 위해서는 import 과정이 필요하다
package com.ssafy.project.service; import com.ssafy.project.dto.Person; public class PersonService { Person p; }
PersonService.java
에서 Person 클래스를 사용하기 위해서는 import 해야 한다.- import를 선언할 때는 import 키워드 뒤에 package 이름과 클래스 이름을 모두 입력하거나, 해당 패키지의 모든 클래스를 포함할 때는 ‘*’를 사용하기도 한다.
★ 하위 패키지에 있는 것들은 다른 공간의 친구들이라 가져올 수 없어! 하위 패키지에 접근하고 가져와야 함import package_name.class_name; import package_name.*; // *: 모두 가져오라는 뜻
캡슐화 (Encapsulation)
public class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat() {
System.out.println("음식을 먹는다.");
}
}
Person p = new Person ("김싸피", 28);
이런 일이 가능한 이유는 무엇일까?
캡슐화
- 객체의 속성(data fields)과 행위(메서드, methods)를 하나로 묶고
- 실제 구현 내용 일부를 외부에 감추어 은닉한다
접근 제한자 (access modifier)
- 클래스, 멤버 변수, 멤버 메서드 등의 선언부에서 접근 허용 범위를 지정하는 역할의 키워드
- 접근 제한자의 종류
- public: 모든 위치에서 접근 가능
- protected: 별로 사용할 일이 없을 것이에요
→ 같은 패키지 - 접근 가능
→ 다른 패키지 - 불가능
→ 단, 다른 패키지의 클래스와 상속관계가 있을 경우 접근 가능 - (default)
→ 같은 패키지 - 접근 허용
→ 접근제한자가 선언이 안 되었을 경우 기본 적용 - private
→ 자신 클래스에서만 접근 허용
클래스(외부) 사용 가능: public, default
내부 클래스, 멤버변수, 메소드 사용가능: 4가지 모두 가능
- 그 외 제한자
- static: 클래스 레벨의 요소 설정
- final: 요소를 더 이상 수정할 수 없게 함
- abstract: 추상 메서드 및 추상 클래스 작성
- …
| 수식어 | 클래스 내부 | 동일 패키지 | (다른 패키지 내의)
하위 클래스 | 다른 패키지 |
| --- | --- | --- | --- | --- |
| private | O | | | |
| (default) | O | O | | |
| protected | O | O | O | |
| public | O | O | O | O |
접근자(getter) / 설정자(setter)
- 클래스에서 선언된 변수 중 접근제한에 의해 접근할 수 없는 변수의 경우 다른 클래스에서 접근할 수 없기 때문에 접근하기 위한 메서드(설정자와 접근자)를 public으로 선언하여 사용
public class Person { private String name; private int age; //접근자 public String getName() { return name; } //설정자 public void setName(String name) { this.name = name; } //접근자, boolean 타입의 getter는 is를 쓰는 것이 국룰~ isHungry~ public int getAge() { return age; } //설정자 public void setAge(int age) { this.age = age; }
객체 배열 관리
싱글턴 패턴 (Singleton Pattern)
객체가 딱 하나만 필요할 때!!
- 소프트웨어 디자인 패턴에서 싱글턴 패턴(Singleton pattern)을 따르는 클래스는 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴//static으로 미리 올려 놓는다면? --> public static ... -> instance 변수를 가져올 수 없기 때문에 에러 남
→private static Person
로 instance도 static으로 미리 선언해야 됨여기서 p1과 p2는 같은가?**YES**
같은 인스턴스 값을 가져오기 때문에! (singleton의 경우에만 해당되는 듯) main Person p1 = Person.getInstance(); Person p2 = Person.getInstance();
public class Manager { //외부에서 생성하지 못하게 막아버림!11 생성자에 private을 걸어버령 //기본 생성자를 작성하고 접근 제한자를 private으로 만들어 private static Manager manager = new Manager(); //가지고 있고 싶을 때 private Person () {}; private Person instance = new Person(); //이렇게 선언하는 것도 private String name = "Yang"; //이런 식으로 선언하는 거랑 같음 //외부에서 나의 instance에 접근해서 사용할 수 있게 하는 메소드 public Person getInstance() { //미리 선언하지 않고 이런 식으로 조건문을 활용해서, instance가 존재하지 않을 경우 -> 만들어서 return // if (instance == null) // instance = new Person() return instance; } private Manager() {} public static Manager getManager() { return manager; } }
객체 배열 관리
객체 배열 관리란?
- 정보 관리 시스템 ex) 학사 관리 시스템
- 캡슐화를 이용하여 클래스 작성
- DB 대신 배열을 사용해 객체의 정보를 저장
- 객체의 조회, 추가, 수정, 삭제(CRUD)를 구현
- 싱글턴 패턴을 사용하여 정보 관리 일원화
728x90
'Java > 기본 문법' 카테고리의 다른 글
JAVA 객체지향 프로그래밍 - 다형성 (0) | 2023.08.10 |
---|---|
JAVA 객체지향 프로그래밍 - 상속 (0) | 2023.08.10 |
JAVA 객체지향 프로그래밍 - 클래스와 메소드 (0) | 2023.08.09 |
JAVA 문법: 배열 (0) | 2023.08.09 |
JAVA 기본 문법: 변수와 자료형, 형 변환, 연산자, 제어/반복문 (0) | 2023.07.25 |