Language/JAVA

여섯째날 [클래스(1)]

구일일구 2022. 7. 28. 21:00
반응형

목차

1. 객체 지향 프로그래밍

2. 객체(Object)와 클래스(Class)

3. 클래스 선언

4. 객체 생성과 클래스 변수

5. 클래스의 구성 멤버

6. 필드(Field)

7. 생성자(Constructor)


[1] 객체 지향 프로그래밍

* OOP : Object Oriented Programming

* 부품 객체를 먼저 만들고 (클래스를 만든다) + 그것들을 조립해 완성된 프로그램을 만드는 기법

* 클래스를 만들어서 동작하되, 여러 클래스를 만들어 조립해서 만들어가는 프로그램

 

* 객체(Object)

- 물리적으로 존재하는 것 (자동차, 책, 사람 ...) 

- 추상적인 것 중에서 속성과 동작을 가지는 모든 것

- 객체는 필드(속성, 변수)와 메소드(동작)로 구성된 자바 객체로 모델링 가능

 

* 객체의 상호 작용 : 객체들은 서로 연관성이 있고, 상호작용 할 수 있음

- 사람 ↔️ 계산기 : 서로 간 기능(동작)을 이용하고 데이터를 주고 받는다.

- 대신, 객체를 생성해야 활용 가능

 

* 객체간의 관계

- 사용 관계 : 객체가 다른 객체를 사용하는 관계 (사람이 자동차를 사용)

- 상속 관계 : 종류 객체와 구체적인 사물 객체 관계 (자동차는 기계 안에 있는 내용을 상속 받는다 = 기계 안의 모든 내용이 자동차 안에 있다)

- 집합 관계 : 완성품과 부품의 관계 (일대다의 관계, 자동차 객체는 엔진.타이어.핸들 객체인 부품들과 관계됨)

 

* 객체 지향 프로그램의 특징

- 캡슐화 : 실제 구현 내용을 감춘다

- 상속 : 부모 객체의 필드와 메소드를 자식 객체에게 물려주는 행위. 자식은 기능을 더 추가해서 확장 가능

- 다형성 : 같은 타입이지만 실행 결과가 다양한 객체를 대입할 수 있음 (하나의 자동차에도 여러 종류의 타이어 가능)


[2] 객체와 클래스

* 객체(Object)와 클래스(Class)

- 현실의 설계도 = 자바 클래스

- 클래스에는 객체를 생성하기 위한 필드와 메소드가 정의됨

- 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스 라고 말함

- 객체 = 인스턴스 : 인스턴스는 내가 만든 클래스에 있는 변수가 메소드가 '힙 메모리'에 올라가는 상태를 말함. 즉 조금은 다르지만, 편하게 같다고 말해도 상관X

- 하나의 클래스로부터 여러 개의 인스턴스를 만들 수 있음 : 여러개의 객체가 가능하다는 소리.

- 클래스 : 내가 하고 싶은 것들을 기능상으로 넣어줌. 잘 만든 클래스는 객체를 생성하여 사용하면 됨


[3] 클래스 선언

* 클래스 이름 정하기 

* 클래스 소스 파일 생성 : "클래스이름.java"

* 클래스 선언

public class 클래스이름{

}

일반적으로 소스 파일 당 하나의 클래스를 선언. 하지만 두 개 이상의 클래스 선언도 가능. 대신 파일 이름과 똑같은 클래스에만 public을 붙여줘야 함

소스파일이 Car.java라면

public class Car{

}
class Tire {

}

[4] 객체 생성과 클래스 변수

* 클래스 선언하고 컴파일 했다면, 객체를 생성할 설계도가 만들어진 것

* 클래스로부터 객체를 생성하는 방법

new 클래스();

'new' : 클래스로부터 객체를 생성시키는 연산자.

new + 생성자 = new + 클래스()

생성자 : 클래스() 형태

new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성됨 ➡️ 객체의 주소를 리턴함 ➡️ 참조 타입인 클래스 변수에 저장 : 변수를 통해 객체 사용 가능

* 클래스 타입으로 선언된 변수에 new 연산자가 리턴한 객체의 주소를 저장하는 코드 : 2줄 또는 1줄로 가능

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

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

클래스는 하나여도, new 연산자를 사용한 만큼 객체가 메모리에 생성된다.

이러한 객체가 클래스의 인스턴스들이다.

같은 클래스로부터 생성되더라도, 객체들은 자신만의 고유 데이터를 가지게 된다.

 

* 클래스의 용도

- 라이브러리(API : Application Program Interface)용 : 자체적으로 실행되지 않음, 다른 클래스에서 이용할 목적으로 만든 클래스

- 실행용 : main()메소드를 가지고 있는 클래스. 실행할 목적으로 만든 클래스

- 대부분의 객체 지향 프로그램은 라이브러리와 실행 클래스가 분리되어 있음

더보기

1개의 애플리케이션 = (1개의 실행클래스) + (n개의 라이브러리 클래스)


[5] 클래스의 구성 멤버

필드(Field)

생성자(Constructor)

메소드(Method)

더보기

클래스 구성 멤버 = 멤버 변수 = 필드,생성자,메소드 = 전역변수 = 글로벌변수

: 클래스 블럭에 만드는 것, 객체를 만드는 것에 쓰이는 멤버들, 힙메모리에 올라가는 변수들

로컬 변수 = 지역 변수  : 메소드 블럭에 만드는 변수


[6] 필드(field)

* 필드의 내용 : 저장하는 데이터들

- 객체의 고유 데이터

- 객체가 가져야 할 부품 객체

- 객체의 현재 상태 데이터

타입 필드 = 초기값;

String company = "현대자동차";
String model = "그랜저";
int maxSpeed = 300;
int productionYear;		//초깃값 설정하지 않아도 됨

 

* 필드의 기본 초기값 : 초기값이 지정되지 않은 필드. 객체 생성 시 자동으로 기본값으로 초기화. 

 

 

* 필드 사용 : 필드값을 읽고, 변경하는 작업

* 필드 사용 객체 내부 : "필드이름"으로 접근

- 같은 클래스 내부라는 뜻. 힙 메모리 안(같은 메모리 안)에 필드, 생성자, 메소드가 생성되기 때문에 그냥 필드이름 바로 써서 접근 가능

객체 내부

//필드
int speed;

//생성자
Car(){
	speed = 0;
}

//메소드
void method(...){
	speed = 10;
}

 

* 필드 사용 객체 외부 : "변수.필드이름"으로 접근

- 남의 클래스를 쓸때니까, 객체 생성하고 난 후 "변수.필드이름" 써서 접근해야 함

void method(){
	//Car 객체 생성
    Car myCar = new Car();
    //필드 사용
    myCar.speed = 60;
}

 

* main()은 static이 붙었기 때문에, 메소드 영역에 저장됨 : 바로 필드를 사용할 수 없고 접근 불가. 사용하려면 객체를 생성하는 수 밖에

 


[7] 생성자 (Constructor)

* 생성자 : new 연산자에 의해 호출되어 객체의 초기화 담당

더보기

new 클래스();

- 필드의 값을 설정

- 메소드를 호출해 객체를 사용할 수 있도록 준비하는 역할을 수행함

- 생성자를 실행시키지 않으면 클래스로부터 객체를 만들 수 없다. 

- 생성자 이름 : 언제나 클래스 이름과 똑같음

- 메소드와 비슷하게 생겼지만, 리턴 타입이 없고, 클래스 이름으로 되어 있다.

 

* 기본 생성자 (Default Constructor)

- 모든 클래스는 생성자가 반드시 존재함. 하나 이상 가질 수 있음.

- 생성자 선언을 생략하면 컴파일러는 기본 생성자 추가 : public 클래스 () { }

- 클래스에서 생성자를 선언하지 않아도, new 연산자 뒤에 기본 생성자를 호출해서 객체를 생성시킬 수 있음 : 색칠된게 기본 생성자

더보기

Car myCar = new Car();

- 클래스에 명시적으로 선언한 생성자가 한 개라도 있으면, 컴파일러는 기본 생성자를 추가하지 않음.

 

* 생성자 선언 

- 기본 생성자 대신 개발자가 직접 선언하는 경우

클래스 (매개변수선언, ...){
	//객체의 초기화 코드
}

- 객체의 초기화 코드 : 필드에 초기값 저장, 메소드를 호출해 객체 사용 전에 필요한 준비를 함

- 매개 변수 선언 : 생략 가능, 또는 여러 개 선언 가능

- new 연산자로 객체를 생성할 때, 개발자가 선언한 생성자가 있으면 반드시 사용한다. 

Car 클래스에 생성자 선언이 있기 때문에 기본 생성자(Car())를 호출해서 객체 생성X. Car(String color, int cc)를 호출해서 객체 생성해야 함

 

* 필드 초기화

- 클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정됨

- 다른 값으로 초기화하고 싶을 때 방법 (1) 필드를 선언할 때 초기값을 주는 방법 : 동일한 클래스로부터 생성되는 객체는 모두 같은 데이터 갖게 됨

<Korean 클래스에 nation 필드를 선언하면서 "대한민국"으로 초기값을 준 경우, Korean 클래스로부터 k1과 k2 객체를 생성하면 k1과 k2 객체의 nation 필드에는 모두 "대한민국"이 저장되어 있음>

public class Korean{			
	String nation = "대한민국";		   
    String name;
    String ssn;
}
Korean k1 = new Korean();
Korean k2 = new Korean();

 

- 다른 값으로 초기화하고 싶을 때 방법 (2) 생성자의 매개값으로 초기값 설정 : 외부에서 제공되는 다양한 값으로 초기화 할때. 이름(name)과 주민번호(ssn) 필드값은 클래스를 작성할 때 초기값을 줄 수 없다. 객체 생성 시점에 다양한 값을 가져야 하기 때문.

따라서 생성자의 매개값으로 값들을 받아 초기화 한다.

public class Korean{			
	//필드
    String nation = "대한민국";		   
    String name;
    String ssn;


	//생성자
    public Korean(String n, String s){
    	name = n;
        ssn = s;
    }
}
Korean k1 = new Korean("박자바", "012345-6789012")
Korean k2 = new Korean("김자바", "012345-2948571")

"박자바", "김자바"는 매개 변수 n을 통해 전달되고, 주민번호는 매개 변수 s를 통해 전달됨. 이 값들은 각각 name 필드와 ssn 필드의 초기값으로 사용됨  

 

* 매개 변수와 필드명이 같은 경우 this 사용

- 매개 변수 이름이 너무 짧으면 코드의 가독성이 좋지 않음. 관례적으로 필드와 동일한 이름을 갖는 매개 변수를 사용

따라서 "this.필드"로 사용해야 함. 

- this : 객체가 객체 자신을 this라고 함. this라는 참조 변수로 필드를 사용하는 것과 동일함

 

* 생성자 오버로딩 : 매개변수의 타입, 개수, 순서가 다른 생성자 여러 개 선언 가능

- 이유 : 객체를 생성할 때 외부 값으로 객체를 초기화할 필요가 있음. 외부 값이 어떻게 제공될지 모르니 생성자도 다양화 해야 한다는 것

 

* 다른 생성자 호출 : this()

- 생성자 오버로딩 시, 생성자 간의 중복된 코드가 발생함. 초기화 내용이 비슷한 생성자들에서 이런 현상을 많이 볼 수 있음 

➡️ 초기화 내용을 한 생성자에 몰아서 작성한 후, 다른 생성자는 전부 다 적은 생성자를 this(...)로 호출한다.

- this()는 자신의 다른 생성자를 호출하는 코드

- 반드시 생성자의 첫줄에서만 허용됨

Car(String model, String color, int maxSpeed){
	this.model = model;
    this.color = color;
    this.maxSpeed = maxSpeed;
	}

Car(String model){
	this(model, "은색", 250);
    }
    
Car(string model, String color){
	this(model, color, 250)
    }

 


[8] 메소드

메소드 : 객체의 동작(기능) / 호출해서 실행할 수 있는 중괄호{} 블록 / 메소드 호출하면 중괄호 {} 블록에 있는 모든 코드들이 일괄 실행 / 다른 객체를 생성해서 다양한 기능을 수행하기도 함 / 객체 간의 데이터 전달 수단으로 사용 / 외부로부터 매개값을 받을 수도 있고, 실행 후 어떤 값을 리턴할 수도 있음

[8.1] 메소드 선언

리턴타입  메소드이름  ([매개변수선언, ...]){

//실행할 코드 작성

}

 

* 리턴타입 : 메소드가 실행 후 리턴하는 값의 타입, 있을 수도 있고 없을 수도 있음

- void : 리턴 안함

- 기본 데이터 타입 8개 & 모든 클래스 올 수 있음

 

* 메소드이름 : 내맘대로, 자바 식별자 규칙에만 맞게 쓰면 됨

 

* 매개 변수 선언 : 메소드가 실행할 때 필요한 데이터를 외부에서 받기 위해 사용. 필요 없을 수도 있음

메소드 선언

void powerOn(){...}
double divide(int x, int y){...}
메소드 호출

powerOn();
double result = divide(10, 20);

혹은 이렇게 표현

byte b1 = 10;
byte b2 = 20;
double result = divide(b1,b2)

 

* 매개 변수의 수를 모를 경우

(1) 매개 변수를 배열 타입으로 선언 : 대신 메소드 호출 전 배열 생성해야 함

더보기

int sum1(int[] valeues) { }

(2) 값의 리스트만 넘겨줌 . 매개변수를 "…"를 사용해서 선언 : 메소드 호출 시 넘겨 준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용

 

[8.2] 리턴문

* 메소드 실행을 중지하고 리턴값 지정

* 리턴값이 있는 메소드 : 반드시 리턴문 사용해 리턴값 지정할 것 : return문 뒤에 실행문 올 수 없음

* 리턴값이 없는 메소드 : 메소드 실행을 강제 종료 시키는 역할

 

* 메소드 호출 

- 내부 : 메소드 이름으로 호출

- 외부 : 객체 생성 후, 참조 변수를 이용해 호출

 

* 메소드 오버로딩 : 매개변수의 타입, 개수, 순서가 달라야 함

 

 

반응형