본문 바로가기
자바/Java의 정석

[Chapter 06] 객체지향 프로그래밍 I

by 코딩diary 2024. 11. 19.

객체지향이론

실제 세계를 컴퓨터 속에 옮겨놓은 것과 같은 가상 세계를 구현

'실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이다.'

상속, 캡슐화, 추상화 개념을 중심으로 발전하였다.

 

객체지향언어

1. 코드의 재사용성이 높다.

    - 기존 코드를 이용하여 새로운 코드를 쉽게 작성

 

2. 코드의 관리가 용이하다.

    - 코드간의 관계를 이용해서 적은 노력으로 쉽게 코드 변경

 

3. 신뢰성이 높은 프로그래밍을 가능하게 한다.

    - 제어자와 메서드를 이용해서 데이터를 보호, 올바른 값을 유지

    - 코드의 중복을 제거하여 오동작 방지

 

 

클래스

객체를 정의해놓은 것. 객체의 설계도 또는 틀

 

객체

실제로 존재하는 것. 클래스에 정의된 내용대로 메모리에 생성된 것

클래스 객 체
제품 설계도 제품
TV 설계도 TV
붕어빵 기계 붕어빵

 

객체와 인스턴스

인스턴스화 : 클래스로부터 객체를 만드는 과정

인스턴스 : 어떤 클래스로부터 만들어진 객체

 

"책상은 책상 클래스의 인스턴스다"

 

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

Tv = t;
t = new Tv();

 

class Tv {
    String color;
    boolean power;
    int channel;

    void power() {
        power = !power;
    }

    void channelUp() {
        channel++;
    }

    void channelDown() {
        channel--;
    }
}

public class classTv {
    public static void main(String[] args) {
        Tv tv = new Tv();
        tv.channel = 7;
        tv.channelDown();
        System.out.println("현재 채널은 " + tv.channel + " 입니다.");
    }
}

 

 

객체 배열

많은 수의 객체를 다룰 때, 배열을 사용

Tv tv1, tv2, tv3;

// 객체 배열 사용
Tv[] tvArr = new Tv[3];	
/*  
    tvArr[0] = new Tv();
    tvArr[1] = new Tv();
    tvArr[2] = new Tv();
*/

 

 

메서드

"특정 작업을 수행하는 일련의 문장들을 하나로 묶은 것"

 

사용하는 이유

1. 높은 재사용성

2. 중복된 코드의 제거

3. 프로그램의 구조화

반환타입 메서드이름 (타입 변수명, 타입 변수명, ... ) {
	// 메서드 호출 시 수행될 코드
}
--------------------------------------------------------
int add (int a, int b) {
	int result = a + b;
    return result;
}

 

지역변수

메서드 내에 선언된 변수들은 해당 메서드 내에서만 사용 가능한 지역변수

int add (int a, int b) {
    return a + b;
}
    
// 위 아래 코드의 a와 b는 서로 다른 변수 
    
int multiply (int a, int b) {
    return a * b;
}

 

 

인자

메서드를 호출할 때 괄호() 안에 지정해준 값들

 

매개변수

호출된 메서드에 선언

int add(int x, int y) {	// 매개변수
	int result = X + y;
    return result;
}

public static void main(String[] args) {
	int result = add(3, 5);	// 인자
}

"인자의 개수와 순서는 메서드에 선언된 매개변수와 일치해야 함"

 

 

재귀 호출

메서드의 내부에서 메서드 자신을 다시 호출하는 것

void method() {
	method();	// 재귀호출
}

사용 이유 : 논리적 간결함

 

팩토리얼 계산 예제

public class FactorialTest {
    public static void main(String[] args) {
        int result = factorial(5);

        System.out.println(result);
    }

    static int factorial(int n) {
        int result = 0;
        if (n == 1)
            return 1;
        else
            result = n * factorial(n - 1);

        return result;
        
        /* 같은 결과
        if(n==1) return 1;
        return n * factorial(n-1);
        */
    }
}

 

 

클래스 메서드와 인스턴스 메서드 차이

클래스 메서드 = static으로 선언된 메서드. 객체 생성 없이 호출 가능

class MyClass {
    static void classMethod() {
        System.out.println("클래스 메서드 호출");
    }
}

public class Test {
    public static void main(String[] args) {
        MyClass.classMethod();  // 객체 생성 없이 호출 가능
    }
}

 

 

인스턴스 메서드 = static 키워드 없이 선언된 메서드. 객체 생성해야 호출 가능

class MyClass {
    void instanceMethod() {
        System.out.println("인스턴스 메서드 호출");
    }
}

public class Test {
    public static void main(String[] args) {
        MyClass obj = new MyClass(); // 객체 생성
        obj.instanceMethod();       // 인스턴스 메서드 호출
    }
}

 

 

 

오버로딩

한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면 사용 가능.

 

1. 메서드 이름이 같아야 함.

2. 매개변수의 개수 또는 타입이 달라야 함.

 

 

생성자

인스턴스가 생성될 때 호출되는 '인스턴스 초기화 메서드'

1. 생성자의 이름 = 클래스의 이름

2. 리턴 값 X

클래스이름(타입 변수명, 타입 변수명, ... ) {
	// 인스턴스 생성 시 수행될 코드,
    // 주로 인스턴스 변수의 초기화 코드를 적는다.
}

class Card {
    Card() {	// 매개변수가 없는 생성자
    	...
    }
    
    Card(String k, int num) {	// 매개변수가 있는 생성자
    	...
    }
}

 

 

기본 생성자

클래스 내에 생성자가 없다면 기본 생성자를 생성해줌. 하지만 클래스에 이미 생성자가 정의되어 있으면 기본 생성자를 생성해주지 않는다.

class Data1 {
	int value;
}

class Data2 {
	int value;
    
    Data2(int x) {	// 매개변수가 있는 생성자
    	value = x;
    }
}

class ConstructorTest {
	public static void main(String[] args) {
    	Data1 d1 = new Data1();
        Data2 d2 = new Data2();	// 컴파일 에러 발생
    }
}

 

 

생성자 예제

 

class Car {
	String color;
    String gearType;
    int door;
    
    Car() {}
    
    Car(String c, String g, int d) {
    	color = c;
        gearType = g;
        door = d;
    }
}

class CarTest {
	public static void main(String[] args) {
    	Car c1 = new Car();
        c1.color = "white";
        c1.gearType = "auto";
        c1.door = 4;
        
        Car c2 = new Car("white", "auto", 4);
        
        System.out.println("c1의 color = " + c1.color + ", gearType = " + c1.gearType + ", door = " + c1.door);
        System.out.println("c2의 color = " + c2.color + ", gearType = " + c2.gearType + ", door = " + c2.door);
    }
}

 

생성자에서 다른 생성자 호출 - this(), this

- 생성자의 이름으로 클래스 이름 대신 this를 사용한다.

- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫 줄에서만 호출이 가능하다.

Car(String color) {
	door = 5;	        // 첫 번째 줄
    Car(color, "auto", 4);	// 에러1. 생성자의 두 번째 줄에서 다른 생성자 호출
}				// 에러2. this(color, "auto", 4); 로 해야함

 

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

    Car() {
        this("white", "auto", 4);
    }

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

    Car(String color, String gearType, int door) {
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}

public class CarTest2 {
    public static void main(String[] args) {
        Car c1 = new Car();
        Car c2 = new Car("blue");

        System.out.println("c1의 color = " + c1.color + ", gearType = " + c1.gearType + ", door = " + c1.door);
        System.out.println("c2의 color = " + c2.color + ", gearType = " + c2.gearType + ", door = " + c2.door);
    }
}

 

 

 

변수의 초기화

멤버변수(클래스 변수와 인스턴스 변수)와 배열의 초기화는 선택적이지만, 지역변수의 초기화는 필수

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

'자바 > Java의 정석' 카테고리의 다른 글

[Chapter 08] 예외처리  (0) 2024.11.23
[Chapter 07] 객체지향 프로그래밍 II  (2) 2024.11.19
[Chapter 05] 배열 array  (1) 2024.11.17
[Chapter 04] 조건문과 반복문  (1) 2024.11.17
[Chapter 3] 연산자  (1) 2024.11.17