자바의 정석 기초편 - 객체지향개념 공부(2)

인영·2022년 11월 3일
0

자바의 정석

목록 보기
2/6

매개변수

기본형 매개변수 - 변수의 값을 읽기만 할 수 있다. (read only)
참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다. (read & write)

참조형 반환타입 - 객체 주소를 반환, 객체를 반환

static 메서드와 인스턴스 메서드

class Ex {
	long a, b; // 인스턴스 변수 (클래스 전체에서 사용 가능)
    long add() { // 인스턴스 메서드
    	return a + b;
    }
    static long add(long a, long b) { // 클래스 메서드 (static메서드), 지역변수
    	return a + b;
    }
}
class Test {
	public static void main(String args[]) {
    System.out.println(Ex.add(200L, 100L)); // 클래스 메서드 호출 (객체 생성없이 호출)
    Ex ex = new Ex(); // 인스턴스 생성 (객체 생성)
    ex.a = 200L;
    ex.b = 100L;
    System.out.println(ex.add()); // 인스턴스 메서트 호출 (객체 생성 후 호출)
}

인스턴스 메서드

인스턴스 생성 후 참조변수.메서드이름()으로 호출
인스턴스 멤버(iv, im)와 관련된 작업을 하는 메서드
메서드 내에서 인스턴스 변수(iv) 사용가능

static 메서드(클래스 메서드)

객체 생성없이클래스이름.메서드이름()으로 호출
인스턴스 멤버(iv, im)와 관련없는 작업을 하는 메서드
메서드 내에서 인스턴스 변수(iv) 사용불가
ex) Math.random(), Math.round() -> 객체생성 없이 Math 메서드를 사용하는 것

🔅 인스턴스 변수 사용여부로 갈린다... 사용하면 인스턴스 메서드, 사용하지 않으면 static 메서드

static을 언제 붙여야 할까?
속성(멤버 변수) 중에서 공통 속성에 static을 붙인다.
인스턴스 멤버(iv, im)을 사용하지 않는 메서드에 static을 붙인다.

메서드 간의 호출과 참조

❌ static 메서드는 인스턴스 변수(iv)를 사용할 수 없다.

class Ex2 {
	int iv; // 인스턴스 변수
    static int cv; // 클래스 변수
    void instanceMathod() { // 인스턴스 메서드 (객체 생성 후 호출 가능)
    	System.out.println(iv); // 인스턴스 변수 사용 가능
        System.out.println(cv); // 클래스 변수 사용 가능
    }
    static void staticMethod() { // static 메서드 (객체 생성 없이 호출 가능)
    	System.out.println(iv); // 에러! 인스턴스 변수 사용 불가능
        System.out.println(cv); // 클래스 변수 사용 가능
    }
}

❌ static 메서드는 인스턴스 메서드(im)를 호출할 수 없다.

class Ex3 {
	void instanceMathod() {}; // 인스턴스 메서드
    static void staticMethod() {}; // static 메서드
    void instanceMathod2() { // 인스턴스 메서드 (객체 생성 후 호출 가능)
    	instanceMethod(); // 다른 인스턴스 메서드 호출 가능
       staticMethod(); // static 메서드 호출 가능
    }
    static void staticMethod2() { // static 메서드 (항상 호출 가능)
    	instanceMethod(); // 에러! 인스턴스 메서드 호출 불가능
        staticMethod(); // static 메서드 호출 가능
    }
}

오버로딩(overloading)

한 클래스 안에 같은 이름의 메서드 여러 개 정의하는 것

성립하기 위한 조건
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
3. 반환 타입은 영향 없다.

오버로딩의 올바른 예 - 매개변수는 다르지만 같은 의미의 기능 수행

class Ex4 {
	int add(int a, int b){
        return a+b;
    }
    long add(long a, long b){
        return a+b;
    }
    int add(int[] a){
        int result = 0;
        fot(int i=0; i<a.length; i++)
        	result += a[i];
        return result;
    }
}

생성자(constructor)

인스턴스가 생성될 때마다 호출되는 인스턴스 초기화 메서드
인스턴스 생성시 수행할 작업(iv 초기화)에 사용

Time t = new Time();
t.hour = 12;
t.minute = 34;
t.second = 56;
Time t = new Time(12, 34, 56) // 생성자를 추가해야만 가능

생성자를 작성할 때 필요한 조건

이름이 클래스 이름과 같아야 한다.
리턴값이 없다. (void 안 붙임)
모든 클래스는 반드시 생성자를 가져야 한다.

클래스 이름(타입 변수명, 타입 변수명, ...) {
	// 인스턴스 생성 시 수행될 코드,
    // 주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Card {
	Card() { // 매개변수 없는 생성자.
    	// 인스턴스 초기화 작업
    }
    Card(String kind, int number) { // 매개변수 있는 생성자
    	// 인스턴스 초기화 작업
    }
}

기본 생성자(default constructor)

매개변수가 없는 생성자
생성자가 하나도 없을 때만, 컴파일러가 자동 추가
(기본 생성자가 있을 경우, 생성자 꼭 기입해야함)

클래스이름() {} // 기본 생성자
Point() {} // Point클래스의 기본 생성자

매개변수가 있는 생성자

class Car {
	String color;
    String gearType;
    int door;
    
    Car() {} // 기본 생성자
    Car(String c, String g, int d) { // 매개변수가 있는 생성자
    	color = c;
        gearType= g;
        door = d;
    }
}
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;
Car c = new Car("white", "auto", 4);
1. 참조변수 c 생성
2. new 연산자가 객체 생성 (color, gearType, door)
3. 생성자 호출 (객체 초기화)
4. 대입 (연결)

생성자 this()

생성자에서 다른 생성자 호출할 때 사용
다른 생성자 호출시 첫 줄에서만 사용 가능

class Car2 {
	String color;
    String gearType;
    int door;
    
    Car2() { // Car2(String color, String gearType, int door)를 호출
    	this("white", "auto", 4);
    }
    Car2(String color) { // Car2(String color, String gearType, int door)를 호출
    	this(color, "auto", 4);
    }
}

참조변수 this

인스턴스 자신을 가리키는 참조변수
인스턴스 메서드(생성자 포함)에서 사용 가능
지역변수(lv)와 인스턴스 변수(iv)를 구별할 때 사용
선언 안 해도 사용 가능

    Car2(String color, String gearType, int door) {
    	// this.color는 iv, color는 lv
    	this.color = color;
        this.gearType = gearType;
        this.door = door;
    }

참조변수 this와 생성자 this()

this와 this()는 비슷하게 생겼을 뿐 완전히 다른 것이다. this는 '참조변수'이고, this()는 '생성자'이다.

this
- 인스턴스 자신을 가리키는 참조변수, 인스턴스 주소가 저장되어 있다.
- 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
this(), this(매개변수)
- 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다. (클래스 이름 대신 this())
class Ex {
	long a, b; // this.a, this.b => iv의 진짜 이름 (this 생략 가능)
    
    Ex(int a, int b) { // 생성자
    	this.a = a; // this.a => iv , a => lv (iv, lv 같은 이름이기 때문에 this 생략 불가)
        this.b = b; // this.b => iv , b => lv (iv, lv 같은 이름이기 때문에 this 생략 불가)
    }
    long add() { // 인스턴스 메서드
    	return a + b; // return this.a + this.b; (같은 이름이 아니기 때문에 this 생략)
    }
    static long add(long a, long b) { // 클래스 메서드(static 메서드)
    	return a + b; // 클래스 메서드는 iv 사용 불가, this 사용 불가
    }
}

🔅 생성자, 인스턴스 메서드에서만 this 사용 가능 / 클래스 메서드는 this 사용 불가


변수의 초기화

지역변수(lv)는 수동 초기화 해야함(사용전 꼭!!!)
멤버변수(iv, cv)는 자동 초기화된다.

class Test { // 자동
	int x; // 인스턴스 변수
    int y = x; // 인스턴스 변수
    
    void method1() { // 수동
    	int i; // 지역 변수
        int j = i; // 에러! 지역변수를 초기화하지 않고 사용
    }

멤버변수의 초기화

명시적 초기화
선언 시 대입연산자(=) 사용
간단한 초기화

class Car {
	int door = 4; // 기본형(primitive) 변수의 초기화
    Engine e = new Engine(); // 참조형(reference type) 변수의 초기화
}

초기화 블럭
인스턴스 초기화 블럭: {}
클래스 초기화 블럭: static {}
복잡한 초기화, 여러 문장 넣기

생성자
iv 초기화
복잡한 초기화

Car(String color, String gearType, int door) { // 매개변수 있는 생성자
	this.color = color;
	this.gearType = gearType;
	this.door = door;
    }

클래스 변수 초기화 시점: 클래스가 처음 로딩될 때 단 한번 (메모리에 올라갈 때)
인스턴스 변수 초기화 시점: 인스턴스가 생성될 때 마다
초기화 순서: 1. cv -> iv / 2. 자동(0) -> 간단(=) -> 복잡(static{}, 생성자)

class Test{
	static int cv = 1; // 클래스 명시적 초기화(간단)
    int iv = 1; // 인스턴스 명시적 초기화(간단)
    
    static { cv = 2; } // 클래스 초기화 블럭(복잡)
    { iv = 2; } // 인스턴스 초기화 블럭(복잡)
    
    Test() { // 생성자(복잡)
    	iv = 3;
    }

0개의 댓글