Language/Java
자바의 객체지향 정리
hu6r1s
2023. 12. 22. 17:46
클래스와 객체
클래스의 정의 : 클래스란 객체를 정의해 놓은 것이다.
클래스의 용도 : 클래스는 객체를 생성하는데 사용한다.
객체의 정의 : 실제로 존재하는 것, 사물 또는 개념
객체의 용도 : 객체가 가지고 있는 속성과 기능에 따라 다르다.
쉽게 표현하자면 이렇다.
클래스
|
객체 |
제품 설계도 | 제품 |
TV 설계도 | TV |
붕어빵 기계 | 붕어빵 |
객체와 인스턴스 용어 정리
- 객체 : 모든 인스턴스를 대표하는 일반전인 용어
- 인스턴스 : 특정 클래스로부터 생성된 객체
- 인스턴스화 : 클래스 => 인스턴스
더 쉽게 정리되어진 글을 찾아봤다.
객체의 구성요소
객체 = 속성(변수) + 기능(메서드)
객체의 생성
객체의 생성
클래스명 변수명;
- 클래스의 객체를 참조하기 위한 참조변수를 선언
변수명 = new 클래스명;
- 생성된 객체의 주소를 참조변수에 저장
객체 생성 방법
Tv t;
- Tv 클래스 타입의 참조변수 t를 선언
t = new Tv();
- Tv 인스턴스를 생성한 후, 생성된 Tv 인스턴스의 주소를 t에 저장
객체의 사용
TV 클래스
속성
- 색깔
- 전원상태
- 채널
기능
- 파워(전원)
- 채널 증가
- 채널 감소
TV1 인스턴스
속성
- 색깔 : 검정색
- 전원상태 : false
- 채널 : 1
기능
- 파워(전원)
- 채널 증가
- 채널 감소
class Tv1_1 {
// 속성 : 변수 선언
String color; // 색깔
boolean power = false; // 전원상태 : false 로 초기화
int channel = 1; // 채널 : 1 로 초기화
// 기능 : 메서드 선언
void power() { // 전원 기능
power = !power;
if (power) {
System.out.println("전원 ON");
} else {
System.out.println("전원 OFF");
}
}
void channelUp() { // 채널 증가
channel++;
System.out.println("채널 증가");
}
void channelDown() { // 채널 감소
channel--;
System.out.println("채널 감소");
}
}
class Tv1_1Main {
public static void main(String[] args) {
Tv1_1 t1 = new Tv1_1(); // TV1 인스턴스
t1.color = "검정색"; // 색깔 초기화
Tv1_1 t2 = new Tv1_1(); // TV2 인스턴스
t2.color = "흰색"; // 색깔 초기화
System.out.println("TV1 인스턴스 색깔 = " + t1.color);
System.out.println("TV2 인스턴스 색깔 = " + t2.color);
t1.power(); // 메서드 호출
System.out.println("TV1 인스턴스 채널 = " + t1.channel);
t1.channelUp(); // 메서드 호출
System.out.println("TV1 인스턴스 채널 : " + t1.channel);
t1.channelDown(); // 메서드 호출
System.out.println("TV1 인스턴스 채널 : " + t1.channel);
t1.power(); // 메서드 호출
// TV2 인스턴스 참조변수에 TV1 인스턴스의 주소 저장 했을 때
t2 = t1;
System.out.println("TV1 인스턴스 색깔 = " + t1.color); // 검정색
System.out.println("TV2 인스턴스 색깔 = " + t2.color); // 검정색
// 흰색이었던 TV2 인스턴스 의 색깔이 검정색으로 바뀐건가요?
// 아닙니다.
// 참조변수 t2 에 저장되어있던 TV2 인스턴스 의 주소가 없어지고
// TV1 의 주소가 t2 참조변수에 저장이 됩니다
// 따라서 t2 = t1; 이후 부터는
// t2 참조변수로는 더 이상 TV2 인스턴스 에 접근할 수 없습니다.
}
}
변수의 종류
선언 위치에 따른 변수의 종류
클래스 영역 : 클래스 변수
- 클래스가 메모리에 올라갈 때 생성된다.
- 객체 생성을 하지 않아도 생성되고 언제든지 사용 가능하다.
- 접근 방법 : 클래스명.클래스변수명
클래스 영역 : 인스턴스 변수
- 객체가 생성될 대 인스턴스 변수가 생성된다.
- 접근 방법 : 참조변수명.인스턴스변수명
메서드 영역 : 지역변수
- 메서드가 호출되서 실행될 때 생성된다.
메서드가 종료되면 자동으로 제거된다.
클래스 변수와 인스턴스 변수에 대해 잘 이해되지 않으면 영상을 보면 이해가 쉬울 것 같다.
class Obj4_1 {
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static 변수, 공유 변수)
void method() {
int lv;
lv = 30;
// 지역변수는 자동으로 초기화가 되지 않기 때문에 사용하려면 반드시 초기화 필요
System.out.println("lv 지역 변수 = " + lv);
}
}
class Obj4_1Main {
public static void main(String[] args) {
// 클래스 변수 접근 및 사용
// 접근방법 : 클래스명.클래스변수이름
Obj4_1.cv = 10;
System.out.println("ObjVar.cv 클래스 변수 = " + Obj4_1.cv);
// 인스턴스 변수 생성 및 사용
// Obj4_1.iv = 20; // Error, 인스턴스를 통해서만 생성 및 사용 가능
Obj4_1 objVar = new Obj4_1();
objVar.iv = 20;
System.out.println("objVar.iv 인스턴스 변수 = " + objVar.iv);
// 지역 변수 생성 및 사용
// objVar.lv // Error, 인스턴스로 지역 변수 바로 접근 불가능
objVar.method(); // 메서드 호출 시 지역 변수 생성
// 메서드 종료시 지역 변수 삭제
}
}
static 메서드와 인스턴스 메서드
static 메서드(클래스 메서드)
객체 생성 없이 '클래스이름.메서드이름()'으로 호출 : ex) Math.random()
인스턴스 멤버 (인스턴스 변수, 인스턴스 메서드)와 관련없는 작업을 하는 메서드
메서드 내에서 인스턴스 변수 사용 불가
class StaticMethod7_1 {
int num1, num2; // 인스턴스 변수 선언
// 클래스 변수 선언
// static int num1 = 10, num2 = 20;
static int add(int num1, int num2) { // 메서드 반환타입 앞에 static 이 붙었기 때문에 static 메서드가 됩니다.
System.out.println();
System.out.println("매개변수로 입력 받은 num1, num2 확인");
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
// 여기서 매개 변수에 있는 num1, num2 와 위에 인스턴스 변수로 선언한 num1, num2 는 같은 걸까요?
// 기본형 매개변수에서 배웠듯이 같지 않습니다. 서로 영향을 받지 않습니다.
// 여기서의 num1 과 num2 는 단지 인스턴스 변수와 이름만 같은 지역변수일 뿐 메서드가 종료되면 사라집니다.
// 인스턴스 변수는 클래스 메서드에서 사용하지 못합니다.
// 그렇다면 추가로 StaticMethod7_1 에 선언한 변수를 사용하고 싶다면?
// 인스턴스 변수가 아닌 클래스 변수를 선언해야합니다. static 타입 변수이름;
// 위에 클래스 변수의 주석을 풀고 인스턴스 변수는 주석을 해주세요!
// 자 그럼 이제 클래스 변수로 선언을 했으니까
// 매개 변수에 있는 num1, num2 와 위에 클래스 변수로 선언한 num1, num2 는 같은 걸까요?
// 그렇지 않습니다. 위에서 말씀드렸듯이 num1, num2는 매개변수이자 클래스 변수와 이름만 같습니다.
// 또한 클래스 변수 를 사용하려면 클래스명.클래스변수 로 만 접근 가능합니다.
// 이렇게 클래스 메서드에서 클래스 변수를 사용할 수 있습니다. 아래 주석 풀어주세요!
// System.out.println("클래스변수 확인");
// System.out.println("StaticMethod7_1.num1 = " + StaticMethod7_1.num1);
// System.out.println("StaticMethod7_1.num2 = " + StaticMethod7_1.num2);
System.out.println("num1 + num2 = " + (num1 + num2));
return num1 + num2;
}
}
class StaticMethod7_1Main {
public static void main(String[] args) {
StaticMethod7_1 methodTest = new StaticMethod7_1(); // 객체 생성
methodTest.num1 = 10;
methodTest.num2 = 20;
// methodTest.add(methodTest.num1, methodTest.num2); // add 는 static 메서드 이기 때문에 객체로 생성된 참조변수로는 접근할 수 없습니다.
// 클래스이름.메서드이름() 방식으로 static 메서드를 호출
StaticMethod7_1.add(methodTest.num1, methodTest.num2);
}
}
인스턴스 메서드
인스턴스를 생성한 후, '참조변수.메서드이름()'으로 호출
인스턴스 멤버(인스턴스 변수, 인스턴스 메서드)와 관련된 작업을 하는 메서드
메서드 내에서 인스턴스 변수 사용가능
class InstMethod7_1 {
int num1, num2; // 인스턴스 변수 선언
static int num3 = 100;
int add(int num1, int num2) { // 메서드 반환타입 앞에 static 이 없기 때문에 인스턴스 메서드 입니다.
System.out.println();
System.out.println("매개변수로 입력 받은 num1, num2 확인");
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
// 계속된 실습으로 우리는 위에 매개변수 num1, num2 와 InstMethod7_1 의 인스턴스 변수는 다르다는 것을 알았습니다.
// 그럼 이런 의문이 듭니다. InstMethod7_1 클래스로 methodTest 객체를 생성했고
// 참조변수를 통해 methodTest.num1 = 10;와 같이 인스턴스 변수에 값도 넣었는데
// 저 값을 매개변수로 받는 의미가 있는 건가? 확인해 보겠습니다.
// 인스턴스 변수 값 확인 : this 는 뒤에서 배우기 때문에 간단히 설명드리자면 인스턴스 변수와 매개변수를 구분하기 위한 것입니다.
System.out.println("this.num1 = " + this.num1);
// 10 이렇게 10이 출력될겁니다. 그럼 비교를 위해 아래 methodTest.add(methodTest.num1, methodTest.num2);
// 주석 하고 methodTest.add(80,90); 주석을 푸세요!
System.out.println("매개변수 이자 지역변수 num1 = " + num1);
// 값이 달라졌을 겁니다. 이제 인스턴스 num1 과 매개변수 num1 은 이름만 같을 뿐이라는 것을 아셨을 겁니다.
// 그래서 구분을 위해 변수의 이름을 다르게 하거나 this 를 사용해서 구분해야 합니다.
// 그럼 지금 상황에서는 매개 변수를 받지 않고
// return this.num1 + this.num2; // 이렇게 해도 됩니다.
// 이번에는 그럼 일반 메서드니까 클래스 변수는 사용하지 못 할까? 아래 주석 제거하세요!
// System.out.println("InstMethod7_1.num3 = " + InstMethod7_1.num3); // 당연하게도 사용 가능합니다!
return num1 + num2;
}
}
class InstMethod7_1Main {
public static void main(String[] args) {
InstMethod7_1 methodTest = new InstMethod7_1(); // 객체 생성
methodTest.num1 = 10;
methodTest.num2 = 20;
// 참조변수를 사용하여 인스턴스 메서드 호출
System.out.println("result : " + methodTest.add(methodTest.num1, methodTest.num2));
// System.out.println("result : " + methodTest.add(80,90));
}
}
오버로딩
한 클래스 안에 같은 이름의 메서드를 여러 개 정의하는 것
오버로딩의 성립 조건
1. 메서드 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입, 위치가 달라야 한다.
3. 반환타입에는 영향을 받지 않는다.
사용하는 목적
- 매개변수 즉, 입력하는 값이 다르지만 같은 기능을 수행하는 경우가 많을 때 사용성 및 효율을 높이기 위해 오버로딩을 사용한다.
생성자
인스턴스가 생성될 때마다 호출되는 '인스턴스 초기화 메서드'이다.
- 인스턴스 생성 시 수행할 작업에 사용된다.
- 초기값이 필요한 인스턴스 변수의 값을 초기화 해준다.
생성 조건
- 이름이 클래스 이름과 같아야 한다.
- return 값이 없다.
- void는 붙이지 않는다.
오버로딩 가능하다.
기본 생성자
- 매개변수가 없는 생성자를 의미한다.
- 생성자를 하나도 선언되어 있지 않았을 때는 컴파일러가 자동으로 추가해 준다.
class Tv9_1 {
// 속성 : 변수 선언
boolean power; // 전원상태
int channel; // 채널
String color; // 색깔
long price; // 가격
// 위 속성에서 필수로 초기값이 필요한 값들을 초기화 해주는 기본 생성자
public Tv9_1() {
power = false;
channel = 1;
}
// 오버로딩 한 생성자 - 매장 진열 용 일 경우에는 가격과 색깔의 초기화가 필요합니다. this 는 이전 챕터에서 잠깐 봤었죠! 매개변수와 인스턴스변수를 구분하기 위해 사용하겠습니다.
public Tv9_1(String color, long price) {
power = false; // this.power, power 둘다 지금 상황에서는 인스턴스 변수를 명확하게 판단 할 수 있기 때문에 어떤걸 사용해도 상관 없습니다.
channel = 1;
this.color = color;
this.price = price;
}
// 기능 : 메서드 선언
void power() { // 전원 기능
power = !power;
if (power) {
System.out.println("전원 ON");
} else {
System.out.println("전원 OFF");
}
}
void channelUp() { // 채널 증가
channel++;
System.out.println("채널 증가");
}
void channelDown() { // 채널 감소
channel--;
System.out.println("채널 감소");
}
}
class Tv9_1Main {
public static void main(String[] args) {
// 기본 초기화된 Tv9_1 생성
Tv9_1 tv = new Tv9_1();
System.out.print("기본 생성자 TV: ");
tv.power();
// 진열 용 Tv9_1 생성
Tv9_1 exTv = new Tv9_1("보라색", 3456789);
System.out.print("오버로딩 생성자 TV: ");
exTv.power();
System.out.println("exTv.color = " + exTv.color);
System.out.println("exTv.price = " + exTv.price);
// 근데 이때 주의할 점!
// 기본 생성자는 없고 오버로딩한 생성자만 있을 경우!
// 컴파일러는 기본 생성자를 만들어주지 않기 때문에 기본 생성자를 사용하려고 하면 Error 발생!
// 위 기본 생성자를 주석 하세요!!!!
Tv9_1 tv2 = new Tv9_1(); // Error 발생, 기본 생성자가 없기 때문에 매개 변수를 넣으라고 intellij 가 요구합니다.
}
}
this 와 this()
this
- 인스턴스 자신을 가리키는 참조변수
- 인스턴스 메서드(생성자 포함) 에서 사용 가능
- 지역 변수와 인스턴스 변수를 구별할 때 사용
class Tv10_1 {
// 속성 : 변수 선언
boolean power; // 전원상태
int channel; // 채널
String color; // 색깔
long price; // 가격
// 위 속성에서 필수로 초기값이 필요한 값들을 초기화 해주는 기본 생성자
public Tv10_1() {
this.power = false;
this.channel = 1;
}
// 오버로딩 한 생성자 - 매장 진열 용 일 경우에는 가격과 색깔의 초기화가 필요합니다.
public Tv10_1(String color, long price) {
this.power = false;
this.channel = 1;
this.color = color;
this.price = price;
}
// 기능 : 메서드 선언
void power() { // 전원 기능
this.power = !power;
if (this.power) {
System.out.println("전원 ON");
} else {
System.out.println("전원 OFF");
}
}
void channelUp() { // 채널 증가
this.channel++;
System.out.println("채널 증가");
}
void channelDown() { // 채널 감소
this.channel--;
System.out.println("채널 감소");
}
// 색깔을 수정하고 자기 자신을 반환하는 메서드
Tv10_1 changeColor(String color) { // 반환 타입으로 자기자신인 Tv 선언
this.color = color;
System.out.println("색깔 변경 완료!");
return this; // this 는 자기 자신을 가리키는 참조변수!
}
}
class Tv10_1Main {
public static void main(String[] args) {
// 기본 초기화된 Tv10_1 생성
Tv10_1 tv = new Tv10_1();
System.out.print("기본 생성자 Tv10_1: ");
tv.power();
// 진열 용 Tv10_1 생성
Tv10_1 exTv = new Tv10_1("보라색", 3456789);
System.out.print("오버로딩 생성자 Tv10_1: ");
exTv.power();
System.out.println("exTv.color = " + exTv.color);
System.out.println("exTv.price = " + exTv.price);
System.out.println();
// 진열 용 Tv10_1 의 색깔을 수정하고 수정된 객체를 참조변수에 저장하겠습니다.
Tv10_1 exTvThis = exTv.changeColor("파란색");
// 색깔이 변경된 Tv의 주소가 저장된 참조변수 exTvThis 를 사용하여 변경된 색깔 확인
System.out.println("색깔이 변경되었는지 확인 exTvThis.color : " + exTvThis.color);
// 당연히 exTv 이걸로 확인해도 색깔이 변경되어 있습니다.
System.out.println("exTv.color = " + exTv.color);
}
}
this()
- 생성자에서 다른 생성자를 호출할 때 사용한다.
- this()를 사용하지 않고 클래스명(); 이렇게 생성자를 호출하려고 하면 Error가 발생한다.
- 다른 생성자 호출 시 첫 줄에서만 사용 가능하다.
class Tv10_2 {
// 속성 : 변수 선언
boolean power; // 전원상태
int channel; // 채널
String color; // 색깔
long price; // 가격
// 위 속성에서 필수로 초기값이 필요한 값들을 초기화 해주는 기본 생성자
public Tv10_2() {
this.power = false;
this.channel = 1;
}
// 오버로딩 한 생성자 - 매장 진열 용 일 경우에는 가격과 색깔의 초기화가 필요합니다.
public Tv10_2(String color, long price) {
// 아래 초기화 내용은 위에 기본생성자와 완전히 똑같습니다.
// 이럴 때 this() 를 사용합니다.
// this.power = false;
// this.channel = 1;
this(); // 기본 생성자를 호출합니다.
// Tv10_2() // 이렇게는 불가능 합니다!
this.color = color;
this.price = price;
// this(); // 생성자 호출은 반드시 첫 줄에서만 가능합니다.
}
// 기능 : 메서드 선언
void power() { // 전원 기능
this.power = !power;
if (this.power) {
System.out.println("전원 ON");
} else {
System.out.println("전원 OFF");
}
}
void channelUp() { // 채널 증가
this.channel++;
System.out.println("채널 증가");
}
void channelDown() { // 채널 감소
this.channel--;
System.out.println("채널 감소");
}
// 색깔을 수정하고 자기 자신을 반환하는 메서드
Tv10_2 changeColor(String color) { // 반환 타입으로 자기자신인 Tv 선언
this.color = color;
System.out.println("색깔 변경 완료!");
return this; // this 는 자기 자신을 가리키는 참조변수!
}
}
class Tv10_2Main {
public static void main(String[] args) {
// 기본 초기화된 Tv10_2 생성
Tv10_2 tv = new Tv10_2();
System.out.print("기본 생성자 Tv10_2: ");
tv.power();
// 진열 용 Tv10_2 생성
Tv10_2 exTv = new Tv10_2("보라색", 3456789);
System.out.print("오버로딩 생성자 Tv10_2: ");
exTv.power();
System.out.println("exTv.color = " + exTv.color);
System.out.println("exTv.price = " + exTv.price);
System.out.println();
// 진열 용 Tv10_2 의 색깔을 수정하고 수정된 객체를 참조변수에 저장하겠습니다.
Tv10_2 exTvThis = exTv.changeColor("파란색");
// 색깔이 변경된 Tv의 주소가 저장된 참조변수 exTvThis 를 사용하여 변경된 색깔 확인
System.out.println("색깔이 변경되었는지 확인 exTvThis.color : " + exTvThis.color);
// 당연히 exTv 이걸로 확인해도 색깔이 변경되어 있습니다.
System.out.println("exTv.color = " + exTv.color);
}
}