- 객체란 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성과 기능을 가지고 다른 것과 식별이 가능한 것 (ex. 유형, 무형, 개념 등)
2. 객체 지향 프로그래밍(OOP, Object-Oriented Programming)
- 프로그램을 개발하는 기법으로 객체들을 만들고 이러한 객체들을 연결해서 프로그램을 완성하는 기법
- 객체 지향 프로그래밍 특성을 지원하는 언어를 객체 지향 프로그래밍 언어라고 함
- 클래스는 객체의 특성(속성, 기능)을 정의하는 설계도
- 객체의 속성은 필드를 통해서 정의 (변수와 비슷한 개념)
- 객체의 기능은 메소드를 통해서 정의
- 클래스로부터 메모리에 생성된 객체를 해당 클래스의 인스턴스(Instance)라고 표현
- 객체(Object)는 프로그램에서 구현할 대상으로 이를 구현하기 위한 설계도가 클래스(Class)이고, 클래스로부터 메모리에 생성된 실체가 인스턴스(Instance)
더보기
객체 : 프로그램에서 구현할 대상 (붕어빵 틀)
클래스 : 객체를 구현하기 위한 설계도
인스턴스 : 클래스로부터 메모리에 생성된 실체(붕어빵 1, 붕어빵 2, 붕어빵 3, ... 붕어빵n)
- 클래스를 선언하는 구문은 [접근 제한자] [예약어] class 클래스명 { ... }
- 클래스의 이름은 자바의 식별자 작성 규칙에 따라서 만들어야 함
- 소스 파일의 이름은 반드시 선언된 클래스 이름과 같도록 해야 함
- 접근 제한자는 public, default 설정이 가능
- 클래스에는 구성 멤버로 필드(Field), 메소드(Method), 생성자(Constructor)가 정의
public class Member {
// 필드, 생성자, 메소드 정의
...
}
- 클래스로부터 객체를 생성하려면 new 연산자를 사용해서 생성
클래스명 변수명 = new 클래스명();
- new 연산자는 Heap 영역에 객체를 생성하고 객체의 주소값을 리턴
- 객체의 주소값을 참조 타입인 변수에 저장해서 객체를 사용할 수 있음
// new 연산자와 클래스의 생성자를 사용해서 객체를 생성한다.
Member member = new Member();
필드(Field)
- 필드는 객체의 데이터, 상태 등의 속성이 저장되는 공간
- 선언 형태는 변수와 비슷하지만, 필드를 변수라고 부르지 않음
- 필드는 생성자와 메소드 전체에서 사용되며 객체가 생성되고 소멸되기 전까지 객체와 함께 존재
- 필드를 선언하는 구문은 [접근 제한자] [예약어] 자료형 변수명[ = 초기값];
- 필드 선언은 클래스 중괄호 블록 어디서든 존재할 수 있다. 단, 생성자와 메소드 중괄호 블록 내부에는 선언될 수 없음
- 접근 제한자는 public, private, default, protected 설정이 가능
- 필드의 초기값은 필드 선언 시 주어질 수도 있고, 생략될 수도 있음
- 초기값이 지정되지 않은 필드는 객체 생성 시 자동으로 기본 초기값으로 설정
public class Member {
// 필드 정의
public String name; // null
private int age = 20;
// 생성자, 메소드 정의
...
}
- 클래스 내부에서 필드는 생성자와 모든 메소드에서 사용이 가능
- 클래스 외부에서 필드를 사용하려면 클래스로부터 객체를 생성하고 필드를 사용해야 함
- 접근 제한자가 public인 필드의 경우 도트(.) 연산자를 사용해서 필드에 접근할 수 있음
Member member = new Member();
// 도트(.) 연산자를 사용해서 필드에 접근
member.name; // 접근 가능
member.age; // 에러 발생
생성자(Constructor)
- 생성자는 new 연산자로 호출되는 특별한 메소드로 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당
- 모든 클래스는 생성자가 반드시 존재해야 하고 생성자를 하나 이상을 가질 수 있음
- 생성자와 new 연산자에 의해 힙(Heap) 영역에 객체가 생성되고 생성된 객체의 주소를 리턴
- 생성자를 선언하는 구문은 [접근 제한자] 클래스명([매개변수]) { ... }
- 생성자의 선언은 메서드와 다르게 반환값이 없고 생성자명은 클래스명과 똑같이 지정해 주어야 함
- 클래스에 생성자 선언을 생략하면 컴파일러가 내용이 비어있는 기본 생성자(Default Constructor)를 자동으로 추가해 줌
- 단, 클래스에서 생성자를 한 개라도 명시적으로 선언했다면 컴파일러는 기본 생성자를 추가하지 않음
- 생성자도 메소드이기 때문에 오버로딩이 가능하며 오버로딩의 조건은 메소드 오버로딩과 동일
- 생성자 오버로딩을 통해서 여러 개의 생성자를 만들고 객체 생성 시 필요한 생성자를 호출해서 객체를 만들 수 있음
public class Member {
// 필드 정의
private String name;
private int age;
// 생성자 정의
// 기본 생성자
public Member() {
}
// 매개변수가 있는 생성자 (필드 초기화)
public Member(String name, int age) {
this.name = name;
this.age = age;
}
// 메소드 정의
public String information() {
return "이름은 " + this.name + ", 나이는 " + this.age + "살 입니다.";
}
}
Member member1 = new Member(); // 기본 생성자 호출
Member member2 = new Member("홍길동", 38); // 이름과 나이를 매개값으로 받는 생성자 호출
- 객체 내부에서 객체는 자신을 this라고 표현
- 객체 내부에서 다른 멤버에 접근하기 위해 this를 사용
- this는 주로 생성자와 메소드의 매개변수 이름이 필드와 동일한 경우에 매개변수와 필드를 구분하기 위해 사용
- 생성자에서 다른 생성자를 호출할 때 this()를 사용 ( 단, 생성자의 첫 줄에서만 사용해야 함 )
- this()를 통해서 생성자 간에 중복되는 코드를 제거할 수 있음
public class Member {
private String name;
private int age;
public Member() {
// 생성자의 매개변수 타입과 순서에 맞게 전달해야 한다.
this("아무개", 0);
}
public Member(String name, int age) {
this.name = name;
this.age = age;
}
}
메소드(Method)
- 메소드는 객체의 기능, 동작에 해당하는 코드 블록({})
- 메소드는 수학의 함수와 비슷하며 호출을 통해 사용
- 메소드를 호출하게 되면 중괄호 블록에 있는 코드들이 순차적으로 실행
- 메소드는 외부로부터 필요한 값을 전달받을 수도 있고 메소드 실행 후 결과 값을 반환 가능
- 메소드를 선언하는 구문은 [접근 제한자] [예약어] 반환형 메소드명([매개변수]) { ... }
- 메소드 선언은 선언부(리턴 타입, 메소드 이름, 매개변수)와 실행 블록({})으로 구성
- 접근 제한자로는 public, private, default, protected 설정이 가능
- 매개변수는 메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용
- 메소드를 호출한 곳으로 돌아가면서 결과값을 반환하기 위해 return 문을 사용
public class Member {
// 필드 정의
private String name;
private int age;
// 생성자 정의
...
// 메소드 정의
public String information() {
return "이름은 " + this.name + ", 나이는 " + this.age + "살 입니다.";
}
}
- 클래스 내부의 다른 메소드에서 호출할 경우에는 메소드 이름으로 호출하면 됨
- 클래스 외부에서 메소드를 호출할 경우에는 클래스로부터 객체를 생성한 후 메소드를 호출해야 함
- 메소드를 호출하고 리턴 값을 받고 싶다면 변수를 선언하고 대입하면 됨
- 접근 제한자가 public인 메소드의 경우 도트(.) 연산자를 사용해서 메소드를 호출
String info = null;
Member member = new Member();
// 도트(.) 연산자를 사용해서 메소드에 접근
info = member.information();
- 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것
- 메소드 오버로딩을 통해서 매개값을 다양하게 받아서 필요한 처리가 가능
- 메소드 오버로딩의 조건은 매개변수의 타입, 개수, 순서 중 하나가 달라야 함
- 매개변수 이름만 바꾸는 것은 메소드 오버로딩이 아니다. 또한 리턴 타입만 다르고 매개변수가 동일한 것도 메소드 오버로딩이 아님
// 오버로딩의 대표적인 예시
System.out.println(1);
System.out.println(false);
System.out.println('A');
System.out.println("Hello World!");
5. Getter와 Setter 메소드
- 객체 지향 프로그래밍에서 객체의 데이터는 객체 외부에서 직접적으로 접근하는 것이 불가능
- 메소드를 통해서 필드값을 가공한 후 외부로 전달하는 역할을 하는 메소드가 Getter
- 메소드를 통해서 검증된 유효한 값만 데이터로 저장하는 역할을 하는 메소드가 Setter
- 필드 타입이 boolean일 경우에는 Getter는 get으로 시작하지 않고 is로 시작하는 것이 관례
public class Member {
// 필드 선언
private String name;
private int age;
// Getter & Setter
public void setName(String name) {
// 매개변수의 이름과 필드의 이름이 동일할 경우 this를 사용해서 필드에 접근할 수 있다.
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
// 유효한 값만 데이터로 저장되도록 Setter 작성
this.age = (age >= 1) ? age : 1 ;
}
public int getAge() {
return this.age;
}
}