JAVA - 2

Object와 OOP(Object-Oriented Programming)

Fastcampus 강의, programmers 강의와 부족한 부분들을 검색하면서 공부할 예정이다.


Object

사전적 정의 : 실제로 존재하는 것. 의사나 행위가 미치는 대상.

구체적, 추상적 데이터의 단위이다.(학생, 회원, 주문, 책 한권 등등)


OOP vs Procedural Programming

예시 상황 : 아침에 일어나서 학교를 가는 상황

  1. Procedural programming : 시간이나 사건의 흐름에 따른 프로그래밍.

    일어난다 → 씻는다 → 밥을 먹는다 → 버스를 탄다 → 요금을 지불한다 → 학교에 도착

  2. OOP : Object의 관점에서 하는 프로그래밍 하는 것.

    java2_1

     사진 출처 : fastcampus 강의 

    각각의 객체는 메세지를 주고받고, 데이터를 처리할 수 있다.


Class


보통 현실의 무언가와 class, instance를 비교할 때 다음과 같이 표현한다. 예를 들면 자동차를 생각해보자. 자동차란 무엇인가? 자동차를 정의해보면,

자동차 정의 : 번호판 달렸고, 한국은 운전석이 왼쪽이고, 배기량이 있고…

위와 같이 정의할 수 있다. (물론 저게 완벽한 정의라고 할 수는 없다.) 우리가 이렇게 생각하여 정의한 것을 class라고 한다. 그리고 실제로 자동차공장에서 생성된 자동차를 객체(object)라고 한다. 여기서 자동차공장==Class, 생성된 자동차==Object 라고 할 수 있다.


Method


class Test{
  int a; // instance variable
  String b; // instance variable
  
  int addNum(int n1, int n2) { // addNum이라는 method 정의
    int result; // Stack에 result만큼의 메모리 할당.
    result = n1 + n2;
    return result; // 함수가 끝나면서 Stack에 있던 result 메모리 해제.
  }
}


Object and Instance

Class로 부터 객체를 만드는 과정을 class의 인스턴스화 라고 한다. 어떤 class로 부터 만들어진 객체를 그 class의 instance라고 한다.

java2_2

 사진 출처 

객체나 instance나 비슷한 말이다. new 키워드를 사용하여 instance를 생성한다.


Student studentLee = new Student();
// Student : user defined datatype
// studentLee : reference variable
// new : instance 생성
// Student() : Constructor(생성자)

Student라는 class가 있다고 가정했을 때, 위와 같이 instance를 생성할 수 있다.


Heap Memory


Constructor

Java에서는 객체의 생성과 동시에 instance variables를 원하는 값으로 초기화할 수 있는 생성자(constructor)라는 메소드를 제공.


Student studentKim = new Student();

위 코드에서 생성자는 Student()라고 인스턴스 설명하면서 한번 언급했었다. 다음과 같은 과정으로 인스턴스가 생성된다.

  1. new라는 키워드에 의해 class가 Heap에 인스턴스로 생성됨.
  2. 그리고 해당 인스턴스는 Constructor에 의해 초기화 됨. → instance variable 초기화
  3. 초기화된 인스턴스의 주소가 reference variable에 리턴되어 저장됨.


Default Constructor

Class에는 적어도 한개 이상의 생성자가 존재한다. 근데 현재 포스팅에서 정의했던 모든 class 코드들 중에서 나는 한번도 Constructor를 정의한적이 없다. 과연 어떻게 된걸까? 바로 default constructor이다. class에 생성자를 구현하지 않았어도 new 키워드와 함께 생성자를 호출할 수 있다. 컴파일러가 해당 class에 생성자가 하나도 없는 경우 default constructor code를 넣어주기 때문이다.

class Student{
  int studentId;
  String name;
  
  Student() {} // default constructor
}

기본 생성자 코드는 위와 같다.


내가 만드는 Constructor

class Student{
  int studentId;
  String name;
  
  // Constructor
  Student(int studentId, String name) {
    this.studentId = studentId;
    this.name = name;
  }
}

직접 constructor를 정의했다. 아래는 테스트용 코드이다.

class StudentTest{
    public static void main(String[] args) {
        Student studentKim = new Student(11, "Kjj");
        Student studentPark = new Student(12, "Yjp");
        System.out.println(studentKim.name + " " + studentPark.name);
    }
}
Kjj Yjp

보다시피 초기화가 잘 된 모습을 볼 수 있다. 이렇게 우리가 Constructor를 정의했다면, 기본 생성자는 제공되지 않는다.


this

우리가 원하는 것은 instance variable에 우리가 constructor로 받아온 값을 넣는 것이다. 그러나 아래와 같은 상황이 발생한다.

class Student{
  int studentId;
  String name;
  
  // Constructor
  Student(int studentId, String name) {
    studentId = studentId;
    name = name;
  }
}

studentId 라는 매개변수에 우리가 받아온 매개변수 값을 대입하는 것이다. 우리가 원하는 것은 instance variable에 우리가 constructor로 받아온 값을 넣는 것. 따라서 위처럼 코드를 작성하면 안된다. 따라서 this 라는 키워드를 사용한다.

this(reference variable)는 인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수 - 출처

this라는 reference variable은 해당 인스턴스의 주소를 가리키고 있다. 생성자의 매개변수 이름과 인스턴스 변수의 이름이 같을 경우에는 인스턴스 변수 앞에 this 키워드를 붙여 구분해만 한다.

변수 이름을 같게 하는 이유는 나중에 찾아보기가 좋아서라고 강의에서 말했다.


Overloading

같은 함수 이름을 가지고 있으나 매개변수, 리턴타입 등의 특징은 다른 여러개의 서브프로그램 생성을 가능하게 한다. - 출처

class Student{
  int studentId;
  String name;
  
  // Constructor1
  Student() {} // Student stdKim = new Student(); - OK
  
  // Constructor2
  // Student stdKim = new Student(123, "Kjj"); - OK
  Student(int studentId, String name) {
    studentId = studentId;
    name = name;
  }
}

이렇게 constructor overloading으로 인스턴스를 생성(초기화)하는 2개의 방법을 만들었다.