클래스
변수는 하나의 값과 하나의 타입만 저장할수 있으며, 배열은 여러개의 값과 하나의 타입만 저장할 수 있다.
여러개의 값과 여러개의 타입을 담기위해 클래스를 사용한다.
클래스 안에 선언된 변수와 메소드를 사용하고 싶다면 해당 클래스 타입으로 변수를 선언해야 한다.
클래스 선언
class 클래스명 {
멤버 변수(필드)
멤버 메소드
}
* 멤버 : 필드(변수), 메소드
객체화
객체를 만드는 작업, 추상적인 개념을 구체화시키는 작업이다.
클래스명 객체명 = new 생성자();
ex) MyClass mc = new MyClass();
mc라는 변수(참조변수)에 MyClass 클래스의 객체의 주소값을 담는다.
new 라는 키워드는 객체를 메모리에 올려준다. 이렇게 메모리에 올라간 객체를 인스턴스라고 말한다.
생성자
클래스명 뒤에 소괄호가 있는 형태이며, 메소드와 형태는 유사하지만 메소드라고 부르지 않는다.
생성자는 리턴이라는 기능이 존재하기 않기 때문이다. 생성자의 역할은 초기화이다.
기본 생성자
클래스명() {;}
클래스 선언시 자동으로 선언되며, 사용자가 직접 생성자를 선언하게 되면 선언한 생성자가 기본생성자로 된다.
따라서 기본 생성자와 직접 선언한 생성자를 동시에 사용하고 싶다면 오버로딩 하여 사용한다.
public class Flight {
// ex)
// 비행기 클래스 만들기(Flight)
// 필드(좌석수, 직항여부, 출발 국가, 도착 국가, 운행 회사, 항공편명(ex: KE628))
// 메소드("비행기가 출발하였습니다." 출력 메소드, "비행기가 도착하였습니다." 출력메소드)
// 메소드("비행기에 탑승합니다." 출력 메소드, "비행기에서 내립니다." 출력메소드)
// 공통적인 변수(필드)
int seats;
boolean isDirect;
String fromCountry;
String toCountry;
String company;
String flightNum;
Flight() {;} // 기본생성자
// 공통적인 기능(메소드)
void depart() {
System.out.println("비행기가 출발하였습니다.");
}
void arrive() {
System.out.println("비행기가 도착하였습니다.");
}
void getOffPlane() {
System.out.println("비행기에서 내립니다.");
}
void getOnPlane() {
System.out.println("비행기에 탑승합니다.");
}
}
}
public class ClassTest1 {
public static void main(String[] args) {
// ex)
// 비행기 클래스 만들기(Flight)
// 필드(좌석수, 직항여부, 출발 국가, 도착 국가, 운행 회사, 항공편명(ex: KE628))
// 메소드("비행기가 출발하였습니다." 출력 메소드, "비행기가 도착하였습니다." 출력메소드)
// 메소드("비행기에 탑승합니다." 출력 메소드, "비행기에서 내립니다." 출력메소드)
// 클래스명 객체명(참조변수) = new(연산자) 생성자;
Flight flight = new Flight();
System.out.println(flight.company); // null
System.out.println(flight.flightNum); // null
System.out.println(flight.fromCountry); // null
System.out.println(flight.toCountry); // null
System.out.println(flight.seats); // 0
System.out.println(flight.isDirect); // false
flight.getOnPlane(); // 비행기에 탑승합니다.
flight.depart(); // 비행기가 출발하였습니다.
flight.arrive(); // 비행기가 도착하였습니다.
flight.getOffPlane(); // 비행기에서 내립니다.
}
}
메소드 오버로딩(Overloading)
매개변수의 개수 또는 타입이 다르면 같은 이름의 메소드로 선언할 수 있다.
반환 타입은 오버로딩에 영향을 주지 않는다.
다형성은 같은 코드로 다른 기능을 하는 것이다.
class MyClass{
// 메소드 오버로딩
// 이름은 같지만 매개변수가 다른 메소드
public int plus(int x, int y){
return x+y;
}
public int plus(int x, int y, int z){
return x + y + z;
}
public String plus(String x, String y){
return x + y;
}
// public int plus(int i, int f){ // 변수명은 다르지만, 매개변수의 타입과 개수가 동일한 메소드를 정의 할 수 없다.
// return i+f;
//}
}
this
객체의 주소값을 this라는 변수에 담을 수 있으며, 자동으로 담기게 된다
일반적으로 생성자의 매개변수와 클래스의 필드의 이름이 중복될 경우 구분하기 위해 사용한다.
public class Car{
String name;
int number;
public Car(String name){
name = name; // 가깝게 선언된 변수를 우선 사용하기 때문에 'name=name'이라는 코드는 매개변수의 name의 값을 매개변수 name에 대입하라는 의미가 된다.
} // 즉, 필드는 바뀌지 않는다. 이런 경우 필드라는 것을 컴파일러와 JVM에게 알려주기 위해서 this키워드를 사용해야 한다.
public Car(String name){
this.name = name; // 앞의 this.name은 필드 name을 말하고 =(이퀄) 뒤의 name은 매개변수를 의미한다.
} // 즉 매개변수의 값을 필드에 대입하라는 의미가 된다.
}
this()
자기 자신의 생성자를 의미한다.
생성자 내부에서만 사용이 가능하며 최상단에 작성해야 한다.
public class Flight {
int seats;
boolean isDirect;
String fromCountry;
String toCountry;
String company;
String flightNum;
Flight() {;} // 기본생성자
Flight(int seats, boolean isDirect) {
this.seats = seats;
this.isDirect = isDirect;
}
Flight(int seats, boolean isDirect, String fromCountry, String toCountry, String company, String flightNum) {
this(seats, isDirect); // 자기 자신의 생성자를 호출함으로써 비슷한 코드가 중복되서 나오는 것을 방지할 수 있다.
this.fromCountry = fromCountry;
this.toCountry = toCountry;
this.company = company;
this.flightNum = flightNum;
}
}
변수의 scope와 static
public class VariableScopeExam {
int globalScope = 10;
public void scopeTest(int value){
int localScope = 20;
System.out.println(globalScope);
System.out.println(localScope);
System.out.println(value);
}
// main메소드에서 사용하기
// 같은 클래스 안에 있는데 globalScope 변수를 사용 할 수 없다.
// main은 static한 메소드이다. static한 메서드에서는 static 하지 않은 필드를 사용 할 수 없다.
public static void main(String[] args) {
System.out.println(globalScope); //오류
System.out.println(localScope); //오류
System.out.println(value); //오류
}
}
public class VariableScopeExam {
int globalScope = 10;
static int staticVal = 7; // static한 필드(필드 앞에 static 키워드를 붙힘)나, static한 메소드는 Class가 인스턴스화 되지 않아도 사용할 수 있다.
public void scopeTest(int value){
int localScope = 20;
}
public static void main(String[] args) { // main 메소드는 static 이라는 키워드로 메소드가 정의되어 있다. 이런 메서드를 static 한 메소드 라고 한다.
System.out.println(staticVal); // 사용가능
}
}
VariableScopeExam v1 = new VariableScopeExam();
VariableScopeExam v2 = new VariableScopeExam();
// globalScope같은 변수(필드)는 인스턴스가 생성될 때 생성되기 때문에 인스턴스 변수라고 한다.
v1.globalScope = 20;
v2.globalScope = 30;
System.out.println(v1.globalScope); // 20이 출력된다.
System.out.println(v2.globalScope); // 30이 출력된다.
// staticVal같은 static한 필드를 클래스 변수라고 한다.
v1.staticVal = 10;
v2.staticVal = 20;
// 클래스 변수는 레퍼런스.변수명 하고 사용하기 보다는 클래스명.변수명 으로 사용하는것이 더 바람직하다.
// VariableScopeExam.staticVal
System.out.println(v1.staticVal); // 20이 출력된다.
System.out.println(v2.staticVal); // 20이 출력된다. // static하게 선언된 변수는 값을 저장할 수 있는 공간이 하나만 생성된다. 그러므로, 인스턴스가 여러개 생성되어도 static한 변수는 하나다.
열거형(enum)
- 열거형은 JDK5에서 추가되었다.
- JDK5 이전에는 상수를 열거형 대신 사용하였다.
public class EnumExam {
// 상수를 이용하는 방법
public static final String MALE = "MALE";
public static final String FEMALE = "FEMALE";
public static void main(String[] args) {
String gender1;
gender1 = EnumExam.MALE;
gender1 = EnumExam.FEMALE;
}
}
* 상수를 사용했을 때의 문제점
- String으로 선언된 gender1 에는 MALE,FEMALE 둘 중 한가지 값을 갖기 원하는데, gender1의 type이 String 이기때문에 gender1 = "소년"; 이렇게 수행 되어도 전혀 문제가 되지 않는다.
- 실행할때 원했던 값인 MALE, FEMALE 이 아닌 다른 값이 들어오게 되므로 문제를 발생시킬 수 있다.
* 이런 문제를 발생시키지 않게 하기 위해서 열거형을 사용한다.
enum Gender{
MALE, FEMALE;
}
Gender gender2;
gender2 = Gender.MALE;
gender2 = Gender.FEMALE;
// Gender타입의 변수에는 MALE이나 FEMALE만 대입이 가능. 다른 값은 저장할 수가 없다.
// 특정 값만 가져야 한다면 열거형을 사용하는 것이 좋다.
'JAVA' 카테고리의 다른 글
| 인터페이스(Interface) (0) | 2022.11.16 |
|---|---|
| 상속(Inheritance) (0) | 2022.11.10 |
| 메소드 (0) | 2022.10.30 |
| 배열 (0) | 2022.10.23 |
| 제어문 (0) | 2022.10.19 |