자료형과 메모리

- 기본자료형 && 지역변수 -> 스택에 저장됨, 자동으로 초기값이 설정되지 않음.
- 기본자료형 && 멤버변수/정적변수 -> 아직 안함
- 참조형 -> 값은 힙메모리에 저장됨
- 기본자료형이라도 참조형이면 자료형에 따라 자동 초기화
- 클래스들도 필드들이 자동 초기화됨

 

new 연산자

- String 클래스를 제외한 클래스, 배열, 인터페이스는 필수적으로 new 연산자 사용함
- 힙에 새로운 공간을 형성하라는 표시

 

참조형

- 클래스, 배열, 인터페이스, 열거타입(잘 쓰지 않음)
- 값이 힙메모리에 저장됨, 그 값이 저장된 영역의 시작주소를 스택메모리에서 가짐
- 힙메모리 : 동적으로 계속 공간을 늘릴 수 있는 특징

 

메모리 영역

- 스택 메모리 영역
- 힙 메모리 영역
- 메소드 메모리 영역

 

참조형

+ 인터페이스(자료구조)
- 대표적인게 List

 

배열 정리

- 동일한 자료형만 저장가능한 정적인 자료구조
- 정적 자료구조 = 크기가 딱 정해져 있음. new int[3] 하면 딱 3개만 생성
- 배열이름.length 속성 : 배열의 크기 = 배열 방의 개수 

 

배열 매개변수 예시1
- 메소드의 매개변수가 기본자료형이 아니라 참조형 중 배열일때

 

public static void main(String[] args) {

		int[] scores; // 여기 int[] scores ; 는 아직 주소를 가지지 않은 상태

		scores = new int[] { 83, 90, 87 };

		// int[] scores = new int[] {83,90,87}

		int sum1 = 0;
		for (int i = 0; i < 3; i++) {
			sum1 += scores[i];
		}
		System.out.println("총합 : " + sum1);

		// add 메소드를 호출해서, 리턴된 총합을 sum2에 저장
		int sum2 = add(new int[] { 83, 90, 87 });
		System.out.println("총합 : " + sum2);

	} // main() end

	// 사용자 정의 메소드 : 합을 구해주는 메소드 : 배열을 매개변수로
	public static int add(int[] scores) {
		int sum = 0;
		for (int i = 0; i < scores.length; i++) {
			sum += scores[i];
		}
		return sum;
	}

- int[] scores 는 주솟값을 가지지 못한 형태다
- 메소드의 매개변수가 참조형 중 배열이다.
- 이땐 배열의 주솟값을 전달해야함
- Call by Reference 방식으로 호출해야한다.
- 이 int 형 배열의 주솟값을 전달하자
- 매개변수자리에 클래스, 배열, 인터페이스 다 올 수 있다.

 

배열 매개변수 주의(위 예제의 부분)

 

	public static int add(int[] scores) {
		int sum = 0;
		for (int i = 0; i < scores.length; i++) {
			sum += scores[i];
		}
		return sum;
	}


	public static void main(String[] args) {

		int[] scores; // 여기 int[] scores ; 는 아직 주소를 가지지 않은 상태
	}

- main의 int[] scores 는 주솟값을 가지지 못한 형태다
- new 연산자를 써야만 새로운 공간을 힙메모리에 할당받는데 아직 안썼으므로
아직 주솟값이 없는 상태
- add함수로 전달하는 건 주솟값을 전달해야함 = Call by Reference

 

	public static void main(String[] args) {
		int sum2 = add(new int[] { 83, 90, 87 });
	}

- 이 경우엔 리턴받는게 없으니 이 공간은 재사용을 못한다
- 이렇게 해서 new를 써서 add 메소드로 주솟값을 전달함
- 힙 메모리 상에 있는 "같은 자료형 "(여기선 int형) 배열의 주솟값을 전달해야함
- new를 쓸때마다 새 공간이므로 이 sum2가 가리키는 new의 공간이랑 맨 위에 scores 이 가리키는 공간은 다른 주소이다
- 힙메모리상에 불필요하게 공간을 사용하는건 Garbage Collector 프로그램이 주소를 전달한 뒤 자동으로 지워버림 = 재사용 불가

 

+ 값 전달하는거보다 주솟값을 전달하는게 처리가 빠르다
+ C언어에선 이걸 포인터로 전달함

 

참조형인 매개변수 정리
- 주솟값을 할당받기 위해선 반드시 new 연산자가 있어야함
- String s= "자바" 가 가능하므로 String s 가 매개변수로 올때만 예외적으로 바로 check("자바") 로 호출 가능
- 또는 String s = new String("파이썬") 도 가능하므로 check(new String("파이썬") 으로 호출해도 된다.
- 다른 참조형 변수는 99% new를 써야함

메소드 정리
- 메소드 앞에는 return 자료형이 반드시 와야함
- 정적메소드이기 때문에 클래스명.add 또는 같은 클래스 내에선 .add 로 생략하고도 쓸수있다
- 정적메소드 아니면 객체를 생성후 호출해야한다.

배열 초기화 정리
- int뿐아니라 정수형 배열들은 다 0 으로 초기화 됨(char제외)
- 실수는 float 는 0.0f double 은 0.0
- 클래스/인터페이스/배열은 null로 초기화
* null : 주솟값이 없다는 의미


확장 for문 = 향상된 for문
- 순차적인 자료구조인 배열, 리스트같은 곳의 원소를 끄집어낼때 사용함
- 배열에 있는 값을 원소값이 더이상 없을떄까지 하나씩 왼쪽의 변수로 옮김
- 간결하기때문에 자주 씀

 

for( 타입 변수 : 순차적인 자료구조(배열,컬렉션)) {
             실행문 ;
}

* 타입변수 : 전달 받을 값 
* 컬렉션 = 자료구조(여기선 순차적인 자료구조를 의미), 대표적인게 리스트

 

확장 for문 예제

		int[] score = { 95, 71, 84, 93, 87 };


		// 확장 for문
		int sum1 = 0;
		for(int s : score) {
			sum1 += s;
		}

- 값을 받는 변수 s 도 배열의 자료형과 같은 int 형으로 받아야함
- score 배열에 들은 원소(값)들을 왼쪽의 s변수에 하나씩 전달, 이걸 원소값이 없을때까지 반복한다
- 전달된 값을 sum1 변수에 누적 

+ 순차적인 자료구조 :List, Vector
+ stack은 순차적인 자료구조 아님 다른 방식

 

main 메소드의 매개변수

- public static void main(String[] args){}
- JVM에서 여태껏 main 실행할때 아무 값 전달하지 않았음
- 하지만 전달 할 수도 있다.
- 전달시 args[0]에 첫번째 값이, args[1]에 두번째 값이 들어감
- String 자료형이므로 숫자를 적어도 문자로 처리됨

 

main 메소드의 매개변수 활용

package p2022_06_27;

public class ArrayEx07 {

	// 절대값을 구해주는 메소드
	static int abs(int data) {
		if (data < 0)
			data = -data;
		return data;
	}

	public static void main(String[] args) {

	// args[0] = "-10", args[1] = "-20"
		System.out.println("args[0] : " + args[0]);
		System.out.println("args[1] : " + args[1]);
	// args[0] = "-10" ---> -10 : 형변환(int로)
		int num = Integer.parseInt(args[0]);
		System.out.println("절대값 : " + abs(num));
	}

}

- 이 코드를 그냥 실행시 오류
- main 메소드 통해서 값을 전달할땐 그냥 실행시 오류가 생김
- 실행시키는 방법이 다름 ! (자주 쓰는건 아니지만 알아두기)

 

이클립스로 실행법
1. RUN 초록 화살표 버튼 마우스 대고 있으면  Run Configuration  메뉴 잇다
2. 두번째 탭인 arguments 선택
3. 위칸 program arguments 에서 -10 -20 을 입력(뛰어쓰기로 args[0] args[1] 값 구분)

- args[0]에 -10, args[1]에 -20 이 전달됨
- (-10)을 써도 String[] 이 매개변수이므로 문자인 "-10" 인것임
+이클립스가 아닌 콘솔창 자바 가상머신에서 실행시

java ArrayEx07 -10 -20

- 이렇게 실행함


의미 설명

1. java : 자바 가상머신 JVM
2. ArrayEx07 :ArrayEx07.class 란 바이트 코드를 실행함
3. -10 -20 이렇게 구분해서 입력

 

- args[0]에 -10, args[1]에 -20 이 전달됨
- (-10)을 써도 String[] 이 매개변수이므로 문자인 "-10" 인것임

 

자료형 변환

- 형변환된 값을 abs 메소드에 전달해야하는데 abs는 매개변수가 int 형이므로 그래서 문자를 숫자로 일단 변경하고 메소드 호출해야함.
-이걸 절대값 구할때는 args[]에 들은 데이터는 String은 문자열 이므로 int 로 바꿔야함
- "-10"을 숫자 -10 으로 바꿀땐 

int num = Integer.parseInt(args[0]); // 자주씀 외우기

- 자바의 3가지 자료형 변환 중 두번째 자료형 변환 방법임

 

Wrapper 클래스 (자료형 변환 원리)

- 기본자료형마다 Wrapper 클래스가 있다 .
- Integer 는 int 의 wrapper 클래스임
- 그래서 Integer.parseInt("20") 을 사용해서 문자 20을 숫자 20으로 변환
- Wrapper 클래스를 쓰면 기본자료형과 참조형 사이의 자료형 변환이 가능하다 (ex) string <-> int)
- 모두 java.lang 패키지안에 있어서 import 필요없다
-  Wrapper 클래스 쓰면 다른 자료형으로 쉽게 변환 가능

 

Wrapper Class

- boolean 은 Boolean
- byte 는 Byte
- char 은 Character
- int는 Integer

 

Wrapper 클래스를 이용한 변환 방법 2가지
1.

 int num = Integer.parseInt("20")


- pasreInt는 정적메소드라서 따로 객체 생성없이 클래스명. 으로 호출 parse() 안에는 String 자료형
2. 

Integer in01 = new Integer("20");
int num01 - int01.intValue();


- 언박싱

wrapper클래스의 주요 2가지 기능
1. String -> int (이게 거의 대부분임)
2. int -> String ex) String s - String.valueOf(20);

Integer 클래스 구조 (api 문서)
java.lang.Object
java.lang.Number
java.lang.Integer
- 최상위 클래스 = 슈퍼클래스는 Object
- 부모 클래스는 Number
- 상속 관계가 이미 다 형성되어있다.


1. Integer 의 필드(변수, 상수 의 개념)
- MAX_VALUE 쓰면 int형 변수가 가질 수 있는 최대값을 구해줌(정적필드) 약 +21억
- MIN_VALUE 스면 int형 변수가 가질 수 있는 최솟값을 구해줌


2. Integer 의 생성자
- 2개뿐


3. Integer의 메소드
- 메소드 중 pasreInt 는 2개가 있다 = 메소드 오버로딩
* 메소드 오버로딩 에서 이름은 같아도 매개변수등 구분이 되어야 잘 사용한것
- parseInt (String s) : 우리가 쓴 메소드 . 타입은 static int다 정적메소드이므로 Integer.parseInt로 사용하고, int 형 변수에 결과를 저장해서 돌려줌 매개변수 안엔 String 형만 들어가야함
- parseInt (String s, int radix) 도 있다.

+ 오라클등의 DB 연동할때 java.lang.Class 클래스 사용


배열을 복사하기
- 여러 방법 있다
1. for문
2. System.arrayCopy() 메소드
3. Arrays 클래스 이용

 

for문으로 배열 복사하기

public class ArrayEx08 {

	public static void main(String[] args) {

	//p167~p168
	//배열 복사 : for문으로 배열 복사
		
		int[] oldArray = {10,20,30}; //원본 배열
		int[] newArray = new int[5]; //새로운 배열
		
		for (int i = 0; i < oldArray.length; i++) {
			newArray[i] = oldArray[i]; //배열 복사
		}
		
		//복사된 배열 출력
		for(int i : newArray) {
			System.out.print(i + "\t");
		}
	}

}

- newArray는 배열이므로 0으로 다 초기화 된 상태
- oldArray -> newArray 로 복사할때 for문돌아가면서 10이 newArray[0] 으로 20이 newArra[1]으로 30이 newArray[2]로 복사됨
- 한줄 엔터키를 안쓰고 그냥 띄우기나 \t를 쓸때는 println이 아니라 print인점 주의

 

위 예제 그림

2차원 배열 정의방법 2가지

1.

int[][] score = new int[5][3];

- 메모리상에 값 저장위한 기억공간만 생성하고 그 값이 아직 뭔지 모를때 사용
- 2차원배열은 [][]처럼 2개임, [][]가 score 뒤에 가도 됨
- new란 연산자를 쓰는 형식
- 왼쪽, 오른쪽 자료형 같은걸로 맞추기
- 첫번째 괄호에 들어가는건 행의 수 (가로방향)
- 두번째 괄호에 들어가는건 열의 수 (세로방향)
- 4바이트짜리 기억공간을 행 5, 열 3으로 15개 생성하라는 뜻. 5행 3열짜리 기억공간 생성 

 

그림

2.

int[][] score = {{0,0,0},{0,0,0},{0,0,0}};

- 값이 고정되어있을때 쓰는 방식

 

예시

 

int [][] score = { { 85,  60,  70},      //0 행
	            { 90,  95,  80},       //1 행
	            { 75,  80, 100},       //2 행
                    { 80,  70,  95},       //3 행
	            {100,  65,  80} };     //4 행

- 0행 0열에 85, 4행 2열에 80이 들어감

 

2차원 배열 인덱스
- 행 = row = 가로번호
- 열 = colume = 세로번호
- 행 번호는 가로번호 의미
- 배열에 인덱스는 0번부터니까

배열 인덱스 예시

score[0][0] = 85; //0행0열에 85점을 할당하라
score[4][2] = 80; //4행2열에 80점을 할당하라

 

2차원 배열 입력/출력

 

public class Arr04 {

  public static void main(String[] args) {
   
    int [][]score = { { 85,  60,  70},   //0 행 = 1번학생
			{ 90,  95,  80},   //1 행 = 2번학생
			{ 75,  80, 100},   //2 행 = 3번학생  
                        { 80,  70,  95},   //3 행 = 4번학생
			{100,  65,  80}    //4 행 = 5번학생
					};
    int [] subject = new int[3]; //과목총점 저장할 1차원 배열
    int [] student = new int[5]; //학생의 총점 저장
        //    subject[0]=0, student[0]=0;
    int  r, c;  
	    
    System.out.println("각 과목별 총점구하기 "); //열방향으로 다 합쳐야
    for(c = 0; c < 3 ; c++){ // 과목         
      for(r = 0; r < 5 ; r++){ //학생      
        subject[c] += score[r][c];   
      }//subject[c]=subject[c]+score[r][c];
      System.out.println(subject[c]);  
    }

    System.out.println("학생별 총점구하기");
    for(r = 0; r < 5 ; r++){    //학생      
      for(c = 0; c < 3 ; c++){  //과목    
        student[r] += score[r][c];  
      }//student[r]=student[r]+score[r][c];
      System.out.println(student[r]);
    }

  }//main() end
}// class end

- 행 열을 따로 처리해야하므로 중첩 for문을 쓴다
- 행번호는 0~4이기 때문에 for문으로 0부터 시작해서 <5까지 즉 4까지 함, == 학생수는 5명
- 그 학생 당 과목 성적을 위해서 안쪽 for문으로 0부터 2까지 3번 돌림 == 과목수 3개(국영수)
- 행과 열이 만나는 곳의 점수를 출력하면 score[row][col]
- 더 빨리 바뀌는 부분이 for문의 안쪽에 와야함 나중에 움직이는 부분이 바깥쪽에
- 과목 총점 구하기는 [0][0] [1][0] [2][0] ... 을 더해야하고 ->과목은 열이기 때문에 for문 안쪽에 r 가 와야함
- 학생별 총점 구하기는 [0][0] [0][1] [0][2] ... 를 더해야함 -> 학생은 행이기 때문에 for문 안쪽에 c가 와야함
- int [] subject = new int [3] 이나 int [] student = new int[5]; 는 자동초기화 0 이므로 sum = 0 같은
번거로운일 할 필요 X

 


객체지향언어

 

클래스
- 클래스도 자료형이다
- 배열과 메모리상 처리는 거의 비슷함

String 클래스
- 클래스 중에서 쉽게 이해할 수 있는 String 클래스로 예시들어서 설명
- 클래스 중 사용빈도 가장 높음

String 클래스와 메모리
- String 클래스로 String 객체를 만든다
- 객체를 만들면 배열과 마찬가지로 문자열 " " 들은 모두 힙메모리상에 저장됨(참조형이 가지는 공통적인 특징)
- 그 메모리의 시작주소값을 변수가 스택에서 가지고 있다

 

String name;
name = "신용권"

- 그냥 이름을 저장하는것같아 보이지만 "신용권"은 힙의 공간에 저장, 그 주소를 가진 name은 스택에서 주소를 가지고 있다.

 

String 클래스와 메모리2
- String 클래스의 경우에는 문자를 바로 할당해도 되고 new 연산자를 사용해도 된다
- 이 두가지 되는건 String 밖에 없다
- 보통의 클래스는 new 연산자를 써서만 객체 만들어야함
- 하지만 new 연산 썼을때와 쓰지 않았을때 메모리에 차이가 있다.

String name1 = "신용권";
String name2 = "신용권";

- new 연산자를 쓰지 않고 만들면 처음 한번은 "신용권"을 저장한 기억공간을 힙메모리에 만듬
- 두번째의 경우에는 새로운 공간 만들지 않고 이미 "신용권"이 저장된 공간의 주솟값을 리턴받음
- name1 == name2 주솟값이 같다

 

String name1 = new String("신용권");
String name2 = new String("신용권");

- new 연산자를 쓰면 매번 새로운 공간을 힙메모리에 생성하라는 명시적인 표시
- new 연산자를 2번 썼기 때문에 새로운 공간이 2번 만들어짐
- 그림을 보면 힙 메모리상에 공간이 따로 따로 만들어짐
- name1 != name2 주소가 다르다

 

참조형의 비교

- 참조형들은 비교대상이 2개다
- name1 == name2 처럼 비교연산자로 주솟값을 비교
- equals() 란 메소드로 값들끼리 비교

 

주솟값 비교 예시

		String str1 = "자바";
		String str2 = "자바";

		if (str1 == str2) { //비교연산자(==)로 참조하는 주소를 비교
			System.out.println("같은 주소"); //같은 주소
		} else {
			System.out.println("다른 주소");
		}



		String str3 = new String("자바");
		String str4 = new String("자바");
		
		if (str3 == str4) { //비교연산자(==)로 참조하는 주소를 비교
			System.out.println("같은 주소"); //같은 주소
		} else {
			System.out.println("다른 주소");
		}

- 비교연산자(==)로 참조하는 주소를 비교

 

그림

값 비교 예시

		if(str1.equals(str2)){ // 참조하는 값(데이터)을 비교
			System.out.println("같은 값"); //같은 값
		}else {
			System.out.println("다른 값");
		}

- 값비교 equals() 메소드를 사용
- 같으면 true를 반환

 

참조형의 비교 정리

- 비교연산자(==) : 참조하는 주소를 비교
- equals() : 참조하는 값(데이터)을 비교

 

+ 메소드를 찾는 법
ex) equals() 메소드를 어디서 찾아야할까
1. 1차적으로 api에서 equals() 메소드가 어디 붙어있는지 보자 -> String
2. String클래스 찾아야
3. String클래스 안에 없으면 그거 조상들 클래스를 찾아야
- String의 경우엔 부모가 java.lang.Object가 최상위 클래스 , 자기 부모 클래스 임. 
- String 안에 없더라도 조상이 그 메소드를 가지고 있으면 상속 받아 string 객체에서도사용할 수 있다.
- 만약 String클래스도 String의 부모클래스에도 equals()없다면 그건 없는 것임.

+ 클래스 구조
- 필드 1개 있고 생성자있다
- 생성자 : 객체를 생성할때 자동으로 호출되는 메서드, 클래스와 같은 이름이다.

 

String 클래스 구조 생성자
- 우리는 매개변수가 String으로 된 생성자를 호출해왔었음 String(String original) 을 써왔던것

 

String str3 = new String("자바")

- 에서 오른쪽은 String은 생성자를 호출하는 것임
- 생성자는 없으면 못씀 제공되는것만 쓸 수 있다

 

String 클래스 구조 메소드
- String 클래스 안 메소드 많다(기능 많다 )
- equals() 메소드의 리턴타입은 boolean, 값이 같으면 true, 다르면 false를 리턴해줌
- 그래서 이 메소드 자체를 if문 안에 넣었던 것

 

Object 클래스와 equals()

- equals() 메소드의 매개변수는 Object
- 자바의 가장 최상위 클래스가 Object임 = 슈퍼클래스= 최상위 부모 클래스
- 패키지가 엄청 많지만 그게 뭐든지 가장 위는 Object 
- 즉, Object 는 모든 클래스의 최상위 부모, 조상
- equals() 메소드 매개변수가 equals(Object anObject) 
- 값을 비교할때 Object의 자식들은 다 equals 안에 들어갈 수 있다. 모든 클래스 다 들어갈 수 있다.
- 즉, equals() 괄호 안에 int, boolean, String등 다 들어갈 수 있다
- String뿐만 아니라 Object의 자식들은 모두 비교 equals로 비교가능, 즉 모든 자료형 다 비교 가능

 

예시1

		boolean b = "자바".equals("파이썬");
		if(b) {
			System.out.println("같은 값");
		}else {
			System.out.println("다른 값");
		}

- 가능함
- 3번째 자료형형변환 방법, 레퍼런스 관련이 있다

 

예시2

		if(new Integer(30).equals(30)){
			System.out.println("같은 값");
		}else {
			System.out.println("다른 값");			
		}

- int형끼리 비교도 가능하다.
- int, double, boolean 등 모든 걸 equals 로 비교 가능
- wrapper 클래스 , 오토박싱,오토언박싱 등의 개념 앞으로 공부하는것과 연관

 

객체배열
- 객체의 주소를 참조하는(저장하는) 배열
- C++은 많이 쓰지만 String은 많이 쓰진 않음 객체배열보다 성능 좋은 list등이 있기 때문에

 

ex) String객체를 3개 저장하기 위한 배열 = 객체배열

		String[] strArray = new String[3]; // 객체배열
		strArray[0] = "Java";
		strArray[1] = "Java";
		strArray[2] = new String("Java");

- 이렇게 객체 생성시시에 2가지 방법 써서 가능
- 0번방, 1번방 가리키는 "Java"는 같은 곳임
- 0번방, 2번방 가리키는 "Java"는 서로 다른 곳음

		System.out.println(strArray[0] == strArray[1]); //주소값을 비교, true
		System.out.println(strArray[0] == strArray[2]); //주소값을 비교, false
		System.out.println(strArray[0].equals(strArray[2])); //값을 비교, true

 

사용자 정의 클래스
- String 클래스와 비슷한 방식으로 메모리상 처리가 됨

객체 지향 프로그래밍(OOP)
- 부품 객체를 먼저 만들고 이것들을 하나씩 조립해 완성된 프로그램을 만드는 기법

객체
- 물리적으로 존재하는 모든게 객체가 될 수 있다 ex) 자동차, 사람, 책
- 추상적인 것도 객체가 될 수 있다 ex) 회사, 날짜
- 현실세계에선 사람이란 객체가 있을때 사람에 대한 속성이 있다 ex)나이, 이름 => 속성
- 사람이란 객체가 있을때 있는 동작 ex) 달린다, 걷는다 => 메소드

객체 모델링
- 자바같은 객체지향언어에선 객체 모델링이란 작업을 수행한다
- 사람이란 객체의 속성을 표현할때는 '필드'라는걸가지고 속성을 나타남
- 메소드 바깥쪽에 쓰는 변수 = 멤버변수 = 필드 변수 = 객체의 속성 나타냄
- 메소드를 가지고 객체의 동작을 표현함

현실세계의 자동차 객체
- 필드를 가지고 객체의 속성에 대한 것들을 표현
- 속성 : 색상, 속도 -> '필드' 로 표현함, 필드는 쉽게 말하면 멤버변수임
- 필드는 메소드 바깥쪽에 정의되는 변수로서 멤버변수라고 불린다. 자바에선 필드라고 불림
- 동작 : 메소드를 가지고 표현. 달린다 멈춘다 등의 동작을 메소드로 표현

객체 지향 프로그래밍이 가지는 특징
1. 캡슐화
- 한개의 클래스가 만들어져 있을때 외부클래스에서 접근하지 못하도록 캡슐로 보호를 한다.
- 캡슐화위해선 접근제어자로 접근을 허용을 하기도하고 허용을 하지않기도 한다.
ex) private 써서 외부로부터 접근 막음 = 캡슐화로 안전하게 안의 정보를 보호함

2. 상속
- api에서 제공되는 클래스는 이미 상속관계 정의 다 된 상태임.
- 상속을 함으로서 중복적인 코드를 많이 줄일 수 있다
- 또 유지보수를 편리하게 해주는 기능을 제공하기때문에 상속을 많이 사용함.

ex) 부모 클래스가 있고 자식 클래스가 있을떄
- 클래스 = 필드, 메소드, 생성자 로 구성
- 상속이 되는건 2가지 뿐! 필드와 메소드만 상속이 되고! 생성자는 상속되지 않음!

3. 다형성(Polymorphism)
- 부모로부터 상속받은 것들을 다양한 형태로 바꿔서 쓴다는 것

객체와 클래스
- 설계도 역할을 하는게 클래스다
- 현실세계 : 설계도 -> 객체  를 만들어냄 (ex)설계도로 자동차를만들어냄)
- 자바 : 클래스 -> 객체. 설계도역할하는게 클래스, 클래스 가지고 객체를 무한히 많이 만들어 낼수 있다.

클래스 이름
- 하나이상의 문자로 이루어져야
- 변수명과 마찬가지로 첫번째 글자는 숫자올수없다 ex) Car 3Car (x)
- $나 _ 외의 특수문자 사용불가
- 자바 키워드는 사용할 수 없다
- 변수명,함수명,클래스명등은 한글명으로 클래스 명 쓰는건 바람직하지 않다. 웹으로 가면 여러 문제 발생!

클래스와 소스파일
- 이클립스에서 클래스를 만들면 소스파일이 생성됨 클래스이름.java 가 생성됨
- 이걸 javac.exe가 컴파일 해줘서 클래스이름.class 생성됨
- 앞으로는 한개의 .java 파일에 클래스가 여러개가 들어가는 소스파일 .java 을 만들것
- 소스 파일 당 public class 는 1개만 사용가능함! 이 public 을 가진 클래스와 파일명을 일치시켜야함
- 클래스명과 파일명이 일치되어야하는데 단, 이때 메인메소드를 가진 클래스명과 파일명을 일치 시켜야함
- 컴파일이 되면 파일 안의 여러개 클래스가 각각 따로 따로 .class 파일들로 만들어짐(클래스 수만큼)

객체 생성

new 클래스();

- 클래스와 동일한 이름의 생성자를 호출하라는 코드
- 생성된 객체는 힙메모리상에 객체가 생성됨
- new 연산자는 객체를 생성후 객체 생성 주솟값을 리턴하므로, 왼쪽의 변수가 그 주솟값을 갖고있게됨

 

객체 생성 방법 2가지

1.

클래스 변수;
변수 = new 클래스();

2.

클래스 변수 = new 클래스();

- 한줄

 

클래스 구성 멤버와 역할
- 필드 : 변수기때문에 메모리상의 값을 저장하는 역할
- 생성자 : 객체가 생성시 호출되며 필드값을 초기화하는 역할
- 메소드 : 객체의 동작적인 걸 표현하는 역할

사용자 정의 클래스
- api 에 있는 클래스를 모방하여 생성
- 메소드 바깥쪽에 사용되는 변수 = 필드 = 멤버변수, 변수기때문에 값을 저장함, 속성을 표현
- 생성자는 클래스명과 동일한 이름으로 만들어야함. 객체가 생성될때 생성자가 호출되며
필드값을 초기화시키는게 생성자의 역할
- 메소드는 객체에 대한 동작을 나타냄, ex) public void static main

 

정리
메인 메소드 안의 변수 = 지역변수 = 스택메모리 = 메소드종료시 삭제
메소드 밖의 변수 = 멤버변수 = 필드 = 전역변수 = 힙 메모리 = 초기화

 

사용자정의 클래스 만들기 예시

 

public class Animal {
//Animal 은 사용자 정의 클래스(자료형)

	
	int age; //자바에선 멤버변수, 필드(field) 라고 한다. C에선 전역변수라고 부른다.
		// : 메소드 바깥쪽에 정의되는 변수
	
	public static void main(String[] args) {

	}

}

- age는 메소드 바깥에 있고, 이 클래스 전역에 사용 가능
- 멤버변수= 필드 = 전역변수 는 메모리 중 힙메모리 상에 저장됨!
- 클래스도 참조형이기 때문에 int age; 는 힙메모리상의 공간을 할당받고 초기화 0 으로 자동초기화됨

 

* JAVA구조 : 클래스 내에 메소드가 있다

 

생성자
- 멤버 함수 중 하나
- 반드시 클래스명과 동일한 이름으로 생성해야함.
- () 괄호가 반드시 있어야한다.
- 생성자명앞에는 접근제어자만 올 수 있다.

기본생성자(default constructor)
- 생성자 중 매개변수가 없는 생성자

 

	int age; 
	public Animal() {
		System.out.println("생성자 호출 성공");
	}

 

사용자 정의 클래스와 클래스의 구조 3가지

 

public class Animal {
//Animal 은 사용자 정의 클래스(자료형)

	
	int age; //필드
	public Animal() { //생성자
		System.out.println("생성자 호출 성공");
	} 
	
	public static void main(String[] args) {  //메소드
		
		int a = 10;

	}

}

- 필드, 생성자, 메소드가 다 있는형태
- 생성자는 주로 객체생성과 동시에 필드값의 초기화를 설정하기 위한 용도로 객체가 생성될때 호출되면서 실행
+ a는 지역변수, stack 메모리 영역에 저장, 이 메소드 안에서만 사용가능
+ 지역변수와 멤버변수는 스택과 힙 이라는 다른 공간에 저장되는것 뿐만 아니라 메모리상에 저장되는 영역과 할당되는 시점이 다름

 

	public static void main(String[] args) {

		int a = 10; //지역변수
		String str = new String("자바");
		Animal a1 = new Animal();
	}

+ 이 main메소드는 Animal 클래스 내부임. Animal 클래스 내부에 Animal 클래스로 객체 만들어도 된다.

 

그림

필드 접근

    Animal     a1         =   new       Animal();
// 클래스 레퍼런스변수 연산자 생성자호출

- 이렇게 객체를 생성시 4바이트짜리 Animal 클래스의 '필드'를 저장하기 위한 기억공간을 힙에 생성함
- 그 필드는 age (=0 , 자동초기화) 이다. 그 주솟값을 a1이 가지고 있는 상태
- a1이 age가 저장된 힙메모리상의 시작주솟값을 가지고 있다.
- 이 a1으로 접근해야지만 이 age에 접근가능하다!

 

System.out.println(age); // 불가능
System.out.println(a1.age); // 로 해야함

- 반드시 a1이 가진 주소 이용해서 a1.age로 접근해야함!
- 객체 생성될때마다 새로운 age만들어지므로 어느 영역에 있는 age인지 알 수 없기 떄문이다

- age의 값을 수정하고 싶을때도  a1.age로 접근해서 수정해야한다

		a1.age = 5;
		System.out.println(a1.age); //5가 출력됨

 

생성자 호출

- 오른쪽의 Animal() 은 생성자를 호출하라는 코드임

	public Animal() {
		System.out.println("생성자 호출 성공");
	}

- 출력이 됨

 

생성자를 안쓴다면?
- 기본으로 알아서 생성해줌 

 

객체 생성2

ex) 이번에는 Animal 클래스로 다시 new 연산자로 다시 객체 생성해보자

		Animal a2 = new Animal();
		System.out.println(a2.age);

- 이러면 힙메모리상에 새로운 공간이 또 생성됨!

- 그림 참고

 

그림

- a1이 가진 주소와 a2가 가진 주소를 비교해보자

		if (a1 == a2) {
			System.out.println("같은 주소");
		} else {
			System.out.println("다른 주소");
		}
출력 : 다른 주소

- new로 힙메모리에 새로운 공간을 만들었기 때문이다

+ Recent posts