[Day06] java-basic : 객체지향과 클래스
객체지향이란?
- 눈에 보이는 사물들을 프로그래밍화 시키고 싶은 것이 객체 지향이다.
-
물론 눈에 보이지 않는 사물들을 객체화 하여 프로그래밍화 하기도 한다.
- 절차지향은 행동에 기반한 프로그래밍법이다.
- 절차지향은 문장단위로 만들어진다.
- 문장 중심의 절자지향 프로그램보다는 주어와 동사 기반의 객체지향 프로그램이 유지보수에 능하다.
- 눈에 보이는 사물 하나를 단위로 만들어주는 것을 객체 지향 프로그램이라고 한다
- 객체지향은 절차지향보다 사물의 주체가 중요해진 것이다.
-
고양이가 운다, 고양이가 먹는다 (X) -> 고양이 (O)
- 객체 지향 프로그램에서는 사물끼리 통신하고 대화하도록 만들어주는 것이 중요하다.
-
nextInt()
라는 메소드의 주체가Scanner
냐Random
이냐에 따라 결과가 달라지는 것이 바로 객체지향이다. -
추상화 : 실제 눈에 보이는 사물들 중에서 내가 필요로 하는 기능만 뽑아서 프로그램에서 똑같은 사물을 구현해내는 것을 추상화시킨다고 한다.
- 객체지향에서 디자인 패턴은 꼭 봐야 하는 책이다.
클래스란?
- 객체지향에서 필요한 사물을 추상화시켜서 만든 단위가 클래스이다.
- 하나의 사물은 명사와 동사로 이루어져 있다.
- 사물의 특징(속성)을 명사형태, 행동(동작)을 동사라고 보통 얘기한다.
- 클래스에서 사물의 추상화된 특징을 변수로 구성하고, 사물의 추상화된 행동들을 메소드로 구성하게 된다.
- 클래스를 객체의 생선처, 객체를 생성하는 틀이라고 하는 이유 : 고양이라는 객체를 바로 만드는게 아니고, 애완동물의 특징을 구현한 클래스를 활용해서 고양이(객체)를 만들어낼 수 있기 때문이다.
- 클래스 자체가 객체가 아니고 클래스는 객체를 만들 수 있는 설계 도면이다.
-
객체를 만들기 위해서는 heap 영역에 메모리를 할당해야 한다.
- JVM이 인식하는 단위가 클래스이다.
- JVM은 java.lang만 JVM에 올린다.
- 혹은 import한 것과 main메소드만 올린다.?
객체의 구성
- 멤버변수 = 속성
- 메소드 = 동작
-
필요한 객체를 프로그램이 인식하게 하기 위해서는 1) 클래스 설계 => 2) 클래스로 객체 생성(new) => 3) 생성된 객체를 클래스에 정의된 속성과 동작을 가지고 동작
- heap 영역에 있는 모든 요소를 객체라고 하지만, new를 통해 heap 영역에 객체를 만들면 이렇게 만들어진 객체를 인스턴스 객체라고 한다.
- 예를 들어
TV tv = new TV()
에서tv
는 참조변수,new TV()
에서TV()
가 인스턴스 객체가 되는 것이다. - 이때 인스턴스 객체를 제어하기 위해서는 참조변수
tv
를 통해 제어한다.
클래스의 선언
[접근제한자][활용제한자(final/abstract)] class 클래스명 {
속성 정의 (멤버변수)
기능 정의 (메소드)
}
- 하나의
클래스명.java
파일에는 하나의 클래스만 존재한다?
code실습
- 때에 따라서는 Car클래스를 CarMain 안에 설계할 때도 있는데 일반적으로는 따로따로 설계하는 것이 좋다.
Car.java
- Car.java는 참조클래스이다.
- 참조 클래스 : main메소드 없이 사물에 대한 추상화만 시킨 클래스이다.
- 메인메소드는 프로그램이 시작되었어~ 끝났어~하고 알려주는 용도이기 때문에 모든 java파일마다 main메소드를 가질 필요는 없다.
// 참조 클래스
public class Car {
String name;
int price;
String company;
}
CarMain.java
- CarMain.java는 실행클래스이다.
- 눈에 보이는 사물을 추상화 시킨 클래스는 아니다.
- 다만 main메소드를 통해 Car를 실행시키기 때문에 실행클래스 또는 동작 클래스라고 한다.
// 실행 클래스
public class CarMain {
public static void main(String[] args) {
Car c = new Car();
// c차의 이름 출력하기
System.out.println(c.name);
// c차의 특성 지정하기
c.name = "소나타";
c.price = 3200;
c.company = "현대";
// c2차의 인스턴스 객체 만들고 특성 지정하기
Car c2 = new Car();
c2.name = "K5";
c2.price = 3000;
c2.company = "기아";
}
}
- Ram이라는 메모리에 자동차를 만들어야 한다.
- 자바에서는 눈에 보이는 사물을 만드는 키워드가 new이다.
-
new Car();
를 하면 heap 영역에 자동차라는 객체를 만들게 된다. -
new키워드로 만들어진 객체는 자동 초기화된다. (int는 0으로, String은 null로 초기화됨)
- c의 객체에 속해있는 name에 접근하기 위해서는
c.name
으로 접근한다. - 단축키 : c.name을
드래그
하고ctrl
+space
하면System.out.println(c.name);
자동완성 가능하다. - name은 데이터형이 String이기 때문에 별도의 “소나타”의 공간이 만들어지고 c.name이 “소나타”의 주소???을 가르킨다.
// 실행 클래스
public class CarMain {
public static void main(String[] args) {
Car c = new Car();
// c차의 이름 출력하기
System.out.println(c.name);
// c차의 특성 지정하기
c.name = "소나타";
c.price = 3200;
c.company = "현대";
// c2차의 인스턴스 객체 만들고 특성 지정하기
Car c2 = new Car();
c2.name = "K5";
c2.price = 3000;
c2.company = "기아";
// shallow copy
c = c2;
// c, c2의 정보 출력하기
System.out.println("모델명 : " + c.name
+ ", 가격 : " + c.price
+ ", 제조사 : " + c.company);
System.out.println("모델명 : " + c2.name
+ ", 가격 : " + c2.price
+ ", 제조사 : " + c2.company);
}
}
c = c2;
라면c라는 참조변수
가 가진 값이 heap 영역에 존재하는c2의 주소
로 바뀌게 된다.- heap 영역에 존재하던 c의 객체는 가리키는 참조변수가 없기 때문에 쓸모가 없는 메모리 손실이 발생한다.
- 이때 이런 쓰레기 값을 자동으로 처리하는 자바만의 특성이
가비지컬렉터
이다.
Handphone.java
- 핸드폰 사물의 특성을 정의한 참조클래스
HandphoneMain.java
- 핸드폰 실행 클래스
- 인스턴스 객체를 만든 뒤, 만들어진 객체를 요소로 하는 배열을 만든다.
public class HandphoneMain {
public static void main(String[] args) {
// "홍길동", "010-2222-2222", "삼성"을 가지는 Handphone 인스턴스 객체 만들기
Handphone hp = new Handphone();
hp.name = "홍길동";
hp.phone = "010-2222-2222";
hp.company = "삼성";
// "윤길동", "010-1111-1111", "애플"을 가지는 객체 hp2 생성
Handphone hp2 = new Handphone();
hp2.name = "윤길동";
hp2.phone = "010-1111-1111";
hp2.company = "애플";
// Handphone 데이터형인 배열을 만들어보기=================================================================================
Handphone[] hpArr = {hp, hp2};
// index를 활용한 방법
for(int i = 0; i < hpArr.length; i++) {
System.out.println("소유주명 : " + hpArr[i].name);
System.out.println("핸드폰번호 : " + hpArr[i].phone);
System.out.println("핸드폰제조사 : " + hpArr[i].company);
}
// 1.5버전 foreach문 활용한 방법
for(Handphone h : hpArr) {
System.out.println("소유주명 : " + h.name);
System.out.println("핸드폰번호 : " + h.phone);
System.out.println("핸드폰제조사 : " + h.company);
}
}
}
HandphoneMain02.java
- 배열을 먼저 생성하는 방법
public class HandphoneMain02 {
public static void main(String[] args) {
Handphone[] hpArr = new Handphone[3];
/* 메모리에 어떻게 그려질까??
Handphone형의 참조변수만 만들 뿐, Handphone형의 인스턴스는 만들어지지 않는다!
*/
for(int i = 0; i < hpArr.length; i++) {
System.out.println(hpArr[i]); // null값이 출력됨
/* hpArr[i] 는 null이므로, hpArr[i].name은 nullPointerException이 발생한다. */
// 핸드폰 인스턴스 객체 만들기
hpArr[i] = new Handphone();
System.out.println(hpArr[i]); // 객체를 생성했기 때문에 주소값이 출력됨
}
}
}
- 배열 선언과 인스턴스화를 동시에 하는 경우
public class HandphoneMain02 {
public static void main(String[] args) {
// 다른 방법
Handphone[] hpArr2 = new Handphone[] {new Handphone(), new Handphone(), new Handphone()};
hpArr2[0].name = "홍길동";
hpArr2[0].phone = "010-1111-1111";
hpArr2[0].company = "삼성";
hpArr2[1].name = "윤길";
hpArr2[1].phone = "010-2222-1111";
hpArr2[1].company = "애플";
hpArr2[2].name = "삼실";
hpArr2[2].phone = "010-2222-1111";
hpArr2[2].company = "화웨이";
for(Handphone hp : hpArr2) {
System.out.println(hp);
System.out.println("소유주명 : " + hp.name);
System.out.println("번호 : " + hp.phone);
System.out.println("회사 : " + hp.company);
}
}
}