상속(inheritance) 이란?

: 부모의 생물학적 특성을 물려받는 유전과 유사하다고 생각할 수 있습니다. 즉, 부모클래스에 만들어진 필드, 메소드를 자식클래스가 물려받는 것을 의미합니다. 상속을 통해 간결한 자식 클래스 작성하게 되면 동일한 특성을 재정의할 필요가 없어 자식 클래스가 간결하게 만들 수 있습니다.

 

 

위의 예시와 같이 상속이 없는 경우 중복된 멤버를 가진4 개의 클래스 만들어야 합니다.

 

 

상속을 이용한 경우 중복이 제거되고 클래스의 구조가 간결해집니다.

 

 

상속의 장점

 

1) 클래스의 간결화

: 멤버의 중복 작성이 불필요 합니다.

 

2) 클래스 관리 용이

: 클래스들이 계층적으로 분류됩니다.

 

3) 소프트웨어의 생산성 향상

: 클래스 재사용과 확장 용이합니다.

: 새로운 클래스의 작성 속도가 빠르게 진행됩니다.

 

● 상속 선언하기

: extends 키워드 사용하여 상속 받습니다.

public class Person {
}
public class Student extends Person { // Person을 상속받는 클래스 Student 선언
}
public class StudentWorker extends Student { // Student를 상속받는 StudentWorker 선언
}

 

● 상속자와 접근제어어 사용

 

위와 같이 저장되어있는 class를 상속 받았을 때 각각의 접근제어어의 수행결과를 알아보겠습니다.

 

1) private

System.out.println("num1 = " + num1); 
error : private(접근불가) - 정보 은닉이 우선순위로 작동 

 

2) default

System.out.println("num2 = " + num2);
error : default - 같은 package 안에 있어야 함으로 다른 package에서 접근 불가.

 

3) protected

System.out.println("num3 = " + num3 );
protected int num3;(접근가능) 부모와 자식의 상속 관계 이므로 error 나지 않는다. 

 

4) public

System.out.println("num4 = " + num4);
public int num4; (접근가능) 어디서든 호출 가능. 

 

추가설명 )

참조자료형 field는 private 으로 method 는 public 으로 한다고 합니다. 그 이유는?

 

- method를 통해서 접근 할 수 있도록 하는 이유 내가 만든 것이기 때문에 조건을 제시하여 값을 체크할 수 있는 안정성을 확보 하도록 하기 위함입니다.

-  field 로 접근하도록 하면 정보 은닉 및 변경이 가능해지기 때문에 접근하지 못하도록 하는 것입니다.

 

● 서브클래스에서 슈퍼 클래스의 멤버 접근

 

 

 

● 자바 상속의 특징

- 기존에 정의된 클래스에 메소드와 변수를 추가하여 새로운 클래스를 정의하는 것입니다. (문법적 측면에서의 상속)

 

1) 클래스의 다중 상속을 지원하지 않습니다.

 

2) 상속 횟수는 무제한 입니다.

 

3) 상속의 최상위 클래스는 java.lang.object 클래스 입니다.

 

 - 모든 클래스는 자동으로 java.lang.Object상속받습니다.

 - 자바 컴파일러에 의해 자동으로 이루어집니다.

 

추가 설명)

new에 의해 자녀 클래스의 객체가 생성될 때, 부모 클래스 생성자와 자녀 클래스 생성자 모두 실행됩니다.

호출 순서 : 자녀 클래스의 생성자가 먼저 호출, 자녀 클래스의 생성자는 실행 전 부모 클래스 생성자 호출합니다.

○실행 순서 : 부모 클래스의 생성자가 먼저 실행된 후 자녀 클래스의 생성자 실행합니다.

 

 

 

● 상속 관계에 있는 인스턴스의 생성 예 

class Adder { 
		public static int val = 0; 
		Adder(){}
		public void add(int num) {
			val += num; }
}
	class AdderFriend extends Adder{
		AdderFriend(){super();} 
		public void friendAdd(int num) {val += num ;}	
			public void showVal() {System.out.println(val);}
    }

 class Adder 가 부모 class 이고, AdderFriend 가 자식 class로 extends Adder(class Adder의 값을 자신의 값으로 확장)사용하여 상속 관계를 만듭니다.

 

그때, 자식 class가 부모의 class를 field 를 초기화 해줘야하는 의무를 가지고 있는데, 생성자는 직접 가져 올수도 없고, java에서 선언하는 것이 때문에 super() 라는 예약어를 사용하여 그 의무를 수행합니다.  

 

super() : 자녀 클래스에서 명시적으로 부모 클래스의 생성자 선택 호출합니다.

- 인자를 이용하여 부모 클래스의 적당한 생성자 호출합니다.

- 반드시 자녀 클래스 생성자 코드의 제일 첫 라인에 와야 합니다.

 

 

● 상속을 위한 기본 조건인  IS-A 관계의 성립 

 

1) 상속 관계에 있는 두 클래스 사이에는 IS-A  관계가 성립해야 합니다.

 

2) IS-A 관계가 성립하지 않는 경우에는 상속의 타당성을 면밀히 검토해야 합니다.

 

3) IS-A 이외에 HAS-A 관계도 상속으로 표현 합니다. 그러나 HAS-A를 대신해서 Composition 관계를 유지하는 것이

   보다 적절한 경우가 많습니다. 

 

○ IS - A 관계의 예

package 상속;

class Computer{
	 Computer(){	 
	 }
}
class Notebook extends  Computer{
	Notebook(){
		super();
		}
}
class TabletPC extends Notebook{
	TabletPC(){
		super();
		}
}

노트북 is a 컴퓨터 - 노트북은 컴퓨터를 상속하고 , 테블릿 is a 노트북  - 테블릿은 노트북을 상속하는 것입니다.

일반적으로 IS-A 관계가 성립되면, 불필요한 상 속관계는 형성될 수 있으나, 잘못된 상속관계가 형성된다고는 이야기하지 않습니다.

 

○ HAS-A

상속은 강한 연결고리를 형성합니다. 그렇기 때문에 총을 소유하지 않는 경찰, 또는 총이 아닌 경찰봉을 소유하는 경찰등 다양한 표현에 한계를 가질 수 있습니다. 복합관계는 강한 연결 고리를 형성하지 않습니다. 따라서 HAS -A 관계는 복합관계로 표현하는 것또한 좋은 방법입니다.

 

 

 

'빅데이터 > JAVA' 카테고리의 다른 글

[JAVA] Abstract 클래스, Interface  (0) 2020.05.13
[JAVA] 메서드 오버라이딩(Method Overriding) , Instanceof연산자  (0) 2020.05.07
[JAVA] 콘솔 출력  (0) 2020.05.04
[JAVA] 배열 (array)  (0) 2020.05.02
[JAVA] String  (0) 2020.05.02

Escape Sequence

: 문자열 안에서 특별한 의미로 해석되는 문자를 가리켜 ‘이스케이프 시퀀스’라 합니다.

 

대표적인 종류

- (\") : 역슬레시와 큰따옴표를 사용해서 문자열화 시켜줍니다.

 문자열에 (" ") 싶을 때는?
System.out.println("친구가 어제\"잘 다녀왔어?\"라고 물어서...");	
(\") 역슬레시와 큰따옴표를 사용해서 문자열화 시켜줍니다. (\"잘 다녀왔어?\")


출력값 : 친구가 어제"잘 다녀왔어?"라고 물어서...

 

- (\t) : 탭(tab) 만큼 띄어쓰기 합니다. (4칸)

System.out.println("친구가 어제 \t 잘 다녀왔어 \t 라고 물어서...");	
(\t) 탭(tab) 만큼 띄어쓰기가 됩니다.  (4칸)
        
출력값 : 친구가 어제 	 잘 다녀왔어 	 라고 물어서...

 

- (\n) : 다음줄로 넘어가서 출력 시켜줍니다.

System.out.println("친구가 어제 \n 잘 다녀왔어 \n 라고 물어서...");	
(\n) 다음줄로 넘어가서 출력 시켜줍니다. 

출력값 = 
친구가 어제 
잘 다녀왔어 
라고 물어서...

 

- (\\) : \를 사용해야할 때, 1번 사용하면 error 가 발생하므로 \\ 두번 사용합니다.

System.out.println("C:\workspaces\JAVA"); // error
(\) 역슬레시 뒤에 ", t, n 이 올거라고 java 는 생각하는데 오지 않아서 error가 납니다. 

해결점 (\\) 역슬레시 두번 사용
System.out.println("C:\\workspaces\\JAVA"); 

출력값 : C:\workspaces\JAVA

 

- (') 작은 따옴표는 문제없이 사용됩니다.

System.out.println("친구가 어제 '잘 다녀왔어? ' 라고 물어서...");	
(') 작은 따옴표는 문제없이 사용합니다.

 

 

 

● System.out.printf; 

: 메소드는 문자열의 중간에 삽입될 데이터를 가지고 하나의 문자열을 조합해서 출력합니다.

 

int age = 20;
double tall = 175.7;
String name = "홍길동";

위의 조건을 충족시키는 예시를 들어보겠습니다.

 

 대표 : 문자열 %s , 정수 %d , 실수 %f

System.out.printf("제 이름은 %s 이고, 나이는 %d 살이고, 키는 %.2f 입니다.\n",name, age, tall);
%.nf 소수점 n자리 까지 출력하게 만듭니다. 

출력값 : 제 이름은 홍길동 이고, 나이는 20 살이고, 키는 175.70 입니다.

 

기타 )

System.out.printf("%d, 0x%x,  0%o \n" , 100, 100,100);
정수의 값을 16진수로 출력  0x%x , 8진수로 출력  0%o
		
출력값 : 100, 0x64,  0144         
        
System.out.printf("%g, %g \n", 0.00014, 0.000014); 
출력의 대상에 따라서 %e 또는 %f 형태로 출력한다. 
		
출력값 : 0.000140000, 1.40000e-05         

 

 

 

● Scanner의 활용

: scanner 는 keyboard 의 입력만 받는 것이 아니라 다양한 리소스를 입력 받을 수 있도록 정의 되어있습니다.

 

- 문자형(수치형 데이터)으로 되어 있는 정수로 변환해서 반환합니다.

public class StringScanner {
public static void main(String[] args) {
	
String source = "1 5 7"; 
	
Scanner scanner = new Scanner(source); 
		
int num1 = scanner.nextInt(); // 자료형 String  을 int  로 변환
int num2 = scanner.nextInt();
int num3 = scanner.nextInt();
int sum = num1 + num2 + num3; 	

System.out.printf
("문자열에 저정되어 있는 num1 = %d , num2 = %d , num3 = %d , sum = %d"
				     , num1, num2, num3, sum);		
	}
}


결과값 : 문자열에 저정되어 있는 num1 = 1 , num2 = 5 , num3 = 7 , sum = 13

- 위의 경우 String의 source를 입력 받아 int 형으로 변환해서 반환할 수 있도록 해줍니다.

 

 

 

StringTokenizer

: java.util.StringTokenizer에 저장되어 있으며, 하나의 문자열을 여러 문자열로 분리할 때 사용합니다.

 

문자열을 분리할 때 사용되는 기준 문자 : 구분 문자(delimiter)

- 다음 예에서 ‘&’가 구분 문

String query = "name=kitae&addr=seoul&age=21";
StringTokenizer st = new StringTokenizer(query, "&");

토큰(token) = 구분 문자로 분리된 문자

 

 

-  StringTokenizer의 정형화 되어있는 형태

package 콘솔;
import java.util.StringTokenizer;
public class TokenizerString01 {

	public static void main(String[] args) {
		
		String data = "11:22:33:44:55"; // : 단위로 데이터가 저장.
				
		StringTokenizer st = new StringTokenizer(data, ":"); // 데이터 구분단위 지정
				
		while(st.hasMoreTokens()) { // hasMoreTokens : 데이터가 존재하는지 확인해주는 명령어. 
		System.out.println(st.nextToken()); // nextToken : 데이터를 꺼내오는 명령어. 
		} 
	}
}

결과값 : 
11
22
33
44
55

 

StringTokenizer의 사용방법 3가지

 

1) 구분 단위를 생략

package 콘솔;
import java.util.StringTokenizer; // ctrl + shift + o
public class TokenizerString02 {
	public static void main(String[] args) {
String PhoneNum = "TEL 82-02-1234-5678";

		StringTokenizer st1 = new StringTokenizer(PhoneNum); 
	
		while(st1.hasMoreTokens()) {
			System.out.println(st1.nextToken()); 
		}
        
        결과값 : TEL
                82-02-1234-5678

: 구분 단위를 여백을 구분문자로 인식하여 분리 시킵니다.

 

 

2) 구분단위 두개 이상 사용 가능

package 콘솔;
import java.util.StringTokenizer; // ctrl + shift + o
public class TokenizerString02 {
	public static void main(String[] args) {
String PhoneNum = "TEL 82-02-1234-5678";

StringTokenizer st2 = new StringTokenizer(PhoneNum, "  -"); 
		
		while(st2.hasMoreTokens()) {
			System.out.println(st2.nextToken()); 
		}
       
결과값 : 
TEL
82
02
1234
5678

:  여백과 - 기호를 구분문자로 인식하여 분리합니다.

 

 

3) String str, String delim, boolean returnDelims

package 콘솔;
import java.util.StringTokenizer; // ctrl + shift + o
public class TokenizerString02 {
	public static void main(String[] args) {
String PhoneNum = "TEL 82-02-1234-5678";

StringTokenizer st3 = new StringTokenizer(PhoneNum, "  -", true); 
		while(st3.hasMoreTokens()) {
			System.out.println(st3.nextToken()); 
		}

결과값 : 
TEL
 
82
-
02
-
1234
-
5678
        

: 구분문자 까지 모두 같이 출력해줍니다.

'빅데이터 > JAVA' 카테고리의 다른 글

[JAVA] 메서드 오버라이딩(Method Overriding) , Instanceof연산자  (0) 2020.05.07
[JAVA] 상속(inheritance)  (0) 2020.05.05
[JAVA] 배열 (array)  (0) 2020.05.02
[JAVA] String  (0) 2020.05.02
[JAVA] Scanner  (0) 2020.04.30

● 배열(array)이란?

: 인덱스와 인덱스에 대응하는 데이터들로 이루어진 자료 구조로 배열을 이용하면 한 번에 많은 메모리 공간 할당 가능하도록 하는 것을 의미합니다. 그래서 Data의 효율적인 처리할 수 있도록 해줍니다.

 

 

 

● 배열의 특징

같은 타의 데이터들이 순차적으로 저장

- 인덱스를 이용하여 원소 데이터 접근

- 반복문을 이용하여 처리하기에 적합

- 0부터 카운터 시작

- 하나의 이름으로 많은 양의 data를 관리

 

 

● 배열의 형식

 

1) 기본형

package Array;

public class Array {
	public static void main(String[] args) {
              
       int[] age = new int[3]
    
         age[0] = 20;
		 age[1] = 21;
		 age[2] = 22;
         
         for(int i =0 ; i < 3 ;i++) {
			System.out.println("나이 : " + age[i]);
		}
        
        결과값 : 20 , 21 , 22

	}
}

 

 

2) count 값을 넣지 않은 배열

package Array;

public class Array {
	public static void main(String[] args) {

int[] age = new int[] {20,21,22,23,24,25,26}; 
		
count 값을 넣지 않아야 error 나지 않습니다.  
초기 값을 넣으면 그 값보다 작은 수를 넣으면 
남은 공간에 무엇이 들어와야 하는지 모르기 때문에 java가 오류가 생깁니다. 
		
		
for(int i =0 ; i < age.length ;i++) {
System.out.println("나이 : " + age[i]);
}
       
결과값: 20, 21, 22, 23, 24, 25, 26   

age.length 의 age의 길이를 담기 때문에 code 문제 없이 수행합니다. 
이렇게 처리하게 되면 age의 값이 변동해도 for 반복문은 문제 없이 수행합니다. 
       
    }
}

 

 

3) new 참조형[] 생략 하는 배열 (+ 매서드 활용)

package Array;
public class Array {
	public static void main(String[] args) {
    		int[] arr = {1, 2, 3, 4, 5}; // new int[] 생략하고 초기화가 가능하다.   
        int num = 10;
        
        int [] result ; // 참조 변수 선언으로 stack 영역에 4byte 할당해준다. 
        
		 result = addAllArray(arr , num); // arr = a , num = n
		 
		 for(int i = 0; i < result.length; i++) {
			 System.out.println("result : " + result[i]);  결과값 11, 12, 13, 14, 15
		 }
		 
		 for(int i = 0; i < arr.length; i++) {
			 System.out.println("arr : " + arr[i]);	 결과값 11, 12, 13, 14, 15
		 }
	}
	
	public static int[] addAllArray(int[] a, int n) {  
    // 매개변수 + 지역변수 - int[] arr 과 같은 주소값을 가집니다.
	// 참조변수 일 때, 주소값을 전달 받도록 해서 사용합니다. 
		
	for(int i = 0; i < a.length;i++) {
		a[i] += n;
		System.out.println(a[i]);
            }
		return a; 	// 결과값 11, 12, 13, 14, 15
	} 
}

 

 

4) String 사용 배열(+참조자료형 활용)

package Array;
public class Array {
	public static void main(String[] args) {
    String[] strArr = new String[3]; // 12byte 할당. 
    
    System.out.println(strArr[0]); 
    null 출력 : 선언이 되어서 메모리가 할당 되어 있지만 아무값도 입력되지 않아서 null이 출력합니다.
    
	    strArr[0] = "홍길동";
	    strArr[1] = "이순신";
	    strArr[2] = "세종대왕";
	
     for(int i = 0; i< strArr.length ; i ++){ 
			 System.out.println(strArr[i]); 
			 }
		

 문자열이 저장되어 있는 주소값을 저장하려는 것입니다. 메모리 어딘가에 있는 문자열을 각각의 시장 주소값을 저장하기 위해서 new를 선언하여 strArr으로 주소값을 저장시키는 것입니다.

 

 

 

배열 2가지 관점

 

1. 기본자료형

 

- 반드시 동일한 자료형으로 배열이 가능합니다.

- 하나의 변수안에 같은 자료형으로 순서에 맞게 입력하여 관리합니다.

- 변수의 이름으로 메모리에 접근하고 순서(번호)로 접근합니다.

- 하나의 이름으로 많은 양의 data를 관리합니다.

 

int[] younghee = new int[5];
		
younghee[0] = 90; // 국어
younghee[1] = 95; // 영어
younghee[2] = 85; // 수학
younghee[3] = 95; // 사회
younghee[4] = 90; // 과학
		
데이터 처리에 반복문을 이용
		
for(int i = 0 ; i < 5; i++) {
	ystem.out.println(younghee[i]);
}

 

반복분을 이용해 결과값을 가져오는데 아주 유용합니다.

결과값 = 90, 95, 85, 95, 90

 

 

2. 참조자료형

package 배열.Apple;

public class Applemain {
	public static void main(String[] args) {
		// new Mart[3]; 
		// 만약 : class Mart 총 할당 된 메모리량이 50byte라면 
		// Heap 안에 50byte 씩 3개가 할당 되어지는 것이 아닙니다!!
				
		Mart eMart = new Mart("이마트" ,  100 , 500);
		Mart homeplus = new Mart("홈플러스" , 200 , 1000);
		Mart walmart = new Mart("월마트" , 300, 2000);
				
		Mart[] mart = new Mart[3]; //4byte씩 3개가 할당 된다(주소값만을 넣어주는 것이다)
		mart[0] = new Mart("이마트" ,  100 , 500); // 실질적으로 할당된 주소값을 저장
		mart[1] = new Mart("홈플러스" , 200 , 1000);
		mart[2] = new Mart("월마트" , 300, 2000);
				
		mart[0]. displayMart(); // 이마트
		mart[1]. displayMart(); // 홈플러스
		mart[2]. displayMart(); // 월마트

 

위와 같이 참자료형 자체를 배열로 사용하려고 할 때 우리가 주의해야 할 사항이 있습니다.

그것은!! 선언한 참조자료형 자체 모두가 저장이 되어서 할당 되는 것이 아니라는 사실입니다.

그렇다면 어떻게 배열로 사용할 수 있을까요? 그것은 참조자료형의 주소값을 저장함으로 그 저장되어있는 것을 불러올 수 있게 만드는 것입니다.

 

만약에  mart.매개변수(); 를 불러오면 error 가 나타납니다. 왜냐하면 mart 배열 안에 class Mart 자체를 넣은 것이 아니라 new Mart("이마트" , 100 , 500);의 이름값만 가지고 있는 것이기 때문입니다.

 

= 자료형의 배열 선언은 하나의 이름으로 heap 영역에서 각각의 인스턴스에 접근하도록 하는 것이므로 참조 자료형의 이름(주소값)을 하나로 관리하겠다는 의미로 이해하시면 됩니다.

 

 

● 2차원 배열

package Array;

public class Array {
	public static void main(String[] args) {
		int[][] arr = new int[3][4]; // 대괄호를 2
		4byte 가 12개 할당 받은 것이다 = 48byte , arr 의 이름으로 다 관리한다.
        
        // int [3][4] / 3행 4열
		
		arr[0][0] = 0;
		arr[0][1] = 1;
		arr[0][2] = 2;
		arr[0][3] = 3;
		
		arr[1][0] = 4;
		arr[1][1] = 5;
		arr[1][2] = 6;
		arr[1][3] = 7;
		
		arr[2][0] = 8;
		arr[2][1] = 9;
		arr[2][2] = 10;
		arr[2][3] = 11;

		for(int i = 0; i< 3;i++) {     // 행의 개념
			for(int j=0; j<4; j++) {   // 열의 개념
				System.out.println("[" + i +"]"+"["+j+"]"+ " = "  + arr[i][j]);
			}
		}
         
         
        new int[i][j]; 변경 되어도 error 나지 않도록 하는 방법
		2차원 -> 행 : length / 열 : arr[num].length 
		for(int i = 0; i< arr.length ;i++) {       // 행의 개념
			for(int j=0; j<arr[i].length; j++) {      // 열의 개념
				System.out.println("[" + i +"]"+"["+j+"]"+ " = "  + arr[i][j]);
			}
		}
		
	}
}

 

주의 해야할 점!!

for(int i = 0; i< arr.length ;i++) { // 행의 개념

for(int j=0; j<arr[i].length; j++) { // 열의 개념
for(int j=0; j System.out.println("[" + i +"]"+"["+j+"]"+ " = " + arr[i][j]);

 

위의 코드에서 for(int j=0; j<arr[i].length; j++)  대괄호 안에 i 가 들어가야 하는 이유!?

package exam12;

public class RaggedArray {
	public static void main(String[] args) {
		
		int[][] ar = {
	             {0 ,1},           
	             {4, 5, 6},
	             {8, 9, 10, 11}
		 };
		
		for(int i = 0; i< ar.length ;i++) {       // 행의 개념
			for(int j=0; j<ar[i].length; j++) {   // 열의 개념
				System.out.println("[" + i +"]"+"["+j+"]"+ " = "  + ar[i][j]);
			}
		}
	}
}

arr[i].length 괄호 안에 i 가 들어가야 하는 이유는 열의 개수가 항상 동일한 것이 아니기 때문입니다.

 

 

● 행과 열의 분리선언

: 기능은 지원 되지만 많이 사용하지 않습니다. 가급적이면 처음부터 초기화 시키는 것이 좋습니다.

int[][] a = new int[3][]; // ragged array
		a[0] = new int[2];
		a[1] = new int[3];
		a[2] = new int[4];
		

 

● for - each 문

public static void main(String[] args) {
		int[] arr = {1,2,3,4,5};
		int sum = 0;
	
		for(int e :arr) { 
			 System.out.println("e = " + e);
			 sum += e;
		}

주의!!!

(;) 세미콜론이 아닌 (:) 콜론 하나만 사용해야 합니다. 배열의 전체를 참조할 필요가 있는 경우에 유용되는 반복문입니다.
for (int e :arr){ } arr의 숫자 하나씩 e에 담아주면서 반복합니다.

 

혼돈하지 말아야 할 것!

for(int e :arr) { 
e++; 
System.out.print(e + " " ); // 한줄에 다 출력되게 만들 때 = print 사용.
		}

- e라는 별도의 저장공간을 할당 받아서 수행하는 것이기 때문에 arr 의 값은 변경 없습니다.

 

 

 

 

'빅데이터 > JAVA' 카테고리의 다른 글

[JAVA] 상속(inheritance)  (0) 2020.05.05
[JAVA] 콘솔 출력  (0) 2020.05.04
[JAVA] String  (0) 2020.05.02
[JAVA] Scanner  (0) 2020.04.30
[JAVA] System.out.println() , 자바의 메모리 모델  (0) 2020.04.30

 

String은 우리가 많이 봐왔던 명령어 입니다. 오늘은 String에 대해서 자세히 알아보겠습니다.

 

String클래스는 하나의 문자열 표현하고, java는 큰 따옴표로 묶여서 표현되는 문자열을 모두 인스턴스화 합니다.

String - java.lang.String 에 저장되어 있어서 언제든 필요할 때 사용할 수 있도록 java가 지원합니다.

 

 

● String 사용 (기본적인 형태)

public class StringInstance {
	public static void main(String[] args) {
		String name = "홍길동"; 
		String hello = new String("안녕하세요, 여러분!!!");

String은 Scanner 와 다르게 import 하지 않아도 error 가 나지 않습니다.
그 이유는 String과 같은 아주 많이 사용되는 것들을 java.lang.String;에 넣어놨고, java.lang.은 import를 하지 않아도 되도록 java가 지원하기 때문입니다.  (java스스로 import 합니다. (system포함))

 

 

● String 사용 (new 생략)

package String;

public class StringMethod {
	public static void main(String[] args) {
		String str1 = "Smart"; // = String str1 = new String("Smart");

문자열이 많이 사용되기 때문에 new String를 생략하여도 포함되어지게 동작합니다.

 

단, new 을 넣은 값과 new를 생략한 값이 다른 결과 값이 나올 수 있습니다.

1) new 를 생략하지 않은 코드 

String name1 = new String("세종대왕");
String name2 = new String("세종대왕");
// 각각 메모리가 할당 되어 독립적으로 동작되어진다.

if(name1==name2) {
	    System.out.println("같은 메모리를 가지고 있다. 동일한 인스턴스 참조");
		}else {
		System.out.println("같은 메모리를 가지지 않는다. 다른 인스턴스 참조");	
		}



2) new 를 생략한 코드 

String name3 =  "이순신";
String name4 =  "이순신"; 	
		
		if(name3==name4) {
		System.out.println("같은 메모리를 가지고 있다. 동일한 인스턴스 참조");
		}else {
		System.out.println("같은 메모리를 가지지 않는다. 다른 인스턴스 참조");	
		}
        

1) new 를 생략하지 않은 코드의 결과 값 : 같은 메모리를 가지지 않는다. 다른 인스턴스 참조

2) new 를 생략한 코드의 결과 값 : 같은 메모리를 가지고 있다. 동일한 인스턴스 참조

 

1)과 2)의 결과 값이 다른 이유:

1) 과 같은 경우 name1 과 name2 라는 참조변수로 독립된 메모리를 할당 받지만,

2) 먼저 동일한 heap 영역에 문자열로 이동한 후 그 문자열의 주소값을  stack 영역의 각 이름으로 가지고 와서 주소값이 참조변수 이름에 저장됩니다.

1)의 경우 각각 연결되는 주소값이 다르고, 2)은 연결되는 주소값이 같습니다.

 

● String 의 특징

: 스트링 객체는 수정 불가능 합니다.

String S = new String("Hello") ; 
String T = S.concat("java"); 

System.out.println(S); = Hello
System.out.println(T); = Hellojava

※ concat 은 문자열을 뒤에 붙여주는 역할을 합니다.

 

 

● String 클래스가 제공하는 유용한 메소드

 

1) length 문자열의 길이 반환 public int length() 

public class StringInstance {
	public static void main(String[] args) {
		String name = "홍길동"; 
		String hello = new String("안녕하세요, 여러분!!!");

System.out.println(name.length());   결과값 : 3
System.out.println(hello.length());  결과값 : 13   
System.out.println("홍길동".length()); 결과값 : 3

System.out.println("홍길동".length());

문자열.method = java 문자열을 보면 "홍길동" 의 주소값을 불러오고 .length를 수행하여 해당 메모리로 가게됩니다.
메모리에 담지 않아도 한번만 수행하고 끝이면 문제 없습니다.  

 

 

 

2) 두 문자열의 결합  public String concat(String str) 

 concat(str) 활용이 많습니다. 멀티미디어( 파일의 이름과 확장자 명을 더해줄 때 사용합니다 . ex) drama.mp4)

public class StringMethod {
	public static void main(String[] args) {
		String str1 = "Smart"; // = String str1 = new String("Smart");
		String str2 = " and ";
		String str3 = "Simple";
	
		String result = str1.concat(str2); 
		System.out.println(result); 
		
       str1.concat(str2); =  str1+str2;  같은 결과 값을 가져옵니다. 
       

concat(str) : 내가 가진 문자열에 입력된 문자열을 연결시켜줍니다.

 

 

추가적 설명)

concat이 편하게 문자열을 결합시켜주지만 큰 단점이 존재합니다.

public class StringMethod {
	public static void main(String[] args) {
		String str1 = "Smart"; 
		String str2 = " and ";
		String str3 = "Simple";
       
        result = str1.concat(str2); // 두개의 문자열을 결합
		result = str1.concat(str2).concat(str3);// 3개의 문자열 결합
		System.out.println(result);

str1.concat(str2) -> str1만큼 같은 크기를 별도로 메모리에 할당하고, 입력으로 전달한 str2의 값의 크기만큼도 할당하고 모든 데이터를 복사해주고 concat이 주소값을 줘서 result 에 저장합니다. 
str1.concat(str2).concat(str3) -> str1.concat(str2)가 결합되어 있는 상태를 메모리에 할당하고 concat(str3)의 크기를

할당한다음 str1.concat(str2)과 concat(str3)을 복사해준 다음 주소값을 다시 줘서result에 저장됩니다.  

str1.concat(str2)의 result 값과 str1.concat(str2).concat(str3)의 result의 값은 다 다릅니다.

주소값을 잃어버린 str1.concat(str2)은 쓸데 없이 메모리를 차지하게 됩니다. (concat 많이 사용할수록 낭비되는 메모리가 많아집니다.) 메모리는 한정적이기 때문에 작은 수의 문자열을 결합할 때는 유용하지만 많은 문자열을 결합할 때는 좋지 않다는 큰 단점을 가지고 있습니다.

 

 

해결점 new StringBuilder(); 을 이용하여 해결합니다.

 

 

+ ) new StringBuilder();

 StringBuilder : string 의 기능중 concat의 문제를 해결하기 위해서 사용하는 자료형입니다.

public class BuilderString { 
public static void main(String[] args) {
new StringBuilder(); 
StringBuilder stringBuilder = new StringBuilder("AB"); 
		    
System.out.println(stringBuilder); = 출력값 : AB
 stringBuilder.append(25).append("Y").append(.14).append(true);
System.out.println(stringBuilder);  =  출력값 : AB25Y0.14true
			
stringBuilder.insert(3,false); 
System.out.println(stringBuilder);  = 출력값 : AB2false5Y0.14true
insert : 두번째 자리에 false를 입력하겠다는 것을 이며, 원하는 위치에 삽입합니다.
0부터 카운팅. 
		
	


StringBuilder은 append 명령어를 사용하여 별도의 메모리를 가지고 있어서 추가되는 형태로 저장되며 자신이 할당한 메모리 보다 내용이 많아지면 스스로 메모리를 추가해가는 알고리즘으로 되어 있어서 concat이 가지고 있는 단점으로 극복합니다.

concat 이라는 매서드가 있는 이유는 빠르게 올러올 수 있다라는 장점을 가지고 있기에 사용합니다. 그래서 큰 단점을 극복하기 위해서 java에서 제시해주는 것이 StringBuilder 입니다.


- 문자열의 갯수가 많을 때는 StringBuilder 사용하는 것이 메모리 효율성 해결할 수 있어서 좋습니다.

 

 

 

3) 두 문자열의 비교  public int compareTo(String anotherString) 

compareTo(anotherString) : 파일의 내용이 같은지 다른지를 확인시켜 줍니다.

 

package String;
public class StringMethod {
	public static void main(String[] args) {
		String str1 = "Smart"; // = String str1 = new String("Smart");
		String str2 = " and ";
		String str3 = "Simple";
        
        str1.compareTo(str3); 
		System.out.println(str1.compareTo(str3));  = 결과값 : 4

반환형(int) 이고, 결과의 수가 중요한 것이 아니라, 0인지 양수인지 음수인지 확인하는것이 중요합니다.

- 양수(앞의 문자열이 사전 뒤쪽에 있다), 음수 앞의 문자열이 사전 앞쪽에 있다), 0 (두가지가 같은 내용을 가지고 있다.)

 

 

 

 

 

 

 

 

 

 

'빅데이터 > JAVA' 카테고리의 다른 글

[JAVA] 콘솔 출력  (0) 2020.05.04
[JAVA] 배열 (array)  (0) 2020.05.02
[JAVA] Scanner  (0) 2020.04.30
[JAVA] System.out.println() , 자바의 메모리 모델  (0) 2020.04.30
[JAVA] 객체지향언어(오버로딩, this, 클래스매서드)  (0) 2020.04.29

Scanner 란?

: System.in 에게 키를 읽게 하고, 읽은 바이트를 문자, 정수, 실수, 불린, 문자열 등 다양한 타입으로 변환하여 리턴 하는 명령어를 의미합니다.

- java.util.Scanner 클래스

System.out.println = out : 출력하겠다. println : 모니터 상으로 출력
System.in) = in : 입력하도록 한다. keyboard 가 눌렸을 때 그 정보를 읽어 올 수 있는 연결통로가 되는 동작을 합니다.

 

package String;

import java.util.Scanner;

public class keyboardScanner {
	public static void main(String[] args) {
			Scanner keyboard = new Scanner(System.in);

Scanner가 저장 되어있는 곳을 import 받아야 사용할 수 있습니다.

: import java.util.Scanner; // import 문 필요

 

- Scanner 주요 메소드

 

 

Scanner 사용예시>

package String;

import java.util.Scanner;

public class keyboardScanner {
	public static void main(String[] args) {
			Scanner keyboard = new Scanner(System.in);
			
			System.out.println("덧셈 연산 수행 프로그램."); 
			System.out.print("첫번째 정수값을 입력 : "); 
			int num1 = keyboard.nextInt(); 
				
			System.out.print("두번째 정수값을 입력 : "); 
			int num2 = keyboard.nextInt(); 
			
			int resultint  = num1 + num2 ;
			
			System.out.println(num1 + " + " + num2 + " = " + resultint);
			System.out.println(resultint);

new로 인스턴스화해서 keyboard의 이름으로 값을 입력 할 수 있도록 만듭니다.

 

 

주의 할점!!>

System.out.print("첫번째 실수 값 입력 : ");
    double num3 = keyboard.nextDouble();   // 실수로 강제로 변환 : nextDouble(); 
			
			System.out.print("첫번째 실수 값 입력 : ");
			double num4 = keyboard.nextDouble();
			
			double resultdouble = num3 +num4;
			
			System.out.println(num3 + " + " + num4 + " = " + resultdouble);
			System.out.println(resultdouble);
			
			keyboard.nextLine(); // dummy : 동작상의 원활함을 위해서 넣은 코드. 
			
			// 문자 + 문자열
			System.out.print("당신의 이름은?");
			String name  = keyboard.nextLine();  // 문자열로 출력 : NextLine();
			System.out.println("당신의 이름은" + name + "이군요.");

숫자 코드와 문자열 코드를 함께 사용할 때, nextint와 nextdouble는 enter전 까지의 값을 반환하고 실행하지만
nextLine은 문자열을 처리 하기 때문에 enter나 space가 문자처럼 처리 되기 때문에 위에서 사용된 enter를 문자 취급하여 실행됩니다.
해결점 : keyboard.nextLine();를 숫자 출력 코드와 문자열 출력 코드 사이에 넣어서 enter가 수행되게 하는  

더미 코드를 넣어서 동작상의 원활함을 주도록 합니다. = dummy code 

 

System.out.println(); 일반적으로 무엇인가를 출력하고 싶을 때 사용하는 명령어 입니다.

 

위의 명령을 가능하게 만어주는 것은 system 덕분입니다.

 

System : java.lang 패키지에 묶여있는 클래스의 이름으로 import java.lang 자동 삽입되므로 System이란 이름을 직접 쓸 수 있게해줍니다.

 

out : static 변수이되 인스턴스를 참조하는 참조 변수 입니다. out 은 PrintStram의 인스턴스 입니다.

 

Println 은 PrintStream의 메소드 입니다. Println 넘겨 받은 데이터를 출력합니다.

 

System. Out 을 선언 할 수 있었던 것은 printstrem static 붙어있기 때문입니다. Out. 이라고 입력하여 printstream의 값으로 가도록 만듭니다. 그 안에 들어있는 오버로딩으로 여러 값들이 정의 되어 있는데 그 중에 println 의 값을 호출하도록 만듭니다.

public class System{
    public static final printstream of ;
}

 static final로 선언되었으니, 인스턴스의 생성없이 System.out 이라는 이름으로 접근 가능합니다.

-> System.out.println(); System 클래스의 멤버 out이 참조하는 인 스턴스의 println 메소드를 호출하는 문장이다. 

 

 

 

자바의 메모리 모델 

 

Jvm은 운영체제 위에서 동작합니다.

- 운영체제가 jvm을 포함해서 모든 응용프로그램에게 동일한 크기의 메모리 공간을 할당할 수 있는 이유는 가상메모리

  기술에서 찾을 수 있습니다.

- jvm은 운영체제로 부터 할당 받은 메모리 공간을 기반으로 자바프로그램을 실행해야 합니다.

- jvm은 운영체제로 부터 할당 받은 메모리 공간을 이용해서 자기 자신도 실행하고, 자바 프로그램도 실행합니다.

 

 

메모리

 

  1. Method 영역 (java 자료형의 method와 다름) : 메소드의 바이트코드, static 변수

 

  • data 가 담기면 프로그램 시작~종료까지 지우지 않고 data 보관합니다.
  • 프로그램이 종료되는 시점 data가 사라집니다.
  • .class 파일을 메모리에 올리고 있었는데(실행코드) 이것이 method 영역입니다.

  

  2. Stack 영역 : 지역변수, 매개변수

 

  • 필요한 순간 java가 할당해주고 java의 판단에 의해서 data를 소멸시켜주는 영역입니다.
  • Java의 판단 : 조건문, 반복문, method와 같이 자신의 영역을 가지고 있습니다.
  • 지역변수를 stack 메모리에 저장합니다. (영역 밖으로 나가면 자동소멸)

  

   3. Heap 영역 : 인스턴스

 

  • 인스턴스가 생성되는 메모리 영역입니다.
  • 요청시에 할당되는 메모리 영역입니다.
  • New에 의해서 할당되어지는 메모리 영역입니다.
  • 자바가 알아서 소멸 시키고 우리는 그 시기를 알 수 없습니다.

 

- 인스턴스는 참조가 이뤄지지 않으면 소멸의 대상디 됩니다. jvm 은 인스턴싀 참조관계를 통해서 소멸 대상을 결정합니다.

 

- Stack의 할당되어지는 메모리는 자동 소멸되지만, heap 데이터는 소멸되는 순간이 정해져 있지 않다.

객체지향언어 3탄으로 오버로딩, this, 클래스매서드애 대해서 알아보겠습니다.

 

● 오버로딩이란?

: 동일한 이름의 메소드를 둘 이상 동시에 정의하는 것을 의미합니다.

 

오버로딩을 가능하게 하는 2가지 조건

 

1) 입렵의 매개변수의 자료형이 서로 다르게 정의 되어 있을 때 허용합니다.

2) 자료형이 같아도 개수가 다를때 사용가능합니다.

-  2가지중 어느 한가지라도 충족한다면 오버로딩 할 수 있습니다.

class Adder{
public int add(int n1, int n2){  
return n1+n2;
}
public int add(int n1, int n2, int n3){ -- 자료형은 같지만 개수가 달라서 가능
return n1+n2+n3;
}
public double add(double n1, double n2){ -- 자료형이 달라서 가능                      
}   
public double add(int n1, double n2){ -- 자료형이 달라서 가능       
return n1+n2;                                          
}		                                                            
public double add(double n1, int n2){ -- 자료형이 달라서 가능      
return n1+n2;                                    
}

 

- 메소드  오버로딩 성공과 실패

// 메소드 오버로딩이 성공한 사례

class MethodOverloading {
	public int getSum(int i, int j) {
		return i + j;
	}
	public int getSum(int i, int j, int k) {
		return i + j + k;
	}
}

// 메소드 오버로딩이 실패한 사례

class MethodOverloadingFail { 
	public int getSum(int i, int j) {
		return i + j;
	}
	public double getSum(int i, int j) {
		return (double)(i + j);
	}
}

-두 개의 getSum() 메소드는 매개변수의 개수, 타입이 모두 같기 때문에 메소드 오버로딩 실패

 

 

주의 사항 1>

형변환의 규칙까지 적용해야만 메소드가 구분되는 애매한 상황은 만들지 않아야 합니다.

class MethodOverload {     
void  isYourFunc( int n ) { … }
void  isYourFunc( int  n1, int  n2 ) {…} 
void  isYourFunc( int  n1, double  n2 ) {…}     
} 
MethodOverload inst = new MethodOverload();     
inst.isYourFunc(10,  ‘a’); 
문자 'a'는 int형으로도, double형으로도 변환이 가능합니다.  
 

형변환 규칙을 적용하되 가장 가까운 위치의 자료형으로 변환이 이루어집니다.

따라서 isYourFunc(int n1, int n2)가 호출합니다.

 

주의 사항 2>

반 환형이 다른 것은 메소드 오버로딩이 성립 안됩니다.

반환형이 다르지만 자료형이 같으면 error입니다. 반환형은 결과를 가지고 수행하는 것이지 호출 시에는 정보가 없기 때문에 method overloading 을 하는 것과 관련이 없습니다.

 

※ 생성자 오버로딩

class person {  
	private String name; // 이름
	private int milID; // 군번
	
	person(String name, int mID){
		this.name = name;   
		this.milID =mID;     
	}                      
	
	person(String name){
		this.name = name;  
		this.milID =0; 
	}

생성자 overloading = 1) 매개 변수의 갯수가 다르던지 2)자료형이 달르면 수행 가능 합니다.

- 생성자의 오버로딩은 하나의 클래스를 기반으로 다양한 형태의 인스턴스 생성을 가능하게 합니다.

 

 

 

● This

: this를 이용하면 생성자 내에서 다른 생성자를 호출할 수 있습니다. 또한 생성자의 추가 정의에 대한 편의를 제공하며 생성자마다 중복되는 초기화 과정의 중복을 피할 수 있습니다.
생성자 안에서 field 값으로 접근하고자 할때는 - this.field 이름 = this 정확히 어떤 것인지 지정해주는 명령어입니다.

 

 

* this의 필요성

- 객체의 멤버 변수와 메소드 변수의 이름이 같은 경우

- 다른 메소드 호출 시 객체 자신의 레퍼런스를 전달할

- 메소드가 객체 자신의 레퍼런스를 반환할 때

 

new 와 this

lass person {  
	private String name; // 이름
	private int milID; // 군번
	
	person(String name, int mID){
		this.name = name;  
		this.milID =mID;    
	}                      
	person(String name){
		this.name = name;  
		this.milID =0; 
	}
	public void showInfo() {
		System.out.println("이름 : " + name);
		
		if (milID!=0){
			System.out.println("군번 : " + milID);	
		}
	}
}


new 실행! 

 

1. person 이라는 자료형을 찾고, 메모리 크기만큼을 계산해서 할당합니다.(name, milid, 생성자, showinfo)

 

1-1. this 라는 key word 를 생성하는데  =this 라는 방을 new 하는 순간 할당되게 됩니다.

      this에는 시작 주소값이 저장되어 있다.
2. 생성자 호출하여 구현합니다
3. 시작 값을 반환해줍니다. = this 값을 return 해주고 있는 것입니다. (참소변수) = 시작 주소값으로 갑니다. 
그때마다 할당 되는 메모리의 주소값입니다. new 할 때마다 할당 되는 주소값을 가지게 되므로 항상 다릅니다.

 

- 같아 보여도 this의 값은 다릅니다.(같은 keyword 라고해서 오해하지 말자)
- this 라는 키워드는 정의되고 있는 자료형 안에서만 사용가능하므로 외부에서는 사용이 불가합니다.
- this 를 넣어주므로서 매개변수와 필드의 이름을 동일하게 할 수 있습니다.

 

this 의 실패

public Book() {
	System.out.println("생성자가 호출되었음");
	this(null, null, 0); // 생성자의 첫 번째 문장이 아니기 때문에 컴파일 오류
}

 

 

● 클래스매서드

: static 메소드(클래스 메소드) - 기본적인 특성과 접근 방법은 static 변수와 동일합니다.

class NumberPrinter {  
    public static void showInt(int n) { System.out.println(n); } 
    public static void showDouble(double n) { System.out.println(n); } 
 } 
  
class ClassMethod {
    public static void main(String[] args) {
        NumberPrinter.showInt(20);   // 클래스의 이름을 통한 호출 
  
        NumberPrinter np = new NumberPrinter(); 
        np.showDouble(3.15);         // 인스턴스의 이름을 통한 호출 
    } 
 } 

 class 의 이름으로  static이 선언된 변수에 접근할 수 있도록 합니다.

 class로 가서 static 을 보고 할당 받은 메모리가 있기 때문에 가능합니다.

 

 

 

객체지향언어의 생성자와 정보은닉/ 접근제어 지시자 그리고 Static에 대해서 알아보겠습니다.

 

1) 생성자(Constructo)

: 객체가 생성될 때 초기화를 위해 실행되는 메소드를 의미합니다.

 

  1. 생성자 이름은 클래스 이름과 반드시 동일 해야합니다.
  2. 생성자 여러 개작성 가능 (오버로딩) 합니다.
  3. 생성자는 new를 통해 객체를 생성할 , 객체당 한 번 호출됩니다.
  4. 생성자는 리턴 타입을 지정할 수 없습니다.
  5. 생성자의 목적은 객체 초기화하는 것입니다.
  6. 생성자는 객체가 생성될 때 반드시 호출됩니다. 그러므로 하나 이상 선언 되어야합니다.
  7. 생성자를 작성하지 않았으면 컴파일러가 자동으로 기본 생성자 삽입합니다.
  8. 반환형이 선언하지 않으면서, 반환하지 않는 메소드 입니다.
public class Book {
	String title;
	String author;
	
	public Book(String t) { // 생성자
		title = t; author = "작자미상";
	}
	
	public Book(String t, String a) { // 생성자
		title = t; author = a;
	}
	
	public static void main(String [] args) {
		Book littlePrince = new Book("어린왕자", "생텍쥐페리"); 
		Book loveStory = new Book("춘향전"); 
		System.out.println(littlePrince.title + " " + littlePrince.author);
		System.out.println(loveStory.title + " " + loveStory.author);
	}

제목과 저자를 나타내는 titleauthor 필드를 가진 Book 클래스를 작성하고, 생성자를 작성하여 필드를 초기화 하는 것입니다.

 

기본 생성자(default constructor)

 - 매개 변수 없고 아무 작업 없이 단순 리턴하는 생성자입니다.

 - 디폴트 생성자라고도 부르기도 합니다. 클래스에 생성자가 하나도 선언되지 않은 경우, 컴파일러에 의해 자동으로 삽입 됩니다.

 = class 안에 하나라도 생성자를 작성하면 기본 생성자가 삽입 되지않습니다.

 

 

2) 정보은닉 / 접근제어지시자 

 

● 정보은닉

private 정보 은닉 - 접근의 하지 못하게 하고 private 이 들어간 자료형을 사용하려고 하면 error를 발생시킵니다.

즉, 자신의  영역 안에서는 접근을 가능하게 하지만, 내 영역 이외의 곳에서는 해당 데이터가 담겨있는 것을 가져올 수 없도록 만듭니다.

 인스턴스 변수의 private 
class FruitSeller      
{      
private int numOfApple;      
private int myMoney;      
private final int APPLE_PRICE;         
} 

class FruitBuyer      
{     
private int myMoney;      
private int numOfApple;          
} 

보통 field는 private으로 만들고 , method(기능)에 한에서는 public으로 선언해서 자료형을 사용할 수 있도록 합니다. 그래서 데이터는 함부러 읽어가지 못하게 하고, 기능은 사용할 수 있게 하는 것이 컨셉으로 합니다.

 

 

● 접근제어 지시자

   public > protected > default > private

 

- private : 클래스 내부(메소드)에서만 접근 가능합니다.

- public : 어디서든 접근 가능합니다.(접근을 제한하지 않습니다.)

- default : 접근제어 지시자 선언을 하지 않은 경우 , 동일 패키지 내에서의 접근 허용합니다.

- protected : 상속 관계에 놓여 있어도 접근을 허용, default 선언으로 접근 가능한 영역 접근 가능, 상속 관계에서도 접근 가능합니다. 

 

 

접근 지정자의 목적

- 클래스나 일부 멤버를 공개하여 다른 클래스에서 접근하도록 허용합니다.

- 객체 지향 언어의 캡슐화 정책은 멤버를 보호합니다.

- 접근 지정은 캡슐화에 묶인 보호를 일부 해제할 목적입니다.

 

 

 

 

3) Static

: 객체마다 생기는 것이 아며 클래스당 하나만 생성됩니다. 또한 객체를 생성하지 않고 사용합니다.

- 특성

공간적 특성 - static 클래스 당 하나만 생성합니다.

시간적 특성 - static 클래스가 로딩될 때 공간 할당합니다.

공유의 특성 - static 동일한 클래스의 모든 객체에 의해 공유합니다.

 

non-static

공간적 특성 객체마다 독립적으로 별도 존재합니다.

시간적 특성 필드와 메소드는 객체 생성 후 비로소 사용합니다.

비공유 특성 - 다른 객체에 의해 공유되지 않고 배타적 사용합니다.

 

class StaticSample {
	int n; 						// non-static 필드
	void g() {...} 			// non-static 메소드

	static int m; 			// static 필드
	static void f() {...} // static 메소드

 

● Static 활용

1) 전역 변수와 전역 함수를 만들 때 활용합니다.

public class Math {
   public static int abs(int a);
   public static double cos(double a);
   public static int max(int a, int b);
   public static double random();
   ...
}

잘못된 사용 방법
Math m = new Math();  // Math() 생성자는 private

바른 사용 방법
int n = Math.abs(-5);

2) 공유 멤버를 작성할 때

- static 필드나 메소드는 하나만 생성. 클래스의 객체들 공유

 

 

● static 메소드의 제약 조건

 - static 메소드는 non-static 이 접근할 수 없습니다.

 - 객체가 생성되지 않은 상황에서도 static 메소드는 실행될 수 있기 때문에, non-static 메소드와 필드 사용 불가합니다.

 - 반대로, non-static 메소드는 static 이 사용가능합니다.

 

 

 

- static 메소드는 this 사용불가합니다.

- static 메소드는 객체가 생성되지 않은 상황에서도 호출이 가능하므로, 현재 객체를 가리키는 this 레퍼런스 사용할 수 없습니다.

 

+ Recent posts