JAVA

Java 객체 지향 프로그래밍 / 변수, 메서드, 생성자의 선언과 사용

서묘_ 2021. 11. 29. 23:41

Java의 장점 중 하나가 객체지향 프로그래밍이라는건데 이 객체 지향이 뭘까

 

Object Oriented Programming(OOP) 객체 지향 프로그래밍

 

값, 기능들을 객체로 만들어 놓고 필요할 때마다 가져다 사용한다.

 

객체란 메모리상에 실제로 존재하며 속성과 기능을 가지고 있는 사물 또는 개념이고

클래스란 객체를 정의해 둔 것으로 객체를 생성하기 위한 코드이다.

Java는 이런 객체들을 사용해 프로그래밍한다 (객체 조립)

 

예를 들어 우리가 학생의 학번과 성적을 저장하고, 총점과 평균을 구하는 프로그램을 만들려면

학번과 성적이라는 값이 필요하고 총점과 평균을 구하는 기능이 필요하다.

이 4가지를 객체로 만들어두고 사용한다.

 

값은 변수로 기능은 메서드로 선언한다.

메서드는 값을 받아서 기능을 수행하는데 이때 값을 받을때 사용하는 변수를 매개변수라고한다.

 

메서드 선언

리턴타입 메서드명(매개변수){

            기능;

            return 결과;

}

 

메서드명도 무슨 기능인지 알 수 있게 정해야한다.

동사형, 소문자로 시작, 두개 이상의 단어가 합쳐지면 두번째 단어의 첫번재는 대문자로

ex) javaTest

 

결과의 타입은 리턴타입과 같아야한다. 

리턴할 값이 없는 기능이라면 리턴타입에 void 를 사용하고 return을 생략한다.

리턴 타입이 명시된 경우 어떠한 경우라도 해당 타입의 값을 리턴해야 한다.

 

ex)

두개의 정수를 입력받아 더하고 결과를 리턴하는 메서드

int add(int a, int b){

               int c;

               return a+b;

}

 

문자열을 출력하는 메서드

void print(){

               System.out.println("Java");

}

 

 

* 메서드가 끝나는 경우

1. 메서드의 마지막 블럭{} 에 도달했을 때

2. return문이 실행된 경우 ( 뒤에 코드가 남아있어도 끝남 주의! )

 

메서드가 끝나면 해당 메서드를 호출한 지점으로 돌아간다.

 

 

 

 

클래스 에서 객체 생성

 

클래스명 참조변수;

: 해당 클래스로 만든 객체의 주소를 저장할 참조변수 선언

 

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

: 객체 생성 후 주소 값을 저장, 클래스가 가지고 있는 변수, 메서드들이 메모리에 올라간다.

 

클래스명 참조변수명 = new 클래스명(); //한줄에 작성 가능

 

클래스도 참조형 데이터 타입으로 사용 할 수 있다.

ex)

Book bo; //Book클래스 타입의 변수 bo 선언가능 단, 해당 클래스로 만든 객체의 주소만 저장 가능

 

 

 

 

만들어둔 변수와 메서드 사용

 

참조변수.변수명

참조변수.메서드명(매개변수)

 

메서드 호출 시 매개변수와 입력할 값이 일치해야한다. 타입, 갯수, 순서 모두

 

 

 

* null 값이나 주소값이 없을 때 null로 표현한다.

String은 값을 저장하는 변수가 아닌 주소값을 저장하는 클래스로 참조형 데이터타입으로 본다.

String s = null; -> 주소값이 없다

int i = null; ->  값이 없다

 

 

 

 

Class A {

       int i;

}

 

int 타입 변수 i라는 객체를 생성하는 코드를 가진 A라는 클레스를 만들고

 

A a1 = new A();

Class A의 정보를 메모리에 가져오며 주소값을 받고 참조변수 a1에 대입한다.

A에는 i라는 객체가 있고 int타입의 기본값은 0이기에 현재 a1의 값은 0이된다.

 

A a2 = new A();

Class A의 정보를 또 한번 메모리에 가져오며 주소값을 받고 참조변수 a2에 대입한다.

값은 동일하게 기본값 0이다.

주소값을 새로 받았으니 a1과 a2의 주소값은 다르다.

 

a1 == a2 연산을 실행하면 값은 false가 나온다.

 

a1.i = 10;

참조변수 a1이 가지고 있는 객체 i에 10을 대입한다.

그럼 a1.i의 값은 10으로 변경되겠지만

주소값이 다른 a2.i의 값은 0 그대로다.

 

* 여러개의 참조변수가 하나의 객체를 다루는것은 상관없지만 (어짜피 주소값이 다르니)

하나의 참조변수가 여러개의 객체를 다룰 수는 없다.

 

* String을 비교하는(일치/불일치) 연산 필요 시 == 로는 불가,

equals()라는 메서드를 사용해야한다.

 

 

 

 

 

변수는 하나의 값을 저장하는 공간이라고 계속 반복해서 말씀해주시는데

 

저장되는 형태에 따라 기본형참조형으로 나뉜다.

또 선언되는 위치에 따라 클래스변수, 인스턴스변수, 지역변수로 나뉜다.

각 변수마다 메모리에 올라가는 시점과 호출방법이 달라진다.

 

Class Variable {

           타입 변수명; //인스턴스변수

           static 타입 변수명; //클래스 변수

 

           void 메서드명(){

                    타입 변수명; //지역변수

            }

}

 

클래스 변수 (static 변수)

프로그램이 처음 시작할때 상수와 함게 데이터영역 맨위에 생성되며 프로그램이 끝나면 소멸한다.

즉 처음부터 끝까지 사용할 수 있으며 단 한번만 메모리에 올라간다.

모든 객체가 하나의 클래스 변수를 공유한다.

호출 방법 : 클래스명.변수명

 

인스턴스 변수 (멤버 변수)

객체 생성 후(new) 사용할 수 있다.

힙(메모리영역 맨 아래)에 생성되며 GC(Garbage Collection)가 메모리를 수거할 때 소멸한다.

객체가 생성될 때마다 메모리에 올라가며 클래스 내부에서 사용한다.

호출 방법 : 클래스명(or참조변수명).변수명 (같은 클래스 내부라면  변수명으로만 호출 가능)

 

지역 변수

메서드(or조건문) 내부에 선언되며 메서드 호출시 메모리에 올라가고 메서드 종료시 소멸한다.

매개변수도 지역변수로 보면된다.

호출 방법 : 지역변수명

 

*메서드 내에 메서드를 또 만들 수 없다.

*for, if등의 제어문은 항상 메서드 안에서만 사용 가능하다.

 

모든 객체가 같은 값을 가져야 하는경우는 클래스 변수를,

객체들이 다른 값을 가져야 하는 경우엔 인스턴스 변수를 사용한다.

 

 

 

 

 

★ Java 프로그램 진행 순서

1. Class 정보 로딩 (클래스 관련 정보 : 이름, 상속관계)

2. static 멤버 로딩 (static 변수, static 메서드 등)

3. main() 메서드 실행

4. main 메서드에서 객체 생성

       -> 해당 클래스의 인스턴스 멤버 로딩

       -> 메서드 호출시 메서드의 지역변수 로딩

       -> 메서드 종료시 지역변수 소멸 (메모리가 반환된다)

5. main 메서드 종료 ( 프로그램 종료 )

 

 

메서드가 실행되는 영역은 call stack으로 FILO구조(First In Last Out)를 가지고 있는 공간이다.

먼저 들어온게 컵안에 담듯이 아래부터 쌓이며 나올때는 마지막에 담긴 윗부분부터 나온다.

 

static메서드에서 인스턴스 변수를 사용하려고하면 메모리에 올라가는 시점이 다르기 때문에

인스턴스 변수가 객체로 생성 되지 않았으면 사용할 수 없다. 객체 생성 시점을 주의하며 코딩하자.

 

* 클래스변수와 인스턴스변수는 값을 지정하지않으면 기본값으로 자동 초기화 되지만

지역변수는 자동 초기화가 되지 않으므로 사용하려면 초기값을 =(대입) 해둬야한다. 

 

 

 

생성자(constructor)

객체를 생성할 때 사용하며 인스턴스 변수 초기화 용도로 사용된다.

 

말 그대로 객체를 생성하는거다. A클래스에서 B클래스를 사용할 때 

B클래스의 객체가 있어야 사용 할 수 있으니 B클래스 생성자를 호출하는것.

 

이때 그냥 B클래스의 기본 생성자로 해당 클래스의 객체만 만드는것도 가능하지만

그 클래스가 가지고 있는 인스턴스 변수에 값을 초기화 하는 용도로도 쓸 수 있다.

 

생성자 작성 방법

*[] 안의 내용은 생략 가능하다.

[접근제어자] 클래스명 ( [매개변수] ){ [초기화식] }

 

ex)

Book(){}; 

기본 생성자다.

Class를 만들고 생성자를 하나도 만들지 않으면 Java가 이 기본생성자를 자동으로 넣어둔다. (Default constructor)

단, 하나라도 생성자를 만든 경우엔 자동으로 만들어주지 않으니 기본생성자도 쓸거라면 작성해둬야한다.

 

Book(String t, int p){

       title = t;

       price = p;

}

인스턴스변수 초기화용도의 생성자다. 

Book클래스가 가지고있는 인스턴스 변수에 매개변수로 받은 값으로 초기화시키면서 객체로 생성한다.

 

생성자 호출 방법

다른 클래스에서 호출시 사용법이다.

클래스명 매개변수 = new 생성자();

 

생성자()의 매개변수의 유무, 개수, 타입에 따라 맞는 생성자를 찾아간다.

ex)

Book bo = new Book();

Book클래스의 기본 생성자를 호출한다.

 

Book bos = new Book("가을", 10000);

(String, int) 매개변수 순서, 갯수, 타입이 같은 생성자를 찾아간다.

 

위에 기본생성자만 호출했다면 title과 price를 각각 값을 대압 했어야겠지만

아래 초기화용 생성자를 호출하면 값을 넣으면서 한번에 호출할 수 있다.

 

인스턴스 변수가 많을수록, 자주 사용할 변수들이 들어간 생성자를 만들어두면 편하겠지.

 

* 클래스 안에는 변수, 메서드, 생성자 3가지만 포함할 수 있다.

생성자와 메서드는 생긴게 비슷하지만 꼭 구분하자

생성자 -> 클래스명(){}

메서드 -> 리턴타입 메서드명(){}

생성자는 리턴타입이 없다!!

 

 

 

this 변수와 this() 생성자

 

this 변수

위의 생성자 예시를 가져와보겠다

Book(String t, int p){

       title = t;

       price = p;

}

매개변수도 어떤 값을 받아 오는지 알 수 있도록 이름을 정하는게 좋다. 

이를 따라서 t를 title로 int를 price로 써보자.

Book(String title , int price){

       title = title ;

       price = price;

}

이렇게 인스턴스변수와 지역변수의 이름이 같아져버린다.

지역변수와 인스턴스변수의 이름이 같다면 지역 안에서는 지역변수가 우선권을 가진다.

 

인스턴스변수를 구분하기 위해 인스턴스 변수에 this. 를 붙여준다.

this.변수명 -> 인스턴스변수

Book(String title , int price){

       this.title = title ;

       this.price = price;

}

 

this() 생성자

같은 클래스에 있는 생성자를 호출한다. 생성자의 첫번째 줄에서만 사용 가능하다.

클래스 안에 인스턴스변수가 많다면 생성자도 여러개 만들면서 내부에 같은 코드가 중복되는 일이 생기고

중복되는 코드는 좋은 코드가 아니다.

 

Book(String title , int price){

       this.title = title ;

       this.price = price;

}

 

Book(String title, int price, String publisher){

     this.title = title;

     this.price = price;

     this.publisher = publisher;

}

 

title과 price를 초기화하는 생성자와 publisher까지 3가지를 초기화하는 생성자가 있다.

중복코드를 없애보자

 

1.

Book(String title , int price){

       this.title = title ;

       this.price = price;

}

Book(String title, int price, String publisher){

     this(title, price);

     this.publisher = publisher;

}

 

2.

Book(String title , int price){

       this(title, price, null);

}

Book(String title, int price, String publisher){

     this.title = title;

     this.price = price;

     this.publisher = publisher;

}

 

두가지 모두 가능하다.

생성자를 호출할 때에는 매개변수의 순서, 갯수, 타입이 같은 생성자를 찾기 때문에

초기화하지 않을 값이라도 null값을 넣어서 원하는 생성자를 호출할 수 있다.

'JAVA' 카테고리의 다른 글

Java 배열, 랜덤  (0) 2021.11.30
Java 오버로딩, 접근제어자, 캡슐화, 싱글턴  (0) 2021.11.30
Java Scanner,출력문,조건문, 반복문  (0) 2021.11.25
Java 연산자  (0) 2021.11.25
Java 용어 정리 - 변수, 자료형,형변환  (0) 2021.11.24