2023. 1. 3. 17:43ㆍJava
0. 객체지향언어의 주요특징
1. 코드의 재사용성
: 새로운 코드 작성 시 기존 코드 이용 가능
2. 코드의 관리가 용이
: 쉽게 코드 변경 가능
3. 신뢰성이 높은 프로그래밍의 가능
: 코드의 중복 제거 가능
1. 클래스와 객체
- 클래스
- 쉽게 말해, '객체의 설계도'.
- 객체를 정의해놓은 것으로, 객체를 생성하는 데 사용되는 수단.
- 객체
- 쉽게 말해, '실제로 존재하는 것'.
- 프로그래밍에서의 객체는 클래스에 정의된 내용대로 메모리에 생성된 것을 말함.
프로그래밍에서는 먼저 클래스를 작성하여, 클래스로부터 객체를 생성해 생성된 객체를 사용함.
1-1.객체와 인스턴스
클래스로부터 객체를 만드는 과정 → 클래스의 인스턴스화(instantiate)
클래스로부터 만들어진 객체 → 클래스의 인스턴스(instance)
인스턴스와 객체 모두 같은 의미이지만, 객체는 모든 인스턴스를 대표하는 포괄적인 의미를 갖는 반면, 인스턴스는 어떤 클래스로부터 만들어졌는지를 밝히는 구체적 의미를 갖고 있음.
1-2.객체
객체는 속성과 기능의 두 가지 구성요소로 이루어져 있음.
속성(property) - 멤버변수(member variable), 특성(attribute), 필드(field), 상태(statue)
기능(function) - 메서드(method), 함수(function), 행위(behavior)
2. 변수와 메서드
2-1. 변수의 종류
- 클래스의 필드(field)
- 클래스에 포함된 변수(variable)
- 선언된 위치와 선언자에 따라 클래스 변수, 인스턴스 변수, 지역 변수로 구분됨.
- 클래스 변수
- 클래스 영역에 위치한 변수 중 static을 가지는 변수.
- 모든 인스턴스가 공통된 저장공간을 공유하게 되므로, 한 클래스의 모든 인스턴스가 공유해야 하는 공통된 값을 유지하기 위해 사용됨.
- 클래스 변수는 인스턴스를 생성하지 않고도 바로 사용할 수 있음.
변수 | 선언위치 | 생성시기 | 소멸시기 | 저장메모리 |
클래스변수 (class variable) |
클래스 영역 | 클래스가 메모리에 올라갈 때 | 프로그램이 종료될 때 | 메소드 영역 |
인스턴스 변수 (instance variable) |
인스턴스가 생성되었을 때 | 인스턴스가 소멸될 때 | 힙 영역 | |
지역변수 (local variable) |
클래스 영역 이외의 영역(메서드, 생성자, 초기화 블록 내부) | 블록 내에서 변수 선언문이 수행되었을 때 | 블록을 벗어날 때 | 스택 영역 |
class Book {
String author; //클래스 변수
String title;
static String publisher = "sy"; //인스턴스 변수
}
public class FieldTest {
public static void main(String[] args) {
Book book1 = new Book();
Book book2 = new Book();
Book book3 = new Book();
book1.author = "author1";
book2.author = "author2";
book3.author = "author3";
book1.title = "t1";
book2.title = "t2";
book3.title = "t3";
book1.publisher = "ys";
System.out.println(book1.author+ ", " + book1.title + ", " + book1.publisher); //author1, t1, ys
System.out.println(book2.author + ", " + book2.title + ", " + book2.publisher); //author2, t2, ys
}
}
Book 인스턴스 book1, book2, book3는 클래스 변수 publisher를 공유하므로, book1의 publisher 값을 변경하면, book2, book3의 publisher 값도 바뀌게 됨.
2-2. 메서드
메서드란 클래스 내부의 함수를 의미. 즉, 클래스 내부의 변수들을 사용하여 특정 작업을 수행하는 함수.
메서드의 이점
1. 높은 재사용성
2. 중복된 코드의 제거
3. 프로그램의 구조화
메서드의 선언과 구현
접근제어자 반환타입 메소드명(입력자료형1 매개변수1, 입력자료형2, 매개변수2, ...) { //선언부
//구현부
return 반환값;
}
<선언부(header)>
- 접근 제어자/지정자 : 해당 메서드에 접근할 수 있는 범위를 명시
- 반환 타입 : 메서드가 모든 작업을 마치고 반환하는 데이터의 타입을 명시, 반환할 값이 없으면 "void"를 적어야 함
- 메서드명 : 메서드를 호출하기 위한 이름
- 매개변수 목록(parameters) : 메서드의 작업 수행에 필요한 인수 값들을 저장할 변수들을 선언, 각각의 변수에 타입을 지정해주어야 함
<구현부(body)>
- 메서드의 기능을 수행하는 명령문의 집합
- 선언부 다음에 오는 괄호({}) 부분
- void가 아닌 반환 타입의 경우 모두 'return 반환값'이 반드시 존재해야 하며, 이 반환값은 선언부의 반환타입과 일치하거나 자동 형변환이 가능한 것이어야 함
지역변수(local variable) : 메서드 내에서 선언된 변수로, 메서드 내에서만 사용하고 메서드가 종료되면 자동소멸됨.
인수와 매개변수
public class Main {
public static int mul(int a, int b) { // 변수 a, b는 매개변수(parameter)
return a*b;
}
public static void main(String[] args) {
Main.mul(5,6); //입력값 5,6은 인수(argument)
}
}
- 매개변수(parameter) : 메서드를 정의할 때, 입력으로 전달된 값을 받는 변수
기본형 매개변수 : 변수의 값을 읽기만 할 수 있음(read only).
즉, 메서드의 매개변수가 기본형이면 단순히 '값'만 얻어옴.
참조형 매개변수 : 변수의 값을 읽고 변경할 수 있음(read & write)
즉, 메서드의 매개변수가 참조형이면 '값이 저장된 주소'를 얻어옴.
- 인수(argument) : 메서드를 호출할 때 전달하는 입력값. 즉, 메서드 호출시 괄호() 안에 지정해준 값
JVM의 메모리 구조와 메서드의 호출 흐름
- 메서드 영역(method area)
: 프로그램 실행 중 어떤 클래스가 사용되면, 클래스에 대한 정보(클래스 데이터)와 클래스변수(cv)가 메서드 영역에 저장됨
- 힙(heap)
: 인스턴스가 생성되는 공간으로, 프로그램 실행 중 생성되는 모든 인스턴스가 저장됨. 즉, 인스턴스 변수(iv)들이 생성되는 공간.
- 호출스택(call stack)
: 메서드의 작업에 필요한 메모리 공간을 제공. 메서드가 호출되면 호출스택에 호출된 메서드를 위한 메모리가 할당되며, 이 메모리는 메서드가 작업을 수행하는 동안 지역변수(매개변수 포함)들과 연산의 중간결과 등을 저장하는데 사용. 메서드가 작업을 마치면 할당된 메모리 공간은 반환되어 비워짐.
<호출스택에서의 메서드 호출 흐름>
- 메서드가 호출되면, 메서드를 위한 메모리가 스택에 할당.
- 메서드 작업 수행이 완료되면 메모리가 반환되어 스택이 제거.
- 즉, 맨 위의 스택은 현재 실행 중인 메서드.
- 아래에 있는 스택은 바로 위의 메서드를 호출한 메서드
클래스 메서드/ 인스턴스 메서드
- 클래스 메서드(static method)
- static이 붙어있는 메서드
- 인스턴스를 생성하지 않고도 바로 사용 가능
- static 메서드 내부에서 인스턴스 변수 사용 불가능(인스턴스 변수를 사용하지 않는 메서드)
- 인스턴스 메서드(instance method)
- static이 붙어있지 않은 메서드
- 인스턴스 변수와 관련된 작업을 하는 메서드(인스턴스 변수가 반드시 필요)
메서드 간 호출과 참조
같은 클래스에 속한 멤버들 간에는 별도의 인스턴스 생성 없이도 서로 참조/호출이 가능.
하지만 클래스 멤버가 인스턴스 멤버를 참조/호출하기 위해서는 반드시 인스턴스를 생성해야 함.
클래스 멤버는 항상 존재하지만 인스턴스 멤버는 인스턴스 생성 후에 존재하므로 클래스 멤버가 호출하는 시점에 인스턴스 멤버가 존재하지 않을 수 있기 때문임.
3. 오버로딩(Overloading)
3-1. 메서드 오버로딩(method overloading)
한 클래스 내에 같은 이름의 메서드 여러개를 중복하여 정의해 다양한 상황에서 사용하는 것.
단, 매개변수의 개수나 타입이 달라야 함.
메서드 오버로딩을 간단히 '오버로딩(overloading)'이라 부름.
< 오버로딩의 조건>
1. 메서드 이름이 같아야 함.
2. 매개변수의 개수 또는 타입이 달라야 함.
class Example {
void sum(){
System.out.println(0);
}
//메서드 오버라이딩
void sum(int num){
System.out.println(num);
}
//메서드 오버라이딩2
void sum(int num1, int num2){
System.out.println(num1+num2);
}
//메서드 오버라이딩3
void sum(String string1, String string2){
System.out.println(string1 + ", " + string2);
}
}
4. 생성자(Constructor)
4-1. 생성자
인스턴스가 생성될 때 호출되는 인스턴스 초기화 메서드.
인스턴스 변수의 초기화 작업 및 인스턴스 생성 시 실행되어야 할 작업을 위해 사용됨.
- 생성자의 이름은 클래스의 이름과 동일해야 함.
- 생성자는 리턴 값을 가질 수 없음.
- 생성자는 인스턴스 생성 시 반드시 호출되며, 인스턴스 당 한 번 호출됨.
- 개발자가 생성자를 작성하지 않았더라도, 컴파일러가 자동으로 기본 생성자를 삽입함.
- 생성자는 여러 개 작성 가능(오버로딩).
- 생성자도 메서드이다.
class Book {
String author;
String title;
String publisher;
Book(String author, String title, String publisher){
this.author = author;
this.title = title;
this.publisher = publisher;
}
}
public class Main{
public static void main(String[] args){
Book book1 = new Book("남궁성", "자바의 정석" "도우출판");
Book book2 = new Book("황기태&김효수", "명품 JAVA Programming", "생능출판");
}
}
4-2. 기본 생성자
모든 클래스에는 반드시 하나 이상의 생성자가 정의되어 있어야 함. 하지만 개발자가 클래스에 생성자를 정의하지 않더라도 오류가 나지 않는데, 이는 컴파일러가 기본 생성자를 자동으로 삽입하기 때문임.
기본생성자
: 매개변수를 하나도 가지지 않으며, 아무런 명령어도 포함하고 있지 않은 생성자.
단, 매개변수를 가지는 생성자를 개발자가 정의했다면, 기본생성자는 추가되지 않음.
위의 예에서 'Book book3 = new Book();'를 바로 마지막 줄에 추가한다면, 컴파일 에러가 발생할 것임.
하지만, 밑의 예에서는 어떠한 생성자도 정의해놓지 않았으므로, 기본 생성자가 추가되어 에러가 발생하지 않음.
class Book {
String author;
String title;
String publisher;
//자동으로 기본생성자가 삽입됨
}
public class Main{
public static void main(String[] args){
Book book1 = new Book(); //컴파일 에러가 발생하지 않음
}
}
4-3. this 참조변수와 this() 메서드
this 참조변수
- 자기자신을 가키키는 참조변수
- 해당 인스턴스의 주소를 가리키고 있음
- 인스턴스 변수와 지역변수/매개변수 간의 구별에 용이(특히, 변수명이 같을 경우)
- 인스턴스 자기 자신의 레퍼런스 반환시에도 유용
- 클래스 멤버는 사용 불가능함
class Book {
private String author;
private String title;
private String publisher;
//인스턴스 변수와 매개변수의 변수명이 동일, 구분 위해 this 참조변수 사용
Book(String author, String title, String publisher) {
this.author = author;
this.title = title;
this.publisher = publisher;
}
}
this( ) 메서드
- 같은 클래스의 다른 생성자 호출 시 사용하는 메서드
- 단, 생성자 내부에서만 사용 가능하며, 해당 생성자의 첫 줄에서 호출해야 함
- this( ) 메서드에 인수를 전달하면, 정의되어 있는 다른 생성자를 찾아 호출해 줌
class Book {
private String author;
private String title;
private String publisher;
//인수가 일치하는 다른 생성자를 호출해 줌
Book(){
this("남궁성", "자바의 정석", "도우출판");
}
Book(String author, String title, String publisher){
this.author = author;
this.title = title;
this.publisher = publisher;
}
void getTitle(){
System.out.println(this.title);
}
}
public class Main{
public static void main(String[] args){
Book book1 = new Book();
book1.getTitle(); //자바의 정석
}
}
5. 초기화
5-1. 변수의 초기화
- 멤버 변수(클래스 변수 & 인스턴스 변수) , 배열 : 필수가 아니라 선택
- 지역변수 : 반드시 초기화해야 함(필수)
5-2. 멤버 변수 초기화
- 일반적으로 멤버변수는 각 타입의 기본값으로 자동적으로 초기화 됨(자동 초기화).
명시적 초기화(explicit initialization)
: 변수 선언과 동시에 초기화하는 것으로 간단하고 명료함.
class Book {
String author = "남궁성"; // 명시적 초기화
}
초기화 블록(initialization block)
- 클래스 초기화 블록
- 클래스 변수의 복잡한 초기화에 사용
- 처음 메모리에 로딩될 때(클래스 생성 시에) 한 번만 수행됨
- 인스턴스 초기화 블록과 달리 블록 앞에 static이 붙은 것
- 인스턴스 초기화 블록
- 인스턴스 변수의 복잡한 초기화에 사용
- 클래스 내 블록{} 을 만들고 그 안에 코드를 작성
- 인스턴스 생성시마다 동작함
class Example {
static {
System.out.println("클래스 초기화 블록");
}
{
System.out.println("인스턴스 초기화 블록");
}
}
public class Main {
public static void main(String[] args){
//클래스 초기화 블록
Example example1 = new Example(); //인스턴스 초기화 블록
Example example2 = new Example(); //인스턴스 초기화 블록
}
}
<참고자료>
자바의 정석(3rd edition) - 도우출판
'Java' 카테고리의 다른 글
[JAVA]컬렉션 프레임워크(Collections Framework) (0) | 2023.01.15 |
---|---|
[JAVA] HashMap을 키(key), 값(value) 기준으로 정렬하는 방법 (1) | 2023.01.06 |
[JAVA] 객체지향 프로그래밍2 (0) | 2023.01.03 |