몬그로이

자바의 정석 6. 객체지향 프로그래밍1 본문

Organizing Docs/Java Docs

자바의 정석 6. 객체지향 프로그래밍1

Mon Groy 2024. 6. 19. 22:14
{power = !power}

 

 TV를 사용하려면 TV 리모컨을 사용해야 하고, 에어컨을 사용하려면 에어컨 리모컨을 사용해야 하는 것처럼TV 인스턴스를 사용하려면 TV클래스 타입의 참조변수가 필요한 것이다

 

 

멤버변수 클래스변수 static 공유값 클래스이름.클래스변수
인스턴스변수 x 서로다른값  
지역변수   메서드 내, 생성자,
초기화블럭내부
   
public class Card {

    String kind;
    int number;

    static int width;
    static int height;
}
//
System.out.println("Card.width = " + Card.width);
System.out.println("Card.height = " + Card.height); //static 변수는 변수 선언 없이 사용

Card c1 = new Card();
c1.kind = "Heart";
c1.number = 7;

Card c2 = new Card(); //변수 선언 후 사용
c2.kind = "Spade";
c2.number = 4;

System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.height + ")");

System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");
c1.width = 50; //Card.width = 50; 으로 적기를 더 권장 (어차피 공유값이니까, 그리고 인스턴스로 오해하지 않도록)
c1.height = 80;//c1 만 변경
System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.height + ")"); //c2도 변경됨
메서드를 사용하는 이유
- 높은 재사용성(reusability)
- 중복 코드 제거
- 프로그램의 구조화
메서드의 선언과 구현
- 메서드 선언부(method declaration, method header)
반환타입 + 메서드 이름 + 매개변수 선언(입력)
후에 변경사항이 발생하지 않도록 신중할 것
- 매개변수 선언(parameter declaration)
호출할 때 인자(argument) 또는 인수가 대입됨

 

*메서드가 반환한 결과를 사용하지 않아도 된다

즉, 호출한 메서드의 결과값을 꼭 변수로 받을 필요 없다

** 간단한 메서드의 경우 if문 대신 조건연산자를 활용해 바로 반환해도 된다

int abs(int x) { return x >= 0? x : -x; }

***매개변수의 유효성 검사:

적절하지 않은 값이 매개변수를 통해 넘어온다면

매개변수의 값을 보정하던가, 보정하는 것이 불가능하면

return 문을 사용해서 작업을 중단하고 호출한 메서드로 되돌아가도록 설정해야 한다

예_ 나누기 할 때 분모에 0이 오는 경우

 


JVM의 메모리 구조

1. 메서드 영역(method area) : 클래스 데이터, 클래스 변수

2. 힘(heap) : 인스턴스, 인스턴스 변수

3. 호출 스택(call stack 또는 execution stack)  : 메서드 작업 공간으로 메서드가 호출됐을 때 할당

메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간 결과 등을 저장함

메서드 작업이 끝나면 할당되었던 공간이 비워짐


 

public static void main(String[] args) {
    ReturnTest r = new ReturnTest();
    
    int result = r.add(3, 5);
    System.out.println(result);

    int[] result2 = {0};
    r.add(3, 5, result2);
    System.out.println(result2[0]);
}//result2(배열)의 찹조값을 add 에 넘겼으므로 반환값 받아옴
//add 메서드가 void 이지만 반환값 받음!

 int add(int a, int b) {
    return a + b;
}

void add(int a, int b, int[] result) {
    result[0] = a + b; 
}//매개변수로 넘겨받은 배열에 연산결과를 저장
//이 방식을 이용하면 메서드가 하나만 반환하더라도 여러 값을 받을 수 있음

 

매개변수의 유효성 검사를 설정할 때는 반환타입의 범위도 고려할 것

ex) int 타입의 경우, 약 20억까지 나타낼 수 있으므로 12!을 넘기지 않도록 한다

 

static long factorial(int n) {
    if (n <= 0 || n > 20) return -1;
    if (n <= 1) return 1;
    return n & factorial(n - 1);
}//유효성 검사

public static void main(String[] args) {
    int n = 21;
    long result = 0; //long 타입

    for (int i = 1; i <= n; i++) {
        result = factorial(i);

        if (result == -1) {
            System.out.printf("유효하지 않은 값입니다.(0 <= n <= 20): %d%n", n);
            break;
        }
        System.out.printf("%2d != %20d%n", i, result);
    }//1부터 돌고 결과 출력 -> for 문 다시 돌기
}

 

public static void main(String[] args) {

    String[] strArr = {"100", "200", "300"};

    System.out.println(concatenate("", "100", "200", "300"));
    System.out.println(concatenate("-", strArr)); //("-", new String[] {"100", "200", "300"})
    System.out.println(concatenate(",", new String[]{"1", "2", "3"}));
    System.out.println("[" + concatenate(",", new String[0] + "]"));
    System.out.println("[" + concatenate("," + "]"));
} //주의! ("-", {"100", "200", "300"} ) 는 가변인자로 비허용

static String concatenate(String delim, String... args) {
    String result = "";
    for (String str : args) {
        result += str + delim;
    }
    return result;
} // 오버로딩 주의 (Str...args) 와 구별 못 함

*가능한 가변인자 사용하지 말 것

생성자에서 다른 생성자 호출하기
- 생성자의 이름으로 클래스이름 대신 this 를 사용한다
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 가능하며 이름 대신 this를 사용한다
- 단, static 이 정의된 경우 this 도 사용할 수 없다

*인스턴스를 사용하여 초기화 하는 것 보다 생성자로 초기화 하는 것이 깔끔하다

**this 와 this(): this 는 참조변수, this() 는 생성자 - this(매개변수)도 가능

public class Car {
    String color;
    String gearType;
    int door;

    Car() {
        this("white", "auto", 4);//제일 아래 생성자를 이용함
    }

    Car(String color) {
        this(color, "auto", 4);
    }

    public Car(String color, String gearType, int door) {
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
    
       Car(Car c) { //인스턴스 복사를 위한 생성자
        color = c.color;
        gearType = c.gearType;
        door = c.door;
    }//this 생략 
    //이 방식보다는 위에 이미 생성자를 마련해 뒀으므로 그걸 이용하는 게 바람직함 - 기존코드 활용
    /* Car(Car c) {
        this(c.color, c.gearType, c.door);
        }*/

}
//
public class CarTest2 {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c2 = new Car(c1);//인스턴스 c1 을 c2에 복사
        c1.door = 100;
    }
    //c1 과 c2 는 서로 독립적이다
}

 

 

'Organizing Docs > Java Docs' 카테고리의 다른 글

MyBatis  (0) 2024.06.27
데이터베이스Driver >> JDBCTemplate  (0) 2024.06.26
자바의 정석 5. 배열(Array)  (0) 2024.06.18
쓰기 지연 저장소와 지연 로딩  (0) 2024.06.04
Regrex 정규표현식(Regular Expression)  (0) 2024.05.31