클래스에는 객체가 가져야 할 구성멤버가 선언된다. 구성멤버에는 필드 , 생성자, 메소드가 있다.
필드
객체의 고유 데이터, 객체가 가져야할 부품, 객체의 현재 상태 데이터를 저장하는 곳이다.
자동차 객체를 예를 들어보면 제작회사, 모델, 색깔, 최고 속도는 고유 데이터에 해당하고, 현재 속도, 엔진 회전 수는 상태데이터에 해당한다. 그리고 차체, 엔진,타이어는 부품에 해당한다.
이름은 명사로 만든다.
자동차 객체(객체모델링 ) 자동차 클래스 (클래스구현)
필드 사용
위 그림을 보면 Car클래스의 speed필드는 생성자와 메소드에서 변경이 가능하다.
사용방법은 변수와 동일한데, 차이점은 변수는 자신이 선언된 생성자 또는 메소드 블록 내부에서만 사용할 수 있는 반면 필드는 생성자와 모든 메소드에서 사용이 가능하다. 외부 Person 클래스에서 Car클래스의 speed 필드 값을 사용하려면 Car객체를 사용하려면 Car 객체를 우선 생성해야 한다.
Car myCar = new Car();
myCar 변수가 Car객체를 참조하게 되면 도트(.) 연산자를 사용해서 speed 필드에 접근할 수 있다. 도트(.) 연산자는 객체 접근 연산자로 객체가 가지고 있는 필드나, 메소드를 사용하고자 할 때 사용된다.
메소드
객체사이의 메시지 전달방법이다.
절차 지향에서 함수와 의미가 같다. 메소드 이름은 동사로 만든다.
메소드 선언 : 선언부 ( 리턴타입, 메소드이름, 매개변수선언) 와 실행 블록으로 구성된다. 메소드 선언부를 메소드 시그니처(signature) 이라고 한다.
리턴타입 메소드이름 ([ 매개변수선언 ]) {
실행할 코드를 작성하는 곳
};
리턴타입 : 메소드가 실행 후 리턴하는 값의 타입을 말한다. 메소드는 리턴값이 올 수도 있고 없을 수도 있다.
메소드 실행 후 결과를 호출한 곳에 넘겨줄 경우에 리턴값이 있어야한다.
리턴값이 없는 메소드는 리턴 타입에 void가 와야하며 리턴값이 있는 메소드는 리턴 값의 타입이 와야 한다.
매개 변수 선언 : 메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용된다. 매개 변수도 필요한 경우가 있고 필요없는 경우가 있다. 인자값이 전달될 필요없으면 매개변수를 선언하지 않아도 된다.
double divide(int x, int y ) {
}
double result = divide(10, 20);
호출 시 넘겨준 매개 값인 10과 20은 해당 위치의 매개 변수인 x와 y에 각각 저장되고, 이 매개 변수들을 이용해서 메소드 블록을 실행하게 된다. 매개 값은 반드시 매개 변수의 타입에 부합되는 값이어야한다. divide() 메소드가 int 타입 매개 변수를 가지고 있다면 호출 시 매개값으로 int값이나 int타입으로 변환 될 수 있는 값을 넘겨주어야 한다.
인자가 매개변수를 전달하는 방법
callByValue
자바는 callByValue 방식을 취한다.
쉽게 말해 매개변수에 인자값을 복사 붙히기를 하는 것이라 볼 수 있다.
static void m1(int[] arr) {
arr[0] = 99;
}
public static void main(String[] args) {
int[] arr = new int[3];
arr[0] = 10;
m1(arr);
System.out.println(arr[0]);
}
결과값
99
스택에는 int 타입의 arr 이라는 참조변수 로 들어간다. 이때 참조형으로 들어간다.
heap 에는 new 연산자로 인해 3개의 배열이 생기게 된다.
int [] arr = new int[3]
대입을 통해 스택에 있는 arr 가 heap에 있는 배열을 참조한다.
arr[0] = 10;
arr값 배열 0 번에는 10이 들어가게 된다.
m1(arr);
stack에 들어가 먼저 들어간 arr int[]위에 쌓이게 된다. 여기서 (arr) 인자의 값이 m1 메소드에 있는 인자값의 매개변수로 들어가게 된다.
그렇기 때문에 arr[0]의 값은 99가 힙에 들어가게 되고 최종 결과값은 99가 된다.
매개 변수의 수를 모를경우
메소드의 매개 변수는 개수가 이미 정해져 있는 것이 일반적이지만, 경우에 따라서는 메소드를 선언할 때 매개 변수의 개수를 알 수 없는 경우가 있다.
int sum(int ... values){
}
int result = sum(1, 2, 3 );
int result = sum(1, 2, 3, 4, 5);
매개 변수를 배열 타입으로 선언하면, 메소드를 호출하기전에 배열을 생성해야 하는 불편한 점이 있다. 그래서 배열을 생성하지 않고 값의 리스트만 넘겨주는 방법이 있다. " ... " 를 사용해서 선언하게 되면, 메소드를 호출시 넘겨준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용된다.
" ... " 는 즉 가변길이를 갖는 매개변수이다.
리턴 값이 있는 메소드
매소드 선언에 리턴타입이 있는 메소드는 반드시 리턴(return)문을 사용해서 리턴값을 지정해야한다. return문이 없다면 컴파일오류가 발생한다.
리턴 값이 없는 메소드 (void)
void 로 선언된 리턴값이 없는 메소드에서도 return 문을 사용할 수 있다.
void 는 리턴값이 없는 메소드이다. 그렇지만 void와 return문이 같이 사용할 때에는 메소드를 강제로 종료하게 된다.
메소드 오버로딩
클래스 내에 같은 메소드를 여러개 선언하는 것을 메소드 오버로딩이라고 한다. 오버로딩의 사전적인 의미는 많이 싣는 것을 뜻한다. 하나의 메소드 이름으로 여러 기능을 담는다하여 붙여진 이름이라 생각할 수 있다. 절차지향에서는 존재하지 않지만 객체지향에서는 오버로딩이의 개념이 있다.
객체지향프로그램의 목적은 클래스의 재사용성을 높이는 것이 가장 큰 이유가 된다. 그렇기 위해서는 사용법을 문서화를 하며 이것을 지원하는 것이 javadoc 라고 하며 /** */ 를 사용한다.
그다음으로는 사용이 편리해야한다. 기능은 같다고 할 때 사용자 입장에서 메소드 이름을 하나만 기억하고 사용할 수 있기 때문에 훨씬 편리하다.
메소드 이름이 동일하고 매개변수만 다르다 = 오버로딩이라 한다.
정확히는 이름은 같고 매개변수 자료형, 개수, 순서를 다르게 표현한다.
package oop;
class Culculator { // 비슷한 기능이기 때문에 이름을 같게 한다.
void plus(int a, int b) {
System.out.println(a + b);
}
void plus(double a, double b) {
System.out.println(a + b);
}
void plus(int a, int b, int c) {
System.out.println(a + b + c);
}
void plus(int a, double b) {
System.out.println(a+b);
}
void plus(double a, int b) {
System.out.println(a+b);
}
}
public class Overload { // main메서드가 public으로 되어있어야하며 그 클래서 이름이 .java이름이여야한다
public static void main(String[] args) {
Culculator c = new Culculator();
c.plus(1, 2);
c.plus(3.5, 5.6);
c.plus(1, 2, 3);
}
}
대표적으로 println을 보았을 때 오버로딩이 사용된 것을 알 수 있다.
10개의 메소드가 오버로딩이 되어 있는 것을 볼 수 있다.
'java' 카테고리의 다른 글
java_6_ static (0) | 2021.10.14 |
---|---|
java_6_ 클래스 구성 (생성자) (0) | 2021.10.14 |
Selection Sort & Bubble Sort (0) | 2021.10.13 |
java_4_객체와 클래스 (메모리영역) 실습 (0) | 2021.10.12 |
java_4_객체와 클래스 (메모리영역) 개념 (0) | 2021.10.12 |