본문 바로가기

JAVA

6장

1. 객체 지향

-코드의 재사용성

-유지보수 용이

-중복된 코드 제거

 

2. 클래스

-설계도와 같다

-객체를 정의해놓은 것

-제품을 만들기 위해서는 설계도 필요 = 객체를 만들기 위해서는 클래스 필요

 

3. 객체와 인스턴스

객체

-속성+기능 → 객체의 멤버라고 함

-속성은 멤버변수로

-기능은 멤버메서드로

-인스턴스변수 여러 개를 묶어놓은 것 → 객체는 iv 묶음

 

인스턴스

-객체와 같은 의미

-어떤 클래스에 의해 만들어진 객체 자체를 인스턴스라고 함

-그래서 이와 같은 과정을 인스턴스화라고 함

*한 파일에 여러 클래스 작성

하나의 .java 파일에 여러 개의 클래스가 들어갈 수 있음. 하지만 클래스 명에 public class Test { }와 같이 public이 붙으면

무조건 public 클래스명으로 파일명을 만들자. 되도록이면 하나의 소스 파일에는 하나의 클래스만 넣자.

 

4. 변수의 종류

인스턴스변수(iv)

-클래스 영역에 선언

-인스턴스 new할 때 생성됨

-인스턴스마다 각각 다른 고유의 상태를 유지해야하는 속성(Card 클래스 생각하기)

-멤버변수

 

클래스변수(cv)

-static 변수

-클래스 영역에 선언

-클래스가 메모리에 올라가자마자 바로 생성(new 안해도 됨)

-모든 인스턴스가 공통된 저장공간을 공유

-new 안해도 되니까 바로 호출 가능 클래스 이름으로, Card.width 이런식으로~

-언제 static 변수 사용할까? 공통된 속성이 있을 경우 - 카드의 크기 같은 것

-멤버변수

-코테할 때 메인 메서드랑 solution 메서드 두개에서 함께 쓰여야하는 변수가 있을 때 클래스 영역 변수에 static을 붙여서 썼었지!

 

지역변수(lv)

-로컬변수 (멤버변수 아님)

-메서드, 생성자, 초기화 블럭 영역에 선언

-메서드 안에서 변수 선언문 수행 시에 생김

-for, while문 안의 변수들도 다 지역변수야!!

-메서드 영역에서만 유효하고 메서드가 끝나면 자동으로 사라지는 생명이 짧은 변수

-블럭 안에 선언된 지역변수는 블럭을 벗어나면 사라짐

-한 메서드 안에서만 유효하기 때문에 다른 메서드랑 변수명이 겹쳐도 상관 없음

 

5. 메서드

-작업을 수행하는 명령문들의 집합, 함수라고 할 수 있음

-클래스 영역에 작성

-반환타입 메서드이름 (매개변수1, 매개변수2, …)

-메서드 이름은 동사로 지정해주자

 

매개변수

-메서드가 작업을 수행하는데 필요한 값들을 입력받기 위한 변수

-매개변수도 어쨌든 메서드 안에 있는 변수이기 때문에 지역변수임

-cf) 인수 : 메서드를 호출할 때 괄호 안에 지정해준 값들 = 매개변수에 들어가는 실제 값

-메서드는 어떠한 동작, 행위를 나타내기 때문에 동사인 경우가 많다

 

return문

-출력은 최대 1개

-현재 실행 중인 메서드를 종료하고 호출한 메서드로 돌아가라

 

기본형 매개변수 (그림)

-값 그 자체가 복사됨
-읽기만 가능하다. 실질적인 메인에 있는 애는 변하게 하지 못한다. 왜? 값은 메서드 안에서만 유지되기 때문.

-매개변수를 넣는 괄호 안에 기본형이 들어가있는 것 (int a, int b) 처럼

 

참조형 매개변수 (그림)

-주소 자체가 복사됨 = 걔도 조정할 수 있게 아예 리모컨을 줘버린 것
-읽기, 쓰기 모두 가능하다. 왜? 값이 아니라 주소를 주고 받는 것이기 때문에 메서드 안에서 바뀐 값이 메인 메서드에서도 유지된다.

-매개변수를 넣는 괄호 안에 참조형이 들어가있는 것 (Data d) 처럼

 

6. 클래스 메서드 = static 메서드

-인스턴스 변수 안쓰는 메서드, 지역변수만 쓰는 메서드

-객체 생성 없이(new없이) 바로 사용 가능

-예를 들어, Math.random() → Math 클래스의 random() 메서드 호출

-클래스이름.메서드이름()으로 호출, 왜냐하면~

 보통 참조변수.메서드이름()과 같이 호출하지만, 객체가 없으니 애초에 절대 그렇게 할 수가 없음

-언제 static 메서드를 사용할까? 메서드 내에서 인스턴스 변수를 사용하지 않을 때 

 (인스턴스 메서드와의 구분은 이 점이 가장 중요!)

-인스턴스 변수, 메서드를 사용할 수 없음, 왜냐하면~

 순서상, static 메서드는 항상 일등으로 만들어져서 그 때 인스턴스 멤버들을 호출했을 때, 

 객체가 만들어졌을지, 안만들어졌을지는 아무도 모름 

 → 그냥 쉽게 static 메서드는 인스턴스 멤버의 그 무엇도 쓸 수 없다

 → 굳이 클래스 메서드에서도 인스턴스 멤버 쓰고 싶으면 클래스 메서드 안에서 객체를 생성해(new해)

 

7. 인스턴스 메서드

-인스턴스 변수를 사용하는 일반적인 메서드

-참조변수.메서드이름()과 같이 호출

-인스턴스 메서드는 그 안에서 static 메서드를 호출할 수 있는데, 왜냐하면~

 static 메서드는 객체가 생성되었다면 아주 당연히 있을 수밖에, 반박할 여지가 없음

-static 변수는 물론, 메서드도 사용 가능 (static은 언제나 그냥 사용 가능)

 

 

8. 메서드 오버로딩

-과적한다-추가한다 = 1:1이어야하는데 1:N으로 여러 개 정의한다고 생각해라~

-한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것 (=같은 일을 하는 메서드를 여러 개 정의하는 것)

-메서드 이름은 동일하지만, 대신 매개변수의 개수 또는 타입이 달라야함

-반환타입은 상관없음

-대표적으로 println()메서드는 이미 10개의 오버로딩된 메서드가 구현되어 있어서 출력해야하는 

 타입에 따라 알아서 호출해줌 (10개가 있다는 것은 오버로딩이 되어있다는 것)

 

-언제쓰느냐? 

 하는 일은 똑같은데~ 입력받아야하는 값들의 수나 타입이 달라야할 경우

 예를 들어, 덧셈을 하고 싶은데 하나는 add(int x, int y) add(3, 3)의 값을 받아서 더해야되고,

 또 다른 하나는 add(double x, double y) add(3.5, 3.5)을 받아서 더해야할 때,

 메소드 명은 동일하게 하고 매개변수를 바꿔 여러 개 정의해서 사용한다

 

cf) 오버라이딩 (다시 쓴다-변경)

조상 클래스로부터 상속받은 메서드의 내용을 변경하는 것 (7장 상속에서 나옴)

오버로딩은 기존에 없는 새로운 메서드를 추가하는 것

오버라이딩은 조상으로부터 상속받은 메서드의 내용을 변경하는 것

 

 

9. 생성자

-인스턴스 변수 초기화를 도와주는 특별한 메.서.드.

-초기화 : 값을 저장하는 것. 값을 셋팅하는 것.

-객체가 많아지거나, 변수가 너무 많아서 반복적으로 써주기 힘들 때, 메서드처럼 클래스 안에 선언해놔서 초기화를 간단하게

 

public class Main {

	public static void main(String[] args) {
		
		Time t1 = new Time();
		t1.hour = 12;
		t1.minute = 34;
		t1.second = 56;

		Time t2 = new Time(12, 34);
		
		Time t3 = new Time(12, 34, 56);
		
		System.out.println(t2.second); // 값이 초기화되지 않았으므로 0이 출력됨
		
	}

}

class Time {

	int hour;
	int minute;
	int second;

	public Time() {
		super();
	}

	public Time(int hour, int minute) {
		super();
		this.hour = hour;
		this.minute = minute;
	}

	public Time(int hour, int minute, int second) {
		super();
		this.hour = hour;
		this.minute = minute;
		this.second = second;
	}

}

 

-리턴값이 없음 : 그냥 값을 대입해주는 역할만 하기 때문에 메서드 작성 시에 void 사용하지 않음

-생성자명은 클래스명과 동일하게

-모든 클래스는 반드시 생성자를 가진다 (내가 만들어주지 않으면 컴파일러가 자동으로 기본 생성자를 만들어주기 때문에)

 

-오버로딩 가능, 언제 쓰냐면~

기본 생성자의 디폴트 상태가 있을 것이다.

예를 들면, dog(int eye, int nose, int leg) = dog(2,1,4)

근데, 눈이랑 코 갯수는 같은데 다리 개수가 다른 강아지도 있는거야. 그러면 dog(eye, nose, int leg)

이렇게 한 쪽만 다를 경우, 혹은 공통된 부분도 있는데, 다른 부분도 있을 경우, 생성자를 사용하면 좋아.

 

-생성자는 new 하는걸 쉽게 도와주는거지, 본인이 생성하는게 아님, 그냥 단순히 조력자일뿐

-생성자는 어디에 만드느냐? → 당연히 클래스 안에 작성 (Person, Time 클래스 안에)

 

 

10. 기본 생성자

-Time(){}

-생성자가 하나도 없을 때만!!! 컴파일러가 자동으로 알아서 넣어줌

-기본 생성자말고 다른 생성자가 하나라도 있다면, 컴파일러가 안넣어줌 → 기본 생성자도 넣어줘야됨 나중에 에러난다.

 

 

11. 생성자 this()

-생성자에서 다른 생성자를 호출할 때 사용

 

class Car {
	String color; // 인스턴스 변수
    String gearType;
    int door; 
    
    Car(){
        this("white", "auto", 4); 
        // Car(String color, string gearType, int door)를 호출
        // 아래 생성자를 this()로 가져와서 원하는 값만 셋팅해줌
    }
    
    Car(String color){
        this(color, "auto", 4);
        // 얘도 마찬가지로 아래 생성자를 this()로 가져온건데,
        // color는 다르게 넣고 싶은거야. 그럴 때 사용
        // 예를 들어, 자동차를 만들건데 기어타입이나 문의 갯수는 동일하게 하고
        // 색깔만 다르게 여러 대를 만들고 싶을 때, 이렇게 만들어두면
        // 메인에서 불러서 사용할 때 편하겠지?
    }
    
    // 위의 두 생성자는 모두 이 생성자를 사용함. this()라는 이름으로 가져가서 사용.
    // 왜? 같은 클래스 안에 있는 나랑 같은 생성자니까.
    Car(String color, String gearType, int door){
        this.color = color; 
        this.gearType = gearType;
        this.door = door;
    }
}

 

12. 참조변수 this

-인스턴스 변수 자신을 가리키는 참조변수

-원래 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재하지만, 편의상 지우고 쓰는거야.

  대신 지역변수랑 겹칠 경우에는 구별을 위해 참조변수에 this를 붙이는 것

-인스턴스 메서드와 생성자에서만 사용 가능

-왜 클래스 메서드에서는 못써요? 클래스 메서드는 new 못하잖아.. 근데 참조변수가 왜있어.. 없지..

 

-언제 쓰느냐? 지역변수와 구별할 때, 변수명이 같으면, 참조변수에다가 this.abc 이런식으로 써준다

 

class ThisTest1 {

	int a; //인스턴스 변수

	ThisTest1 (int a) {
		//a = a; // 이름이 같아서 a가 서로 구분이 안된다.
		this.a = a; // ThisTest1.a = a; 와 같다.
	}
    
}

 

 

13. 변수의 초기화

-멤버변수와 배열은 자동으로 초기화됨

-지역변수는 초기화도 혼자 못해.. 그래서 수동으로 해줘야됨

 

class InitTest {
	int x; // int x = 0 과 같음 - 자동 초기화
	int y = x; // y = 0
    
    void method() {
    	//int i; // 에러
        int i = 0; // 지역변수는 초기화 꼭 필요
        int j = i;
    }
}

 

-초기화 방법

1. 자동초기화 → 내가 아무 값들 대입하지 않아도 지들이 알아서 디폴트 값으로 초기화해줌

2. 간단초기화 → 간단하게 내가 직접 값을 대입하는거 (대입 연산자 사용)

3. 복잡초기화 → 생성자(인스턴스변수) / 초기화블럭 (static변수)

 

-초기화 순서

클래스 변수(메모리 로딩 시 바로) -> 인스턴스 변수(new할 때)

자동초기화 -> 간단초기화 -> 복잡초기화

 

-클래스 변수 초기화는 처음 메모리에 로딩될 때만 실행, 그 뒤로는 불러지지않아 부를 필요가 없어 계속 올라와 있거든

-인스턴스 변수 초기화는 인스턴스가 생성될 때마다 (new할 때마다)

 

// static 초기화 블럭 사용법

class StaticBlockTest {
	
    static int[] arr = new int[10]; // 대입 연산자를 이용한 간단 초기화
    
    static { // 클래스 초기화 블럭을 이용한 복잡 초기화
    	for(int i = 0; i < arr.length; i++ {
        	arr[i] = (int)(Math.random() * 10) + 1;
        }
    }
    
}

'JAVA' 카테고리의 다른 글

switch문의 제약 조건  (0) 2020.09.29
Properties 클래스  (0) 2020.09.26
Scanner 클래스  (0) 2020.09.15
Java 기초  (0) 2020.09.12
equals()와 hashCode()  (0) 2020.09.12