[자바의 정석] CHAPTER 6: 객체지향 프로그래밍 Ⅰ
1. 객체지향언어
- 코드의 재사용성이 높다.
새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다. - 코드의 관리가 용이하다.
코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다. - 신뢰성이 높은 프로그래밍을 가능하게 한다.
제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.
2. 클래스와 객체
객체와 인스턴스
class Tv{
// TV의 속성(멤버변수)
String color; // 색상
boolean power; // 전원상태(on/off)
int channel; // 채널
void power(){power = !power;} // tv를 켜거나 끄는 기능을 하는 메서드
void channelUp(){++channel;} // tv의 채널을 높이는 기능을 하는 메서드
void channelDown(){--channel;} // tv의 채널을 낮추는 기능을 하는 메서드
}
public class TvTest {
public static void main(String args[]){
Tv t1 = new Tv(); // tv 인스턴스를 참조하기 위한 변수 t를 선언하고, 인스턴스 생성한다.
Tv t2 = new Tv();
t1.channel = 7; // tv 인스턴스의 멤버변수 channel의 값을 7로 한다.
t1.channelDown(); // tv 인스턴스의 메서드를 호출한다.
System.out.println("현재 채널은 " + t1.channel + "입니다.");
}
}
- 참조변수에는 하나의 값(주소)만 저장될 수 있으므로 둘 이상의 참조변수가 하나의 인스턴스를 가리키는 것은 가능하지만 하나의 참조변수로 여러 개의 인스턴스를 가리키는 것은 가능하지 않다.
클래스
- 객체지향이론의 관점
- 객체를 생성하기 위한 틀 / 클래스는 속성과 기능으로 정의되어있다.
- 프로그래밍적인 관점
- 데이터와 함수의 결함
- 데이터와 함수는 관계가 깊다.
- 데이터와 함수의 결함
c언어에서는 문자열을 문자의 배열로 다루지만, 자바에서는 String이라는 클래스로 다루는 이유?
문자열과 문자열을 다루는데 필요한 함수들을 함께 묶기 위해서이다.
3. 변수와 메서드
선언위치에 따른 변수의 종류
- 멤버변수
- 클래스변수(static 변수, 공유변수)
- 인스턴스를 생성하지 않고도, 언제라도 바로 사용할 수 있다.
- 인스턴스변수
- 인스턴스 생성후에 사용가능하다.
- 클래스변수(static 변수, 공유변수)
- 지역변수
- 지역변수가 선언된 블럭{} 내에서만 사용가능하다.
메서드를 사용하는 이유
- 높은 재사용성
한번 만들어 놓은 메서는 몇번이고 호출할 수 있다. - 중복된 코드의 제거
반복적으로 나타나는 문장들을 메서드로 만들어서 사용하면 코드의 중복이 제거되고, 변경사항이 발생했을 때 이 메서드만 수정하면 된다. - 프로그램의 구조화
전체흐름이 한눈에 들어올 정도록 단순하게 구조화하는 것이 좋다. 프로그램에 문제가 발생해도 해당 부분을 쉽게 찾아서 해결할 수 있다.
JVM의 메모리 구조
- 기본형 매개변수
- 원본이 아니라 복사본이 변경
class Data{
int x;
}
public class PrimitiveParamEx {
public static void main(String args[]) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d.x);
System.out.println("After change(d.x)");
System.out.println("main() : x = " + d.x);
}
static void change(int x) {
x = 1000;
System.out.println("change() : x = " + x);
}
}
change() : x = 1000
After change(d.x)
main() : x = 10
- 참조형 매개변수
- 값이 아니라 값이 저장된 주소를 넘겨준다.
class Data{
int x;
}
public class ReferenceParamEx {
public static void main(String[] args) {
Data d = new Data();
d.x = 10;
System.out.println("main() : x = " + d.x);
change(d);
System.out.println("After change(d)");
System.out.println("main() : x = " + d.x);
}
static void change(Data d) {
d.x = 1000;
System.out.println("change() : x = " + d.x);
}
}
main() : x = 10
change() : x = 1000
After change(d)
main() : x = 1000
- 반환타입이 참조형이라는 것은 메서드가 객체의 주소를 반환한다는 것을 의미한다.
클래스 메서드와 인스턴스 메서드
- 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.
- 생성된 각 인스턴스는 서로 독립적이기 때문에 각 인스턴스 변수는 서로 다른 값을 유지한다. 그러나 모든 인스턴스에서 같은 값이 유지되어야 하는 변수는 static을 붙여서 클래스변수로 정의해야 한다.
- 클래스 변수(static변수)는 인스턴스를 생성하지 않아도 사용할 수 있다.
- static이 붙은 변수는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문이다.
- 클래스 메서는 인스턴스 변수를 사용할 수 없다.
- 인스턴스변수는 인스턴스가 반드시 존재해야만 사용할 수 있는데, 클래스메서드는 인스턴스 생성 없이 호출이 가능하므로 클래스 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수도 있다.
- 인스턴스변수나 인스턴스메서드에는 static이 붙은 멤버들을 사용하는 것이 언제나 가능하다.
- 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
- 메서드의 작업내용 중에서 인스턴스 변수를 필요로 한다면, static을 붙일 수 없다.
- 인스턴스 변수를 필요로 하지 않는다면, static을 붙이자.
- 메서드 호출시간이 짧아지므로 성능이 향상된다.
class MyMath{
long a, b;
long add() { return a + b;}
long subtract() { return a - b;}
static long add(long a, long b) { return a + b;}
static long subtract(long a, long b) { return a - b;}
}
public class MyMathTest {
public static void main(String[] args) {
// 클래스 메서드 호출. 인스턴스 생성없이 호출가능
System.out.println(MyMath.add(200, 201));
System.out.println(MyMath.subtract(200, 201));
MyMath mm = new MyMath();
mm.a = 200;
mm.b = 201;
// 인스턴스 메서드는 객체생성 후에만 호출이 가능함
System.out.println(mm.add());
System.out.println(mm.subtract());
}
}
4. 오버로딩
오버로딩의 조건
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 반환타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.
가변인자와 오버로딩
public class VarArgxEx {
public static void main(String[] args) {
String[] strArr = {"100", "200"};
System.out.println(concatenate("", "100", "200")); // 컴파일에러 발생
System.out.println(concatenate("", strArr));
}
static String concatenate(String delim, String... args) {
String result = "";
for (String str : args) {
result += str + delim;
}
return result;
}
static String concatenate(String... args) {
return concatenate("", args);
}
}
- 가변인자를 선언한 메서드를 오버로딩하면, 메서드를 호출했을 때 구별되지 못하는 경우가 발생하기 쉽다.
- 가능하면 가변인자를 사용한 메서드는 오버로딩하지 않는 것이 좋다.
5. 생성자
생성자란?
인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드이다.
인스턴스 생성 시에 실행되어야 할 작업을 위해서도 사용된다.
생성자에서 다른 생성자 호출하기 - this(), this
- 생성자의 이름으로 클래스이름 대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 반드시 첫줄에서만 호출이 가능하다.
- 생성자 내에서 초기화 작업도중에 다른 생성자를 호출하게 되면, 호출된 다른 생성자 내에서도 멤버변수들을의 값을 초기화할 것이므로 다른 생성자를 호출하기 이전의 초기화 작업이 무의미해질 수 있다.(로직이 복잡해져서?)
- this : 인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어 있다. 모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재한다.
- this(), this(매개변수) : 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
6. 변수의 초기화
- 멤버 변수는 초기화를 하지 않아도 자동적으로 변수의 자료형에 맞는 기본값으로 초기화가 이루어진다.
- 지역변수는 사용하기 전에 반드시 초기화해야 한다.
멤버 변수의 초기화 방법
- 명시적 초기화
- 변수를 선언과 동시에 초기화하는 것
- 생성자
- 초기화 블럭
- 인스턴스 초기화 블럭: 인스턴스변수를 초기화 하는데 사용
- 클래스 초기화 블럭: 클래스변수를 초기화 하는데 사용
클래스 초기화 블럭은 클래스가 메모리에 처음 로딩될 때 한번만 수행
인스턴스 초기화 블럭은 생성자와 같이 인스턴스를 생성할 때마다 수행
생성자보다 인스턴스 초기화 블럭이 먼저 수행
클래스가 처음 로딩될 때 클래스 변수들이 자동적으로 메모리에 만들어지고, 클래스 초기화블럭이 클래스변수들을 초기화
멤버변수의 초기화 시기와 순서
- 클래스 변수의 초기화 시점: 클래스가 처음 로딩될 때 단 한번 초기화된다.
- 클래스 변수의 초기화 순서: 기본값 -> 명시적 초기화 -> 클래스 초기화 블럭
- 인스턴스 변수의 초기화 시점: 인스턴스가 생성될 때마다 각 인스턴스별로 초기화가 이루어진다.
- 인스턴스 변수의 초기화 순서: 기본값 -> 명시적 초기화 -> 인스턴스 초기화 블럭 -> 생성자
Author And Source
이 문제에 관하여([자바의 정석] CHAPTER 6: 객체지향 프로그래밍 Ⅰ), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@haron/자바의-정석-CHAPTER-6저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)