chapter6
클래스(class)
class란 동일한 속성과 행위를 수행하는 객체의 집합이다.
객체 지향 프로그래밍
객체 지향 프로그래밍(OOP:Objcet Oriented Programming): 부품에 해당하는 객체들을 먼저 만들고, 객체들을 하나씩 조립해서 완성된 프로그램을 만드는 기법
객체란?
객체(Object)란 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른 것과 식별 가능한 것을 말한다.
객체는 속성과 동작으로 구성되어 있다. 예를 들어 사람은 이름, 나이 등의 속성과 웃다, 걷다 등의 동작이 있고,
자동차는 색상, 모델명 등의 속성과 달린다, 멈춘다 등의 동작이 있다.
자바는 이 속성과 동작들을 각각 필드(field)와 메소드(method)라고 부른다.
-
현실 세계의 객체를 소프트웨어 객체로 설계하는 것을 객체 모델링(Object Modeling)이라고 한다. 객체 모델링은 현실 세계 객체의 속성과 동작을 추려내어 소프트웨어 객체의 필드(field)와 메소드(method)로 정의하는 과정이라고 볼 수 있다.
-
객체들 사이의 상호작용 수단은 메소드(method)이다. 객체가 다른 객체의 기능을 이용하는 것이 바로 메소드 호출이다.
public class Person{
int math_add_result = Calculator.add(10,20);
// 사람 객체의 필드 math_add_result 는 다른 객체인 Calculator의 add 메소드를 이용해 값을 반환받고 있다.
// 이것이 바로 객체들 사이의 상호작용 수단이다.
}
객체들간의 관계
객체들 사이의 관계에 종류가 있는데, 집합 관계, 사용 관계, 상속 관계가 있다.
-
집합 관계: 하나는 부품이고 하나는 완성품인 관계 예) 완성품: 자동차 객체, 부품: 엔진 객체, 타이어 객체, 핸들 객체 => 집합 관계
-
사용 관계: 한 객체가 다른 객체의 메소드를 사용할 때 예) 사람은 자동차를 사용하므로 사람과 자동차는 사용관계이다. 사람은 자동차를 사용할 때 달린다, 멈춘다 등의 메소드를 호출한다.
-
상속 관계: 상위(부모) 객체를 기반으로 하위(자식)객체를 생성하는 관계를 말한다. 일반적으로 상위 객체는 종류를 의미하고, 하위 객체는 구체적인 사물에 해당한다. 예) 기계는 상위(부모) 객체, 자동차는 하위(자식) 객체. => 상속 관계
객체 지향 프로그래밍의 특징
캡슐화(Encapsulation)
캡슐화란 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것을 말한다.
외부 객체는 객체 내부의 구조를 알지 못하여 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있다.
- 필드와 메소드를 캡슐화하여 보호하는 이유: 외부의 잘못된 사용으로 인해 객체가 손상되지 않도록 하기 위해
=> 함부로 건드리면 그 class가 엉망이 되기 때문에 캡슐화(Encapsulation)을 하는 것이다.
자바언어는 캡슐화된 멤버를 노출시킬 것인지, 숨길 것인지 결정하기 위해 접근 제한자(Access Modifier)를 사용한다.
접근 제한자는 객체의 필드와 메소드의 사용 범위를 제한함으로써 외부로부터 보호한다.(종류: public, protected, default, private)
상속(Inheritance) 상속은 부모가 가지고 있는 재산을 자식에게 물려주는 것을 말하는데, 객체 지향 프로그래밍에서도 부모 역할의 상위 객체와 자식 역할의 하위 객체가 있다.
상위 객체는 자기가 가지고 있는 필드와 메소드를 하위 객체에게 물려주어 하위 객체가 사용할 수 있도록 해준다.
- 상속은 상위 객체를 재사용해서 하위 객체를 쉽고 빨리 설계할 수 있도록 도와주고, 이미 잘 개발된 객체를 재사용해서 새로운 객체를 만들기 때문에 반복된 코드의 중복을 줄여준다.
다형성(Polymorphism)
다형성(Polymorphism)은 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질을 말한다.
코드 측면에서 다형성은 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해준다.
자바는 다형성을 위해 부모 클래스 또는 인터페이스의 타입 변환을 허용한다.(Promotion)
부모 타입에는 모든 자식 객체가 대입될 수 있고, 인터페이스 타입에는 모든 구현(implements)객체가 대입될 수 있다.
다형성의 효과로 객체는 부품화가 가능하다. 예를 들어 타이어라는 부모 객체가 있고, 금호타이어와 넥센타이어가 자식 객체로 있으면,
부모 객체는 자동형 변환을 통해, 또 오버라이딩을 통해 자식 객체로서 다양하게 사용될 수 있다.
객체와 클래스
클래스(class)에는 객체를 생성하기 위한 필드와 메소드가 정의되어 있다. 클래스로부터 만들어진 객체를 해당 클래스의 인스턴스(instance)라고 한다.
그리고 클래스로부터 객체를 만드는 과정을 인스턴스화라고 한다.
예) 개발자 -> 자동차 클래스 -> 자동차1(instance) , 자동차2 …
(설계) (인스턴스화)
- 자동차 객체는 자동차 클래스의 인스턴스(instance)
그리고 객체 생성과정을 위해서는 클래스는 메인 함수가 필요없고, 객체 지향 프로그래밍의 개발에 3가지 단계가 있다.
- 1단계: 클래스 설계.
- 2단계: 설계된 클래스를 가지고 객체를 생성.
- 3단계: 생성된 객체를 이용.
클래스 선언
- 일반적으로 소스파일당 하나의 클래스를 선언한다. 하지만, 두 개 이상의 클래스 선언이 가능하다. ```java public class Car{
}
class Tire{
} // 하나의 소스파일에 두 개이상의 클래스 선언 가능하다. // 단, 파일 이름과 동일한 이름의 클래스 선언에만 public 접근 제한자를 붙일 수 있다.(명심)
=> 이와 같은 파일을 만들고 컴파일하면 클래스 개수당 바이트 코드 파일이 생성된다. 즉 Car.class , Tire.class 이렇게 2개 생성되는데, <br>
결국 소스 파일은 클래스 선언을 담고 있는 저장 단위일 뿐, 클래스 자체는 아님을 알려준다. <br>
#### 객체 생성과 클래스 변수
* 클래스로부터 객체를 생성하는 방법: new 연산자 이용하기
* new 연산자는 클래스로부터 객체를 생성시키는 연산자이다.
```java
//case1
클래스 변수;
변수 = new 클래스();
//case2
클래스 변수 = new 클래스();
new 연산자 뒤에는 생성자(Constructor)가 오는데, 생성자는 클래스() 형태를 가지고 있다. new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성된다. 그리고 new 연산자는 힙 영역에 생성시킨 객체의 주소값을 리턴하도록 되어 있다.
이 주소를 참조 타입인 클래스 변수에게 저장해 두면, 변수를 통해 객체를 사용할 수 있다.
Student s1 = new Student(); // Student 객체1 생성
Student s2 = new Student(); // Student 객체2 생성
// new 생성자는 새로운 객체를 생성하기 때문에 s1과 s2는 다른 주소값을 갖고 있다.(완전히 독립된 객체들)
=> 비록 같은 클래스로부터 생성되었지만 각각의 Student 객체는 자신만의 고유 데이터를 가지면서 메모리에서 활동하게 된다.