클래스와 객체
클래스
: 객체를 정의해 놓은것. 객체의 설계도.
객체
: 실제로 존재하는 것. 사물들이 곧 객체이다.
프로그래밍에서의 객체
: 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻한다.
객체의 정의
: 실제로 존재하는 것
객체의 용도
: 객체가 가지고 있는 기능과 속성에 따라 다르다.
클래스 → 인스턴스화 → 인스턴스(객체)
객체의 구성요소
- 객체는 속성과 기능으로 이루어져 있다.
- 객체는 속성과 기능의 집합이며, 속성과 기능을 객체의 멤버(구성요소)라고 한다.
- 속성은 변수로, 기능은 method로 정의한다.
속성 : 크기, 길이, 높이, 색상, 채널.....
기능 : 켜기, 끄기, 볼륨올리기.....
인스턴스 생성방법
클래스명 참조변수명; // 객체를 다루기 위한 참조변수를 선언한다.
참조변수명 = new 클래스명(); // 객체를 생성한 후에 생성된 객체의 주소를 참조 변수에 저장한다.
Tv t;
t = new Tv();
Tv t = new Tv();
클래스 - 사용자 정의 타입
- 개발자가 새로운 타입을 정의할 수 있다.
- 서로 관련된 값을 묶어서 하나의 타입으로 정의한다.
시간, 시계
int hour; int minute; int second;
int hour1; int minute1; int second1;
int hour2; int minute2; int second2;
int hour3; int minute3; int second3;
int[] hour;
int[] minute;
int[] second;
class Time {
int hour;
int minute;
int second;
}
타입에 따른 변수의 종류(변수에 담길 수 있는 내용물에 따른 분류)
기본형 변수(8가지), 참조형 변수
선언위치에 따른 변수의 종류
- 변수를 선언하는 위치가 변수의 종류와 사용범위를 결정한다.
class Variables { // 클래스 영역
int iv; // 인스턴스 변수
static int cv; // 클래스 변수(static 변수, 공유변수)
void method() { // 메서드 영역
int lv = 0; // 지역변수
}
}
변수의 종류 | 선언 위치 | 생성 시기 |
클래스 변수 | 클래스 영역 | 클래스가 메모리에 올라갈 때 |
인스턴스 변수 | 클래스 영역 | 인스턴스가 생성될 때 |
지역 변수 | 메소드 영역 | 변수 선언문이 수행될 때 |
선언된 위치에 따른 변수의 종류
- 인스턴스 변수
- 클래스 변수
- 지역 변수
인스턴스 변수
- 각 인스턴스의 개별적인 저장공간을 가지고 있다.
- 인스턴스마다 다른 값을 저장할 수 있다.
- 인스턴스 생성 후에 "참조변수.인스턴스변수명" 으로 접근이 가능하다.
- 인스턴스를 생성할 때(new) 생성이 되고 참조변수가 없어졌을 때 가비지컬렉터에 의해 자동으로 제거된다.
클래스 변수
- 같은 클래스의 모든 인스턴스들이 공유하는 변수
- 인스턴스 생성없이 "클래스이름.클래스변수명으로 접근이 가능하다.
- 클래스가 로딩될 때 생성이 되고 프로그램이 종료될 때 없어진다.
지역변수
- 메서드 내에서 선언이 되며 메소드의 종료와 함께 소멸된다.
- 조건문, 반복문의 블럭{} 내에서 선언된 지역변수는 블럭을 벗어나면 소멸한다.
클래스 변수와 인스턴스 변수
인스턴스 변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각각 다른 값을 유지할 수 있지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로 항상 공통된 값을 갖는다.
class Card {
String kind; // 무늬 - 인스턴스 변수
int nunmber; // 숫자 - 인스턴스 변수
static int width = 140; // 폭 - 클래스 변수
static int height = 300; // 높이 - 클래스 변수
}
메서드(method)
작업을 수행하기 위한 명령문의 집합이다.
어떤 값을 입력받아서 처리하고 그 결과를 돌려준다. (argument와 return값이 있다.)
입력받는 값이 없을 수도 있고, 그 결과를 돌려주지 않을 수 도 있다. (void)
메소드를 만드는 이유, 장점
반복적인 코드를 줄이고 코드의 관리가 용이하다.
반복적으로 수행되는 여러문장들을 메소드로 작성한다.
하나의 메소드는 한 가지 기능만 수행하도록 작성하는 것이 좋다.
메소드를 정의하는 방법
메소드 정의는 클래스 영역에만 정의할 수 있다.
리턴타입 메소드이름(타입 변수명, 타입 변수명, ...) { // 선언부
메소드 호출시 수행되는 코드... // 구현부
}
int add(int a, int b) {
int result = a + b;
return result; // 호출한 곳으로 결과를 반환한다.
System.out.println("안녕하세요?");
}
void power() { // 반환값이 없는 경우 void를 사용한다.
power = !power; // 호출한 곳으로 돌려주는 값이 없다.
}
return
: 메소드가 정상적으로 종료되는 경우
- 메소드의 블럭{}의 끝에 도달했을 경우
- 메소드의 블럭{}을 실행하는 도중에 return문은 만났을 때
return문
현재 실행 중인 메소드를 종료하고 호출한 메소드로 되돌아간다.
1. 반환값이 없는 경우는 return문만 써주면 된다. (return;)
2. 반환값이 있는 경우는 return문 뒤에 반환값을 지정해주어야 한다. (return 반환값;)
int add(int a, int b) {
int result = a + b;
// 선언된 리턴타입과 실제 돌려주는 값의 타입이 같아야 한다.
return result;
}
// return문 사용시 주의할 점
int num = max(5, 10);
// 반환값이 있는 메소드는 모든 경우에 return문이 있어야 한다.
int max(int num1, int num2) {
if(num1 > num2) { // 5 > 10 거짓
return num1;
}
}
===>
int max(int num1, int num2) {
if(num1 > num2) {
return num1;
} else {
return num2;
}
}
// return 문의 개수는 최소화하는 것이 좋다.
===>
int max(int num1, int num2) {
int result = 0;
if(num1 > num2)result = num1;
else result = num2;
return result;
}
메소드의 호출
메소드의 호출방법
// 메소드에 선언된 매개변수가 없는 경우
참조변수.메소드이름();
// 메소드에 선언된 매개변수가 있는 경우
참조변수.메소드(값1, 값2, ...);
기본형 매개변수, 참조형 매개변수
- 기본형 매개변수 - 변수의 값을 읽기만 할 수 있다. (read only)
- 참조형 매개변수 - 변수의 값을 읽고 변경할 수 있다. (read & write)
클래스 메소드, 인스턴스 메소드
인스턴스 메소드
- 인스턴스 생성 후 "참조변수.메소드이름()"으로 호출한다.
- 인스턴스 변수나 인스턴스 메소드와 관련된 작업을 하는 메소드
- 메소드 내에서 인스턴스변수 사용이 가능하다.
클래스 메소드
- 객체 생성 없이 "클래스이름.메소드이름()"으로 호출한다.
- 인스턴스 변수나 인스턴스 메소드와 관련없는 작업을 하는 메소드
- 클래스메소드 내에서 인스턴스 변수를 사용
메소드 호출
같은 클래스의 멤버들간에는 객체생성이나 참조변수 없이 참조할 수 있다.
그러나 static멤버들은 인스턴스멤버들을 참조할 수 없다.
class CarClass {
void instanceMethod1() {} // instance method
static void staticMethod1() {} // static method
void instanceMethod2() { // instance method
instanceMethod1(); // instanceMethod1을 호출한다.
staticMethod1(); // staticMethod1을 호출한다.
}
static void staticMethod2() {
instanceMethod1(); // instanceMethod1을 호출한다. - 에러발생
staticMethod1(); // staticMethod1을 호출한다.
}
}
변수의 접근
class CarClass {
int iv; // instance 변수
static int cv; // static 변수
void instanceMethod() { // instance method
System.out.println(iv); // instance변수를 사용할 수 있다.
System.out.println(cv); // static변수를 사용할 수 있다.
}
static void staticMethod() { // static method
System.out.println(iv); // instance변수를 사용할 수 있다. - 에러발생
System.out.println(cv); // static변수를 사용할 수 있다
}
}
method overloading
하나의 클래스에 같은 이름의 메소드를 여러개 정의하는 것을 말한다.
메소드 오버로딩 → 간단히 오버로딩이라고 말한다.
오버로딩 조건
1. 메소드의 이름이 같아야 한다.
2. 매개변수의 개수 또는 타입이 달라야 한다.
(메소드 이름) AND ((매개변수 개수) OR (매개변수 타입))
메소드 이름 AND 매개변수 개수
메소드 이름 AND 매개변수 타입
매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.
(리턴타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.)
// 매개변수의 이름이 다른 것은 오버로딩이 아니다.
int add(int a, int b) {return a + b;}
int add(int x, int y) {return x + y;} // 오버로딩이 성립하지 않는다.
int add(int a, int b) {return a + b;}
long add(int a, int b) {return (long)(a + b);} // 리턴타입은 오버로딩의 성립조건이 아니다.
long add(int a, int b) {return a + b;}
long add(long a, int b) {return a + b;} // 매개변수의 타입이 다르므로 오버로딩이 성립한다.
// ex) OverloadingExam.java
int add(int a, int b) {return a + b;}
long add(long a, long b) {return a + b;}
int add(int[] a) {
int result = 0;
for(int i = 0; i < a.length; i++) {
result += a[i];
}
return result;
}
생성자(Constructor)
- 인스턴스가 생성될 때마다 호출되는 '인스턴스 초기화 메소드'이다.
- 인스턴스 변수의 초기화 또는 인스턴스 생성시 수행할 작업에 사용
- 모든 클래스에는 반드시 하나의 생성자가 있어야 한다.
생성자를 하나도 없이 프로그램을 만들면 컴파일시 JVM이 자동으로 class파일에 만들어 준다.
javac CardTest.java → CardTest.class(기본생성자가 포함된다.)
(인스턴스 초기화 → 인스턴스 변수에 적절할 값을 저장하는 것)
Card c = new Card();
1. 연산자 new에 의해서 메모리에 Card클래스의 인스턴스가 생성된다.
2. 생성자 Card()가 호출되어 수행된다.
3. 연산자 new의 결과로 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장된다.
생성자의 조건
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴 값이 없다. (void를 쓰지 않는다.)
- 생성자도 오버로딩이 가능하다.
클래스이름(타입 변수명, 타입 변수명, ...) {
// 인스턴스 생성될 때 수행되어야 하는 코드
// 주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Card {
Card() {
System.out.println("인스턴스가 생성됩니다.");
}
Card(String kind, int number) {
인스턴스 초기화 작업
}
}
기본 생성자(default constructor)
- 매개변수가 없는 생성자
- 클래스에 생성자가 하나도 없으면 컴파일러가 기본 생성자를 추가한다.
- 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다.
매개변수가 있는 생성자
- 생성자도 메서드처럼 매개변수를 선언하여 호출 시 값을 넘겨 받아서 인스턴스의 초기화 작업에 사용할 수 있다.
- 인스턴스마다 각기 다른 값으로 초기화하여야 하는 경우가 많기 때문에 매개변수를 사용한 초기화는 매우 유용하다.
생성자에서 다른 생성자 호출 - this
- 같은 클래스의 멤버들 간에 서로 호출할 수 있는 것처럼 생성자 간에도 서로 호출이 가능하다.
단, 아래의 두조건을 만족 시켜야 한다.
- 생성자의 이름으로 클래스 이름대신 this를 사용한다.
- 한 생성자에서 다른 생성자를 호출할 때는 생성자의 첫 문장에서만 가능하다.
this
- 인스턴스 자신을 가리키는 참조변수.
- 인스턴스의 주소가 저장되어 있다.
- 모든 인스턴스 메소드에 지역변수로 숨겨진 채 존재한다.
this(), this(매개변수)
- 생성자, 같은 클래스의 다른 생성자를 호출할 때 사용한다.
생성자를 이용한 인스턴스 복사
- 인스턴스간의 차이는 인스턴스변수의 값 뿐 나머지는 동일하다.
- 생성자에서 참조변수를 매개변수로 받아서 인스턴스변수들의 값을 복사한다.
- 똑같은 속성값을 갖는 독립적인 인스턴스가 하나 더 만들어 진다.
인스턴스를 생성할 때는 아래의 2가지 사항을 결정해야 한다.
클래스 : 어떤 클래스의 인스턴스를 생성할 것인가.
생성자 : 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가.
변수의 초기화
- 변수를 선언하고 처음으로 값을 저장하는 것.
- 가능하면 선언과 동시에 적절한 값으로 초기화하는 것이 바람직하다.
- 멤버변수(인스턴스 변수, 클래스 변수)와 배열은 각 타입의 기본값으로 자동 초기화되므로 초기화를 생략할 수 있다.
- 지역변수는 사용전에 꼭 초기화하여야 한다.
class InitTest {
int x; // 인스턴스 변수
int y = x; // 인스턴스 변수
void method() {
int i; // 지역 변수
int j = i; // 에러 발생(지역변수를 초기화하지 않았기 때문에)
}
}
int i = 10; // int형 변수 i를 선언하고 10으로 초기화 한다.
int j = 10; // int형 변수 j를 선언하고 10으로 초기화 한다.
int i, j; // 같은 타입의 변수는 comma(,)를 사용해서
int i = 10, j = 10; // 함께 선언하거나 초기화할 수 있다.
int i = 10, long j = 2; // 타입이 다른 변수는 함께 선언하거나
// 초기화할 수 없다.
멤버변수의 초기화 방법
// 1. 명시적 초기화
class Car {
int door = 4; // 기본형 변수의 초기화
Engine e = new Engine(); // 참조형 변수의 초기화
]
// 2. 생성자(constructor)
Car(String color, String gearType, int door) {
this.color = color;
gearType = gearType;
this.door = door;
}
// 3. 초기화 블럭(initialization block)
인스턴스 초기화 블럭 : {}
클래스 초기화 블럭 : static {}
초기화 블럭
- 클래스 초기화 블럭 : 클래스 변수의 복잡한 초기화에 사용되며, 클래스가 로딩될 때 실행된다.
- 인스턴스 초기화 블럭 : 생성자에서 공통적으로 수행되는 작업에 사용되며 인스턴스가 생성될 때마다 실행된다.(생성자보다 먼저 실행)
멤버변수의 초기화 시기와 순서
- 클래스변수의 초기화 시점 : 클래스가 처음 로딩될 때 단 한번만 초기화된다.
- 인스턴스변수의 초기화 시점 : 인스턴스가 생성될 때마다 각 인스턴스별로 초기화된다.
클래스 변수의 초기화 순서
기본값 → 명시적 초기화 → 클래스 초기화 블럭
인스턴스 변수의 초기화 순서
기본값 → 명시적 초기화 → 인스턴스 초기화 블럭 → 생성자
class InitTest {
static int cv = 1; // 명시적 초기화
int iv = 1; // 명시적 초기화
static {
cv = 2; // 클래스 초기화 블럭
}
{iv = 2;} // 인스턴스 초기화 블럭
InitTest() { // 생성자
iv = 3;
}
}
InitTest it = new InitTest();
'Language > Java' 카테고리의 다른 글
[Java] 이벤트 객체와 이벤트 소스 (0) | 2022.08.21 |
---|---|
[Java] JDK에서 제공하는 어댑터 클래스 (0) | 2022.08.21 |
[Java] 정리 (기초) (0) | 2022.08.20 |
[Java] 실습 (빙고 만들기) (0) | 2022.08.19 |
[Java] 정리 (다형성, 추상...) (0) | 2022.08.19 |