클래스
<객체란?>
-물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있으면서 식별 가능한 것을 말한다.
쉽게 말해, 물리적으로 존재하는 자동차,자전거, 책, 사람과
추상적인 학과, 강의, 주문 등이 모두 객체가 될 수 있다.
객체는 속성과 동작으로 구성되어 있다. 예를 들어, 사람은 이름, 나이, 등의 속성과 웃다, 걷다 등의 동작이 있고,
자동차는 색깔, 모델명 등의 속성과, 달린다, 멈춘다 등의 동작이 있다.
자바는 이 속성과 동작을 각각 필드(field)와 메서드(method)라고 부른다.
*현실 세계의 객체를 소프트웨어 객체로 설계하는 것을 '객체 모델링' 이라고 부른다.
<메서드 호출>
-매개값은 메서드를 실행하기 위해 필요한 데이터이다. 예를 들어 10과 20을 주고 더하기 기능을 이용한다고 했을 때
10과 20이 더하기 기능의 '매개값'이다. 리턴값은 메서드가 실행되고 난후 호출한 곳으로 돌려주는(리턴하는) 값이다.
<객체 간의 관계>
객체는 개별적으로 사용될 수 있지만, 대부분 다른 객체와 관계를 맺고 있다. 이 관계의 종류에는 집합 관계, 사용 관계,
상속 관계가 있다.
<객체와 클래스>
-자바에서는 설계도가 바로 '클래스'이다. 클래스에는 객체를 생성하기 위한 필드와 메서드가 정의되어 있다.
클래스로부터 만들어진 객체를 해당 클래스의 '인스턴스'라고 한다.
자동차 객체는 자동차 클래스의 '인스턴스'인 셈이다. 그리고 클래스로부터 객체를 만드는 과정을 '인스턴스화'라고 한다.
하나의 클래스로부터 여러 개의 인스턴스를 만들 수 있는데, 이것은 동일한 설계도로부터 여러 대의 자동차를 만드는 것과 같다.
<클래스 선언>
-첫 글자는 대문자로!!
일반적으로 파일당 하나의 클래스를 선언한다. 하지만 2개 이상의 클래스 선언도 가능하다.
<객체 생성과 클래스 변수>
-클래스 선언 후 컴파일을 했다면(이클립스에선 저장을 뜻함) 객체를 생성할 설계도가 만들어진 셈이다.
클래스로부터 객체를 생성하려면 다음과 같이 new연산자를 사용하면 된다.
클래스 변수;
변수 = new 클래스();
클래스 변수 선언과 객체 생성을 1개의 실행문으로도 작성이 가능하다.
클래스 변수 = new 클래스();
<클래스의 구성 멤버>
-클래스에는 객체가 가져야 할 구성 멤버가 선언된다. 구성 멤버에는 필드, 생성자, 메서드가 있다.
이 구성 멤버들은 생략되거나 복수의 개수로 작성될 수 있다.
1. 필드
-선언 형태는 변수와 비슷하지만, 필드를 변수라고 부르지는 않는다.
2. 생성자
-new 연산자로 호출되는 특별한 중괄호{} 블록이다. 생성자의 역할은 객체 생성 시 초기화를 담당한다.
3. 메서드
-객체의 동작에 해당하는 중괄호{} 블록을 말한다. 중괄호 블록은 이름을 가지고 있는데, 이것이 메서드의 이름이다.
자세한 내용은 뒤에 추가로 설명..
<정리>
클래스 : 객체를 만들기 위한 설계도
객체 : 클래스로부터 생성되며 new 클래스()로 생성한다.
new 연산자 : 객체 생성 연산자이며, 생성자를 호출하고 객체 생성 번지를 리턴한다.
클래스 변수 : 클래스로 선언한 변수를 말하며 해당 클래스의 객체 번지가 저장된다.
인스턴스 : 객체는 클래스의 인스턴스이다.
클래스 멤버 : 클래스에 선언되는 멤버는 필드, 생성자, 메서드가 있다.
<클래스 변수와 인스턴스 변수>
공통적인 속성은 클래스 변수로 static을 붙여서 선언한다.
개별 속성은 인스턴스 변수로 선언한다.
<static 메서드와 인스턴스 메서드>
-static 메서드는 지역변수를 사용한다.
클래스이름. 메서드이름으로 호출한다.
-인스턴스 메서드는 인스턴스 변수를 사용한다.
객체를 생성하여 사용해야 하며, 객체이름. 메서드이름으로 호출한다.
static메서드는 클래스 형태이며 지역변수를 사용하기 때문에 인스턴스 메서드를 호출할 수 없고,
반대로 인스턴스 메서드는 static메서드를 호출 할 수 있다.
static 메서드는 객체 생성이 필요 없기 때문에 쉽게 호출 할 수 있는 특징이 있다.
생성자
-생성자는 new연사자로 클래스로부터 객체를 생성할 때 호출되어 객체의 초기화를 담당한다.
객체 초기화란 필드를 초기화하거나 메서드를 호출해서 객체를 사용할 준비를 하는 것을 말한다.
생성자를 실행하지 않고는 클래스로부터 객체를 만들 수 없다.
생성자가 실행되면 heap영역에 객체가 생성되고 객체의 번지가 리턴된다.
리턴된 객체의 번지는 클래스 변수에 저장된다.
-모든 클래스는 생성자가 반드시 존재하며, 생성자를 하나 이상 가질 수 있다.
클래스에서 생성자 선언을 생략했다면, 컴파일러는 중괄호 블록 내용이 비어있는 기본 생성자를 바이트 코드에 자동 추가한다.
클래스가 public class로 선언이 되면 기본 생성자도 public이 붙는다.
그러나 클래스에 명시적으로 선언한 생정자가 1개라도 있으면 컴파일러는 기본생성자를 추가하지 않는다.
명시적으로 생성자를 선언하는 이유는 객체를 다양한 값으로 초기화하기 위해서다.
-생성자는 리턴 타입이 없고, 클래스의 이름과 동일하다. 그리고 생성자 블록 내부에는 객체 초기화 코드가 작성되는데,
일반적으로 필드에 초기값을 저장하거나 메소드를 호출하여 객체 사용 전에 필요한 준비를 한다.
생성자 선언이 되어 있으면 객체를 생성할 때 그냥 할 수 없고 값을 넣어주어야 정상적인 객체를 만들 수 있다.
Car(String color, int cc){
}
Car myCar = new Car(); X
Car myCar = newCar("검정",3000); O
<필드 초기화>
-클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정된다.
초기 생성 값이 아닌 다른 값으로 초기화하고 싶다면 다음처럼 실행하면 된다.
public class korean {
String nation = "대한민국";
String name;
String ssn;
korean k1 = new korean();
korean k2 - new korean();
<정리>
기본 생성자 : 클래스 선언 시 컴파일러에 의해 자동으로 추가되는 생성자이다.
생성자 선언 : 클래스로부터 객체를 생성할 때 호출되는 생성자를 명시적으로 선언할 수 있다.
생성자를 선언하면 기본 생성자는 생성되지 않는다.
매개 변수 : 생성자 호출 시 값을 전달받기 위해 선언되는 변수를 말한다.
객체 초기화 : 객체를 사용하기 전에 준비하는 과정으로 필드를 선언할 때 초기화하거나 생성자 내부에서 필드값을
초기화할 수 있으며, 메서드를 호출하는 내용으로 구성된다.
오버로딩 : 매개 변수를 달리하는 생성자를 여러 개 선언하는 것을 말한다.
this() : 객체 자신의 또 다른 생성자를 호출할 때 사용한다.
메소드
-메서드는 객체의 동작에 해당하는 중괄호{}블럭을 말한다.
중괄호 블록 이름이 메소드 이름이며, 메서드를 호출하면 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행된다.
-메서드 선언은 선언부와 실행 블록으로 구성된다. 선언부와 실행 블록에는 다음 요소를 포함한다.
리턴 타입 : 메서드가 리턴하는 결과의 타입을 표시.
메소드 이름 : 메서드의 기능이 드러나도록 식별자 규칙에 맞게 이름을 지어준다.
매개 변수 선언 : 메서드를 실행할 때 필요한 데이터를 받기 위한 변수를 선언한다.
메소드 실행 블록 : 실행할 코드를 작성한다.
<리턴 타입>
-리턴 타입은 리턴값의 타입을 말한다. 리턴값이란 메서드를 실행한 후의 결과값을 말한다.
메서드는 리턴값이 있을 수도 있고 없을 수도 있으나 리턴값이 있을 경우 리턴 타입이 선언부에 명시되어야 한다.
(리턴값이 없다면 void로 명시)
-메서드를 호출할 때도 리턴값이 있는 경우엔 그 리턴값을 받을 변수를 선언해서 받아줘야 한다.
>> double result = divide(10,20);
위와 같이 double타입의 result 변수에 divide메서드를 실행하고 리턴받은 값을 넣어준다.
만약 변수 타입이 맞지 않다면 컴파일 에러가 발생한다.
하지만 리턴타입이 있다고 해서 '반드시' 리턴값을 변수에 저장할 필요는 없다. 리턴값이 중요하지 않고,
메소드 실행이 중요할 경우에는 변수를 선언하지 않고, 메소드를 호출할 수도 있다.
<메서드 이름>
-숫자시작 안됨
-관례적으로 메소드 이름은 소문자로 작성.
-카멜케이스
-메서드 이름은 어떤 기능을 수행하는지 쉽게 알 수 있도록 기능 이름으로 지어주는 것이 좋다.
<매개 변수 선언>
-매개 변수는 메서드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용된다.
메서드에서 매개 변수가 필요한 경우가 있고, 필요 없는 경우가 있다.
다음은 매개 변수가 있는 divide() 메소드 선언의 예
double divide (int x, int y) {...}
이렇게 선언된 divide() 메소드를 호출할 때에는 반드시 2개의 int 값을 주어야 한다.
double result = divide(10,20);
<매개 변수의 개수를 모를 경우>
-몇 개의 매개 변수가 입력될지 알 수 없는 상황에서는 매개 변수를 배열 타입으로 선언하는 방법이 있다.
하지만 항상 배열로 매개 변수를 선언하면 번거롭기 때문에, 매개 변수 선언 시에
(변수타입... 변수명)으로 선언하면 메서드 호출 시 넘겨준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용된다.
다음은 코드 예시이다.
int sum1(int[] values) { }
sum1() 메소드를 호출할 때 배열을 넘겨줌으로써 배열의 항목 값들을 모두 전달할 수 있다. 배열의 항목 수는 호출할 때 결정된다.
int[] values = {1,2,3};
int result = sum1(values);
int result = sum1(new int[] {1,2,3,4,5});
또한 다음과 같이 생성도 가능하다..
int sum2(int ... values) { }
<리턴(return) 문>
-리턴값이 있는 메서드...
> 메서드 선언에 리턴 타입이 있는 메서드는 반드시 리턴문을 사용해서 리턴값을 지정해야 한다.
만약 리턴문이 없다면 컴파일 에러가 발생하고, 리턴문이 실행되면 메서드는 즉시 종료된다.
-리턴값이 없는 메서드(void)...
> 리턴값이 없는 메서드는 리턴 타입으로 void를 사용한다. 그런데 void로 선언된 메서드에서도
리턴문을 사용할 수 있다. 이것은 리턴값을 지정하는 것이 아니라 메서드 실행을 강제 종료시키는 역할을 한다.
<메서드 호출>
- 클래스 내부의 다른 메소드에서 호출할 경우에는
단순한 메소드 이름으로 호출하면 되지만, 클래스 외부에서 호출할 경우에는 우선 클래스로부터 객체를 생성한 뒤
참조변수를 이용해서 메서드를 호출해야 한다. 객체가 존재해야 메소드도 존재하기 때문이다.
<정리>
선언부 : 메소드 선언부는 리턴 타입, 메소드 이름, 매개 변수 선언 부분을 말한다.
void : 리턴값이 없는 메서드는 리턴 타입으로 void를 기술해야 한다.
매개 변수 : 메서드 호출 시 제공되는 매개값은 메소드 선언부의 매개 변수에 차례대로 대입되어 ,메소드 블록 실행 시 이용된다.
리턴문 : 메소드 선언부에 리턴타입이 있다면 리턴값을 지정하기 위해 리턴문이 반드시 있어야 한다.
리턴타입이 void라면 리턴문은 필요 없지만, 메서드 실행 종료를 위해 사용할 수도 있다.
호출 : 메서드를 실행하려면 '메소드 이름(매개값,...)' 형태로 호출해야 한다.
오버로딩 : 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것을 메소드 오버로딩이라고 한다.
메소드 오버로딩의 조건은 매개 변수 타입, 개수, 순서 중 하나가 달라야 한다는 점이다.
인스턴스 멤버와 정적 멤버
-인스턴스 멤버란 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드를 말하는데,
이들을 각각 인스턴스 필드, 인스턴스 메서드라고 부른다. 우리가 지금까지 작성한 모든 필드와 메서드는 인스턴스 멤버이다.
<정적 멤버와 static>
-정적(static)은 '고정된'이란 의미이다. 정적 멤버는 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는
필드와 메서드를 말한다. 이들을 각각 정적필드, 정적 메소드라고 부른다.
<정적 멤버 선언>
-정적 필드와 정적 메소드를 선언하려면 필드와 메소드 선언 시 static 키워드를 추가적으로 붙이면 된다.
-필드를 선언할 때는 인스턴스로 할 것인가, 정적으로 할 것인가의 판단 기준이 필요하다.
객체마다 모두 가지고 있어야 할 데이터라면 인스턴스 필드로 선언하고,
객체마다 가지고 있을 필요가 없는 공용 데이터라면 정적 필드로 선언하는 것이 좋다.
-메서드 역시 인스턴스 필드를 포함하고 있다면 인스턴스 메서드,
인스턴스 필드를 포함하고 있지 않다면 정적 메서드로 선언한다.
<싱글톤>
-가끔 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우가 있다. 단 하나만 생성된다고 해서 이 객체를 싱글톤 이라고 한다.
-싱글톤을 만들려면 클래스 외부에서 new연산자로 생성자를 호출할 수 없도록 막아야 한다. 생성자를 호출한 만큼
객체가 생성되기 때문이다. 생성자를 외부에서 호출할 수 없도록 하려면 생성자 앞에 private 접근 제한자를 붙혀주면 된다.
그리고 자신의 타입인 정적 필드를 하나 선언하고 자신의 객체를 생성해 초기화한다.
참고로 클래스 내부에서는 new연산자로 생성자 호출이 가능하다. 정적 필드도 private를 붙혀준다.
대신 외부에서 호출 가능한 정적 메서드인 getInstance()를 선언하고 정적 필드에서 참조하고있는 자신의 객체를 리턴해준다.
<정리>
인스턴스 멤버 : 객체를 생성한 후 사용할 수 있는 필드와 메서드를 말하는데, 이들을 각각 인스턴스 필드, 인스턴스 메서드라고 부른다.
정적 멤버 : 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
static : 정적 멤버를 선언할 때 사용하는 키워드이다.
싱글톤 : 단 하나만 생성된다고 해서 이 객체를 싱글톤 이라고 한다.
final 필드 : 초기값이 저장되면 이것이 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없는 필드를 말한다.final
상수 : 수학에서 사용되는 원주율 파이나 지구의 무게 및 둘레 같은 불변의 값을 저장하는 필드를 자바에서는 상수라고 한다.final static
패키지와 접근제한자
<패키지 선언>
-클래스를 작성할 때 해당 클래스가 어떤 패키지에 속할 것인지를 선언하는 것을 패키지 선언이라고 한다.
패키지는 클래스의 일부이다. 그 이유는 클래스만 따로 복사해서 다른 곳으로 이동하면 클래스를 사용할 수 없기 때문이다.
<접근 제한자>
-접근 제한자는 말 그대로 접근을 제한하기 위해 사용된다. 여기서 접근이란 클래스 및 인터페이스 그리고 이들이 가지고 있는 멤버 접근을 말한다.
<접근 제한자의 종류>
public : 단어 뜻 그대로 외부 클래스가 자유롭게 사용할 수 있도록 한다.
protected : 같은 패키지 또는 자식 클래스에서 사용할 수 있도록 한다.
private : 단어 뜻 그대로 개인적인 것이라 외부에서 사용될 수 없도록 한다.
위 세 가지 접근 제한자가 적용되지 않으면 default 접근 제한을 가진다.
default : 같은 패키지에 소속된 클래스에서만 사용할 수 있도록 한다.
public > protected > default > private 순으로 접근 제한이 강화된다.
<Getter,Setter>
-getter는 필드의 값을 직접 사용하게 되면 부적절한 경우도 있기 떄문에, 이런 경우에는 메소드로 필드값을 가공한 후 외부로 전달하면
되는데, 이런 메소드가 바로 Getter이다.
-setter는 매개값을 검증해서 유효한 값만 객체의 필드로 저장할 수 있게 만들어준다.
<접근제한자 범위 정리>
접근 제한 | 적용 대상 | 접근할 수 없는 클래스 |
public | 클래스,필드,생성자,메소드 | 없음 |
protected | 필드,생성자,메소드 | 자식 클래스가 아닌 다른 패키지에 소속된 클래스 |
default | 클래스,필드,생성자,메소드 | 다른 패키지에 소속된 클래스 |
private | 필드,생성자,메소드 | 모든 외부 클래스 |
'JAVA Study' 카테고리의 다른 글
[JAVA] 컬렉션 프레임워크 (0) | 2024.04.16 |
---|---|
[JAVA]예외 처리 (0) | 2024.04.11 |
[JAVA]중첩 클래스 (0) | 2024.04.11 |
[JAVA] 상속(Inheritance) (0) | 2024.04.04 |