-객체 배열: 객체를 원소로 하는 배열
-> 실제로는 객체의 레퍼런스를 원소로 갖는 배열!! (>>'레퍼런스 배열')
ex)```
Circle [] c; // Circle 배열에 대한 레퍼런스 변수 C 선언, []안에 배열의 크기 지정 X
c = new Circle[5]; //레퍼런스 배열 생성```
!! 레퍼런스로 저장할 배열을 생성.
Circle 객체를 생성하는 것이 Xx!
ex)```
for (i=0; i<c.length; i++){
c[i] = new Circle[i]; //배열의 각 원소개체 생성
}
```
--> 기본 타입 배열 생성과 객체 배열 생성은 다름!!
배열 C의 i번째 원소(=객체)에 접근하기 위해서는 C[i] 레퍼런스를 사용한다.
일반 배열 vs 객체 배열
//일반 정수형 배열 변수 intArr 생성
int[] intArr = new int[5];
//정의된 Example 객체에 대해 객체 배열 exArr 생성
Example[] exArr = new Example[5];
-> intArr 0 0 0 0 0
exArr Example객체 Example객체 Example객체 Example객체 Example객체
<선언>
클래스명[] 배열명;
클래스명 배열명[]; //일반 자료형의 배열 선언의 자료형 부분에 클래스명을 적어주는 차이!
<할당>
배열명 = new 클래스명[배열크기];
<선언과 동시에 할당>
클래스명 배열명[] = new 클래스명[배열크기];
->일반 배열: 동일한 자료형으로만 이루어져 있어 heap 메모리에 선언된 자료형 크기로 배열을 이룸
객체배열: 다른 자료형들(String, double, int 등)로 이루어질 수 있음 > 각기 다른 자료형 크기로 배열이 이루어져 있음! (처음에 배열을 동적할당 한 후 각 객체 인스턴스도 동적 메모리 할당을 함)
>객체 배열의 경우 초기화가 null에서 시작
객체를 배열에 하나 할당하면 객체의 참조 변수가 들어감
(일반 배열과 달리 참조 변수 단계를 하나 더 거침)
>일반 배열이 new 키워드를 한번 사용해서 배열을 메모리에 할당 & 사용
객체 배열은 배열을 만들 때 한번, 객체를 만들 때 한번,, 총 두번 new 키워드를 사용
ex)```
public class Main {
public static void main(String[] args) {
myObject[] arrayObj = new myObject[3];
// 사용할 수 없다
// arrayObj[0].id = 10;
arrayObj[0] = new myObject(101, "first array, John");
arrayObj[1] = new myObject(102, "second array, Mary");
arrayObj[2] = new myObject(103, "third array, Smith");
for (int i = 0; i < arrayObj.length; i++) {
System.out.println("arrayObj["+i+"] = " + arrayObj[i]);
}
arrayObj[0].showInfo();
arrayObj[1].showInfo();
arrayObj[2].showInfo();
}
}
class myObject{
int id;
String description;
myObject(){
}
public myObject(int id, String description) {
this.id = id;
this.description = description;
}
public void showInfo(){
System.out.println("(id) : " + id);
System.out.println("(description) : " + description);
}
}
[실행값]
arrayObj[0] = com.kay.myObject@12edcd21
arrayObj[1] = com.kay.myObject@34c45dca
arrayObj[2] = com.kay.myObject@52cc8049
(id) : 101
(description) : first array, John
(id) : 102
(description) : second array, Mary
(id) : 103
(description) : third array, Smith
```
-파일 1개당 클래스 1개,, 같은 패키지 안에 만들면 별도의 절차 없이도 같이 사용 가능
-메소드 : 클래스의 멤버 함수, 반드시 클래스 안에 있어야 함! (캡슐화 원칙)
>구성 형식:
1. 접근지정자-public, private, protected, 디폴트(접근지정자 생략)
2. 리턴타입
-자바의 인자 전달 방식: 값에의한 호출call-by-value (호출하는 실인자의 값이 복사되어 메소드의 매개변수에 전달됨)
1. 매개변수가 기본 타입으로 선언된 경우(기본 타입의 값 전달)
: 호출자(caller)가 건네는 값이 매개변수에 복사되어 전달, 메소드의 매개변수가 변경되어도 호출한 실인자값은 변경되지 X (C와 비슷)
2. **객체 또는 배열 전달** ⭐️
: 객체 또는 배열의 **레퍼런스 전달**! 통째로 복사되어 전달되는 것이 X
메소드의 매개변수와 호출한 실인자 **객체나 배열 공유**
(저쪽에서 변경 시키면 원래의 인자도 변경될 수 O!! -> 이를 피하려면 원본을 통째로 copy해서 사용해야 함,,)
-매개변수가 실인자의 객체 공유
-배열 레퍼런스로 전달
>장점: 아무리 큰 객체/배열도 하나의 정수 크기인 레퍼런스로 전달 가능, 시간 절약, 메모리 오버헤드 효율적으로 관리
>단점: **메소드에서 전달받은 객체의 필드/배열의 원소값을 변경할 수 X** (이거 변경하는건 위험!), 객체/배열의 정보가 변경될 수 O
-메소드 오버로딩Overloading : 이름이 같은 메소드 작성(매개변수의 개수&타입이 서로 다르고, 이름 동일)
>리턴 타입은 관련 X
-오버로딩된 메소드 호출: 자바 컴파일러는 각 호출문에 대하여 매개변수의 타입과 개수에 일치하는 해당 메소드를 찾는다.
-객체 소멸: new에 의해 할당된 객체 메모리를 자바 가상 기계의 가용 메모리로 되돌려주는 행위
>자바 응용프로그램에서 임의로 객체 소멸할 수 X, Java에서 메모리에 손대는 것을 허용하지 XX!
(임의 할당 & 회수 불가)
-> 안전하긴 하다,,
-가비지gabage: 레퍼런스가 하나도 없는 객체, 누구도 사용할 수 없게 된 메모리
-가비지 컬렉션gabage collection: 자바 가상 기계의 가비지 콜렉터가 자동으로 가비지 수집 반환 (메모리 관리 기법)
>자바에서 가비지를 자동 회수하여 가용 메모리로 반환한다.
알아서 가상 머신에서 주기적으로 함,, 신경쓸 필요 없다
-but! 개발자에 의한 강제 가비지 컬렉션
```
System.gc(); //가비지 컬렉션 작동 요청
//System 또는 Runtime 객체의 gc() 메소드 호출
```
-객체지향언어에는 접근지정자 존재!
: 객체를 캡슐화하기 때문에, 다른 객체가 특정 객체에 대해 접근 가능한지의 허용 여부를 지정할 필요 O (C에서는 X)
-패키지: 관련있는 클래스 파일(컴파일된 .class)을 저장하는 디렉토리(폴더)
-> 자바 응용 프로그램은 하나 이상의 패키지로 구성.
-자바 접근지정자 (4가지) : private, protected, public, 디폴트(접근지정자 생략)
캡슐화 정책 : 멤버를 보호하기 위함
접근 지정 : 캡슐화에 묶인 보호를 일부 해제할 목적
🌟
1. private: 외부로부터 완벽 차단
2. 디폴트: 동일패키지에 허용
3. protected: 동일패키지와 자식클래스에 허용 (상속받은 서브 클래스는 다른 클래스에 있어도 접근 O)
4. public: 모든 클래스에 허용
클래스 접근 지정 -> 다른 클래스가 해당 클래스를 사용하도록 허용할 지 지정
-static: 객체당 X, 클래스당 하나 생성!!
어떠한 값이 메모리에 한번 할당되어 program이 끝날 때까지 그 메모리에 값이 유지된다는 의미
>객체 간 공유는 통신으로 해야함,, (통신은 복잡해!)
-> 이때 객체가 공유하는 메모리가 있으면 편리.
>객체 생성여부와 관계 없이 static 이용할 수 O!
(객체 생성 전에 미리미리 메모리에 올려지므로)
비교
1. non-static 멤버 : 멤버들은 객체마다 독립적으로 별도 존재 (-> "인스턴스 멤버"), 필드/메소드는 객체 생성 후 비로소 사용 가능! (객체가 생성되어야 메모리에 존재하기 때문)
>클래스가 로딩될 때 공간 할당
>동일한 클래스의 모든 객체에 의해 공유-static 활용:
전역변수와 전역함수를 만들 때 활용
(전역변수 / 전역함수는 static으로 클래스에 작성)
>ex)```
public class Math{
public static int abs(int a);
..
}
//사용법
int n = Math.abs(-5);
//클래스 이름. (이때 같은 클래스면 클래스명 안붙여도 O)
```
공유멤버를 작성할 때 활용 (클래스에 객체들 공유)
-static 메소드는 non-static 멤버를 정의할 수 Xx
>객체가 생성되지 않아도 static 메소드는 실행될 수 O
--> non-static 메소드와 필드 사용 불가! (아직 안잡혀있으므로,,)
>**반대로 non-static 메소드는 static 멤버 사용 O**
(이미 객체 생성 전에 메모리에 static 멤버가 올라가 있으므로!)
-static 메소드는 this 사용 불가
-> static은 객체가 생성되지 않은 상황에서도 호출 가능하므로.. 현재 객체를 가리키는 this 레퍼런스를 사용할 수 X
-final : 클래스 상속 불가
-final 메소드 -> 오버라이딩 불가 (가져가서 수정한 후 다시 사용 Xx), 바꾸지 못하고 부모 클래스가 만든 대로 그대로 가져다 사용해야함!
-final 필드,, 상수 선언 -> 상수를 선언할 때 사용
->상수필드는 선언 시에 초기값을 지정해야 함! (실행 중에 값 변경 불가)
ex)```
public static final double PI = 3.14;
//C에서의 define문과 유사
```
-객체 지향의 상속 : 부모 클래스에 만들어진 필드, 메소드를 자식 클래스가 물려받음
>클래스의 간결화, 관리 용이, 소프트웨어의 생산성 향상
-자바의 상속 선언: extends 키워드 사용
>ex)```
public class Person {
..
}
public class Student extends Person {
..
}
public class StudentWorker extends Student {
..
}
//계층적으로 상속 가능
```
-서브 클래스는 슈퍼 클래스의 private 멤버를 제외하고 모든 멤버에 접근 가능!
-자바 상속 특징: 클래스의 다중 상속 XX!!
상속 횟수 무제한 (계층)
상속의 최상위 클래스는 java.lang.Object 클래스 (->다중상속 유일하게 예외)
객체 클래스 -> default로 상속,,
다중 상속: 부모 클래스를 여러 개 갖는 것
-상속관계에서 주의할 접근지정자 : private(아예 접근불가) & protected(자식클래스에 접근 허용)
->상속 받았을 때 접근지정자 유의해서 보기!