추상화와 구조체
추상화
구현할 대상을 프로그래밍적으로 꼭 필요한 부분만 단순화 시키는 것
구조체
추상화를 통해 프로그래밍적으로 활용할 특정 요소만 저장한 하나의 자료단위
사람{
String name;
int age;
int height;
}
구조체를 메서드로 편하게 다루는 법
해당 구조체에 있는 요소를 하나하나 검색하기 불편하기 때문에
System.out.println(구조체.name);
System.out.println(구조체.age);
System.out.println(구조체.gender);
그래서 특정 구조체 전용 메서드를 만든다
public static void getHumanInfo(구조체 변수명){
System.out.println(변수명.name);
System.out.println(변수명.age);
System.out.println(변수명.gender);
}
위 메서드를 한줄로 호출만 해도 3줄에 달하는 이름, 나이, 성별 호출구문을 완성시킬수 있다.
getHumanInfo(구조체);
클래스
구조체 전용 함수를 구조체 내부에 배치하면, 활용처가 명확해지며 호출도 안전해진다.
-> 특정 구조체용 함수를 구조체 내부에 선언한 것을 클래스라고 부른다.
자바에서 클래스는 객체를 만들기 위한 틀이다
- 클래스의 변수 : 객체의 속성
- 클래스의 메서드 : 객체의 기능
★★★★★★★★★★★★★★
객체 생성 new
클래스명 변수명 = new 클래스();
★★★★★★★★★★★★★★
- new 키워드는 "힙"에 해당 자료를 생성하고 자료의 주소를 리턴한다
멤버변수와 지역변수
- 멤버변수: 클래스 안에 선언된 변수
초기화를 하지 않아도 자동으로 각 데이터 타입의 기본값으로 자동 초기화된다.
- 지역변수: 메서드 안에 선언된 변수
메서드 블록 밖에서는 사용 불가. 사용하기 전에 반드시 초기화 필요
생성자
클래스의 생성자
사용자가 필수 필드에 강제로 값을 채우도록 강요해야하기에, 생성자 함수를 클래스 내부에 정의한다
class 클래스명{
클래스명(){
// 생성자 함수
}
}
- 파이썬에서의 선언법
def __init__():
실행문...
생성자 : 객체가 생성될 때 객체의 상태(멤버변수)를 초기화하는데 사용
- 객체가 생성될 때 new 키워드 다음에 오는 것
반드시 클래스 안에 하나 이상 선언해야 하며, 만일 생성자를 만들지 않을 경우 자바 가상 머신(JVM)이 대신해서 기본 생성자를 자동으로 하나 만든다
기본 생성자 : 매개 변수를 가지지 않는 기본 형태의 생성자
ex) Pen() { }
생성자를 만드는 규칙
- 생성자의 이름은 클래스 이름과 대/소문자까지 정확히 같아야한다. 달라진다면 메서드로 간주한다.
- 생성자는 메서드와는 달리 반환 유형을 적지 않는다
- 생성자는 다른 유형으로 여러개 생성 가능하다 (생성자 오버로딩)
Garbage Collecting
- 객체를 생성하는데 사용되는 키워드는 new, 생성된 객체를 메모리에서 해제시키는 키워드는 존재하지 않는다.
- 자바 가상머신(JVM)이 메모리 관리를 해준다
- 객체가 더 이상 프로그램에서 사용되지 않으면 (스택과의 연결이 끊어져서 호출이 불가능하다면) 가비지 컬렉터가 스스로 판단하여 메모리를 해제하고 수거한다.
패키지 (package)
** 클래스의 2종류 **
- 개발자가 직접 만들어 사용하는 사용자 정의 클래스
- JDK 안에 포함되어 있거나, 다른 개발자들이 미리 만들어 놓은 클래스
-> 이런 클래스는 종류가 많고 비슷한 기능들을 분류 시켜야 할 필요성이 있기에, 서로 관계가 있는 클래스들을 패키지로 묶어서 관리한다.
현재 클래스에서 다른 패키지의 외부 클래스를 사용하고 싶은 경우,
import
키워드로 해당 클래스 전체 경로를 지정해줘야한다.
ex)import java.util.Scanner;
해당 패키지 안에 들어있는 모든 클래스를 사용하고 싶은 경우,
*
기호를 넣어준다.
ex)import java.util.*;
*package 선언 방법 *
- 클래스의 가장 윗 부분에 패키지 구문을 포함시킨다.
ex)package store;
- 패키지 이름은 영문 소문자로 지정하는 것을 권장
- 대분류와 소분류 패키지를 구분할 때는
.
을 사용한다 - 최상위 패키지의 이름은 java로 시작 X.
-> java 패키지는 표준 API들의 모음을 구성해놓은 패키지이다.
5. 자바의 키워드는 패키지 이름으로 사용 X
기본타입 (primitive type) vs 참조타입 (reference type)
** 기본 타입 **
정수, 실수, 문자, 논리 값을 저장하는 데이터 타입
- 실제 값을 변수 안에 저장
** 참조 타입 **
객체의 주소를 참조하는 타입.
배열, 클래스, 인터페이스 타입을 말한다
- 메모리의 주소 값을 변수 안에 저장
- stack 영역에 주소값 저장, 내부의 실제 값은 heap 영역에 저장한다.
복사의 두가지 유형
* 얕은 복사 *
기본형 변수 : 단순 대입으로도 값 복사가 일어나지만
int a = 5;
int b = a;// b에 a변수에 들어있던 값인 5 대입
참조형 변수 : 주소값만 복사가 일어나고, 실제 heap 영역에 있는 자료는 복사되지 않는다.
int[] a = {1, 2, 3, 4, 5}
int[] b = a; // a가 저장중인 주소값 복사가 일어남
참조형 변수 간 대입연산자 사용 시, 주소값만 복사하는 행위를 얕은 복사라고 부른다.
=> 얕은 복사가 이뤄지면 같은 자료를 두 개의 변수가 동시에 조회하기 때문에
a[0] = 99;
두 변수가 모두 영향을 받는 문제가 발생한다.
* 깊은 복사 *
깊은 복사 : 스택에서 주소값을 복사 받는 것이 아니라, heap 쪽에 실제 자료를 복사 대상과 똑같이 하나 더 할당한 다음, 새롭게 할당된 자료의 주소를 변수에 대입한다.
int[] a = {1, 2, 3};
int[] b = a.clone(); // .clone(), .copy() 등을 보편적으로 깊은 복사에서 사용한다
=> 하나의 자료 값을 변경해도 다른 하나는 영향을 받지 않는다
위의 원리로 인해,
배열에서 단순 명령어를 찍으면 주소값이 출력되기 때문에 Arrary.toString
을 사용해야한다.
package equal.array;
import java.util.Arrays;
public class ArraryEqualsTest {
public static void main(String[] args) {
//배열은 참조형 변수이기 때문에 단순 대입 시 문제가 발생한다
int[] intArray1 = {1,2,3,4,5};
System.out.println("배열 1의 주소 : " +intArray1);
// 배열도 참조형 변수이므로 주소가 아닌 실제 자료를 조회하려
// Array.toString(배열자료) 형식으로 호출해야 한다.
System.out.println(Arrays.toString(intArray1));
}
}
참조타입 String과 객체 동등 비교 메서드 equals()
자바는 문자열이 동일하다면 String 객체를 공유하도록 되어있다.
그래서 단순히 문자열을 String 변수에 할당한다면 같은 주소값을 갖게 된다
ex.String str1 = "Hello"; String str2 = "Hello"; // str1 == str2 => true
new 키워드를 사용하여 String 객체를 직접 heap 영역에 생성한다면, 문자열의 내용이 같더라도 다른 주소값을 가지게 되므로 동등==, 비동등!= 연산자의 결과가 false로 나오게 된다
ex.String str3 = new String("Hello"); String st4 = new String("Hello"); / str3 == str4 => false
- 동일 String 객체이든, 다른 String 객체이든 상관없이 문자열의 내용값 그 자체를 비교할 때는 equals() 메서드를 사용해야한다.
'Programing🤖 > JAVA' 카테고리의 다른 글
[JAVA] 추상 클래스 (0) | 2024.08.23 |
---|---|
[JAVA] 접근제한자와 상속 (0) | 2024.08.23 |
[JAVA] 함수와 메서드 (0) | 2024.08.23 |
[JAVA] 제어 (0) | 2024.08.23 |
[JAVA] 변수와 자료 (0) | 2024.08.23 |