객체 지향 언어의 역사
- 80년 초 소프트웨어의 위기 - 시대의 빠른 변화를 쫒아가기 어려움
- 해결책으로 절차적인 언어 방식에서 객체 지향 언어 방식을 도입하기 시작했다.
- 기존의 많이 사용하던 C에 객체 지향 개념을 얹은 C++이 탄생했다
- 하지만 C++의 학습은 생각보다 굉장히 어려웠고 객체 지향 개념이 퍼지지 못했다
- 그 후 90년대 C++에서 너무 어렵거나 잘 사용하지 않는 개념을 정리한 JAVA의 등장으로 객체 지향 언어를 보편화에 큰 영향을 끼침
- 객체 지향 언어 = 프로그래밍 언어 + 객체 지향 개념(규칙) 이다.
객체 지향 언어
객체 지향 언어는 코드의 재사용성이 높고, 유지보수가 용이하며, 중복 코드를 제거하는 기능이 많다.
특히 유지보수가 용이한것이 얼마나 좋은것이냐 하면 빠른 변화에 쉽게 대채할 수 있기때문이다.
객체 지향 언어는 기존의 프로그래밍 언어에 객체 지향 개념을 더한것이다.
객체 지향 언어의 개념(규칙) - Object-Oriented Programming
- 캡슐화
- 상속
- 추상화
- 다형성
클래스와 객체
- 클래스(설계도, 데이터 + 함수, 사용 정의 타입)
- 정의 = 클래스란 객체를 정의해 놓은것
- 용도 = 클래스는 객체를 생성하는데 사용
- 객체 (제품)
- 정의 = 실제로 존재하는것, 사물 또는 개념
- 용도 = 객체가 가지고 있는 기능과 속성에 따라 다름
◆ 클래스
※ 하나의 소스 파일에 여러가지 클래스를 작성하려면??
옳바르게 작성된 파일
Hello2.java
public class Hello2 {}
class Hello3 {}
만약 public이 붙어있는 class가 있다면 소스파일의 명과 반드시 같아야한다.
Hello2.java
class Hello2 {}
class Hello3 {}
만약 public이 붙어있지 않다면 소스파일 이름은 둘중 무엇이라도 상관없다.
잘못 작성된 파일
Hello2.java
public class Hello2 {}
public class Hello3 {}
public이 붙은 클래스는 파일명과 같은 하나만 있으면 된다
Hello3.java
public class Hello2 {}
class Hello3 {}
public이 붙은 클래스의 명이 파일명과 다르다
hello2.java
public class Hello2 {}
class Hello3 {}
파일명의 이름은 대소문자를 구분한다
1. 설계도
클래스의 생성
객체 = 속성 (변수) + 기능(메소드) 로 이루어져 있다
예로 들면 Tv의 속성은크기, 길이, 높이, 색상, 볼륨 등과 같은 변할 수 있는것이고 기능은 전원,채널변경, 볼륨 등과 같이 모든 Tv에 공통적으로 있어야하는 내용이다
이렇게 설계도를 표현 할 수 있다
class Tv {
String color; // 변수
boolean power; // 변수
int channel // 변수
void power() { power = !power } // 메소드
void channelUp { channel++; } // 메소드
void channelDown { channel--; } // 메소드
2. 클래스 == 데이터 + 함수
1. 변수 : 하나의 데이터를 저장할 수 있는 공간
2. 배열 : 같은 종류의 여러 데이터를 하나로 저장할 수 있는 공간
3. 구조체 : 서로 관련된 여러 데이터(종류 관계X)를 하나로 저장할 수 있는 공간
4. 클래스 : 데이터와 함수의 결합(구조체 + 함수) = 서로 관련된 변수뿐 아니라 메소드또한 같은 곳에 묶자는 취지
3. 사용 정의 타입
사용자 정의 타입 - 원하는 타입을 직접 만들 수 있다.
int hour;
int minute;
int second;
우리가 원하는 시간이 3가지의 종류일때
int hour1, hour2, hour3;
int minute1, minute2, minute3;
int second1, second2, second3;
이것을 배열로 하나하나 묶는것은 좋지 않다.
이때 class를 사용하면 되는것이다.
class Time {
int hour;
int minute;
int second;
}
이렇게 작성 해놓는다면 Time t = new Time();으로 모든 시간을 한번에 다룰수 있는것이다.
사용자 정의 타입으로 가져올 수 있는 가장 큰 장점은 바로 유지보수가 용이해진다 이다.
◆ 객체
객체를 사용하는 큰 흐름은 3단계로 이루어진다.
객체의 구성 요소와 생성, 사용
1. 클래스의 생성
위의 클래스에서 설명 했지만 보기편하게 한번더 작성해보면 이런식으로 생겼다.
class Tv {
String color; // 변수
boolean power; // 변수
int channel // 변수
void power() { power = !power } // 메소드
void channelUp { channel++; } // 메소드
void channelDown { channel--; } // 메소드
2 .객체의 생성
클래스명 변수명;
변수명 = new 클래스명();
Tv t; // Tv클래스 타입의 참조변수 t(객체의 리모콘)를 선언한다
t = new Tv(); // Tv객체(인스턴스)를 생성하고, 생성된 Tv인스턴스의 주소를 t에 저장한다.
Tv t = new Tv();
새롭게 만든 리모콘을 Tv랑 연결시켜 Tv리모콘인것을 만든다
3. 객체의 사용
앞서 만든 객체를 사용해보자
t.channel = 7; // 변수(속성)를 입력한다
t.channelDown(); // 메소드(기능)을 사용한다.
System.out.println("현재 채널은 " + t.channel + " 입니다.");
이렇게 크게 3단계로 나누어 사용한다.
● 객체와 인스턴스
굉장히 많이 헷갈릴수 있는 내용인 객체와 인스턴스의 구분이다.
- 객체 : 모든 인스턴스를 대표하는 포괄적인 용어
- 인스턴스 : 특정 클래스로부터 생성된 객체( 예) Tv인스턴스 )
※ 인스턴스화
앞서 우린 클래스(설계도)를 통해 객체(인스턴스)를 만들게 되는데 이것을 "인스턴화" 라고 한다
그렇다면 아까 위에 설계도를 적어놓은 것을 토대로 제품을 표현해보자면 이런식으로 그려볼수 있다.
리모콘(t) | Tv인스턴스화 | Tv객체 |
0x100 | --------▶ | 0x100 |
color power channel 변수 |
null | |
false | ||
0 | ||
메소드 | power() | |
channelUp() | ||
channelDown() |
우리가 만든 Tv객체는 이런식으로 생겼다
우리는 반드시 Tv객체를 Tv리모콘으로만 다룰것이다.
- 하나의 인스턴스(제품)를 여러 개의 참조변수(리모콘)가 가르키는 것은 가능하다
그렇다면 같은 Tv를 가리키는 2개는 어떨까?
Tv t1 = new Tv();
Tv t2 = new Tv();
t1.channel = 7;
이렇게 된다고 해도 각각의 리모콘은 서로 다른것이다. t1.channel을 하더라도 t2 리모콘엔 간섭하지 못한다.
※ 그렇다면 t2 = t1;이라고 적는다면 어떻게 되는걸까?
t2의 주소값이 바뀐다. t2는 0x200이라는 주소값을 가지고 있는데 0x100인 주소값을 가진 t1을 t2에 대입하면서 t1의 주소값인 0x100을 받은것이다. 이때는 t1.channel에의한 영향은 t1과 t2모두 받는다.
※ 가비지 콜렉터(java)
각각의 변수와 객체는 생성 메모리 위치를 받는데 t2의 변수를 통해 Tv인스턴스화를 진행할때 0x200의 자리에 만들어진 객체가 있다.
이 객체는 t2가 0x100을 바라보게 되면서 사용이 불가능해지는데 남은 이것은 어떻게 되는걸까??
이때 GC (가비지 콜렉터) 일명 청소부가 불필요하게 메모리에 잔재하는 것들을 찾아 제거한다.
이로써 메모리 낭비를 줄일수 있는것이다.
- 여러 인스턴스(제품)이 하나의 참조변수(리모콘)을 가리키는 것은 불가능하다
● 객체 배열
객체 배열 == 참조변수 배열
Tv tv1, tv2, tv3 ------▶ tv[] tvArr = new Tv[3]; 이건 길이가 3인 Tv타입의 참조변수 배열
0x100 | ----------▶ | 0x100 | ||
tvArrr | tvArrr[0] : null | tvArrr[1] : null | tvArrr[2] : null |
tvArr[0] = new Tv(); , tvArr[1] = new Tv(); , tvArr[2] = new Tv(); 로 생성해서 각 배열의 요소에 저장한다.
Tv[] tvArr = { new Tv(), new Tv(), new Tv() }; 로 만드는것도 가능하다
즉 우리는 배열을 만드는것과 참조변수를 만들어주는 행위를 꼭 해줘야한다
Tv[] tvArr = new Tv[3];
tvArr[0] = new Tv();
tvArr[1] = new Tv();
tvArr[2] = new Tv();
이처럼 만들어주지 않고 Tv[] tvArr = new Tv[3]; 이 줄만 만들어놓으면 그냥 리모콘만 만들어 놓은것이다
각각의 리모콘을 어느 TV에 배정할지 꼭 정해주길 바란다.
'Java > 객체 지향' 카테고리의 다른 글
호출 스택(call stack) (0) | 2023.05.08 |
---|---|
메소드(ft . return 문) (0) | 2023.05.08 |
변수의 종류 (0) | 2023.05.08 |
다향성 (참조변수의 형변환, instanceof 연산자) (0) | 2023.03.07 |
클래스들의 관계. 상속과 포함 (0) | 2023.03.07 |