클래스와 객체를 이해할 때 생각하면 좋은 것은 붕어빵 틀(클래스)
이고, 붕어빵(객체)
가 붕어빵이다.
클래스
란 객체를 정의하는 설계도이고, 객체
란 클래스에서 만들어진 실체를 의미한다.
여기서 인스턴스
라는 단어도 등장하는데, 인스턴스
는 클래스와 객체의 관계를 의미한다.
'클래스로부터 객체를 선언하는 행위를 인스턴스화
한다' 라고 하고,
'A 클래스
에서 만들어진 B 객체
는 A 클래스
의 인스턴스
' 라고 한다.
클래스를 정의하는 방법은 아래와 같다.
/* 클래스 선언 */
class 클래스명 {
// 필드
// 생성자 함수
// 메서드
}
/* 클래스 생성 */
클래스명 객체명 = new 클래스명();
필드
생성자 함수
메서드
예제1
class Car {
String name;
String type;
// 생성자 함수를 작성하지 않았지만 default로
// Car() {} 가 작동한다.
public void printInfo() {
System.out.println("name is " + name);
System.out.println("type is " + type);
}
public void move() {
System.out.print("이동 !");
}
public void brake() {
System.out.print("정지 !");
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car();
car1.name = "Lambo";
car1.type = "Sports";
car1.printInfo(); // name is Lambo
// type is Sports
car1.move(); // 이동 !
car1.brake(); // 정지 !
}
}
예제2
class Car {
String name;
String type;
Car (String name, String type){
this.name = name;
this.type = type;
}
public void printInfo() {
System.out.println("name is " + name);
System.out.println("type is " + type);
}
public void move() {
System.out.print("이동 !");
}
public void brake() {
System.out.print("정지 !");
}
}
public class Main {
public static void main(String[] args) {
Car car1 = new Car("Lambo", "Sports");
car1.printInfo(); // name is Lambo
// type is Sports
car1.move(); // 이동 !
car1.brake(); // 정지 !
}
}
위 코드에서 this
가 나온다.
this
this.name
은 클래스 자신의 필드에 있는 name
을 의미한다.this()
오버로딩
이란 한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것을 의미한다.
오버로딩 규칙은 아래와 같다.
class 클래스명 () {
/* 생성자 함수의 오버로딩 */
클래스명 () {}
클래스명 (String name, String type) {}
/* 메서드의 오버로딩 */
메서드명 () {}
메서드명 (int num) {}
}
class Car {
String name;
String type;
Car(String name, String type) {
this.name = name;
this.type = type;
}
public void printInfo () {
System.out.println("name is " + name);
System.out.println("type is " + type);
}
public void printInfo (String date) {
this.printInfo();
System.out.println("date is " + date);
}
public void printInfo (int carNum) {
this.printInfo();
System.out.println("carNum is " + carNum);
}
public void printInfo (String date, int carNum) {
this.printInfo();
System.out.println("date is " + date);
System.out.println("carNum is " + carNum);
}
}
public class Main {
public static void main (String[] args) {
Car car = new Car("Lambo", "sports");
car.printInfo(); // name is Lambo
// type is sports
car.printInfo("2022"); // name is Lambo
// type is sports
// date is 2022
car.printInfo(1111); // name is Lambo
// type is sports
// carNum is 1111
car.printInfo("2022", 1111); // name is Lambo
// type is sports
// date is 2022
// carNum is 1111
}
}
접근 제어자를 알아보기 전에 먼저 패키지에 대해 알아보자.
패키지
란 클래스의 묶음이다.
같은 이름의 클래스라도 서로 다른 패키지에서 존재하는 것이 가능하다.
클래스가 파일이라면, 패키지는 폴더 혹은 디렉토리 정도로 생각하면 되겠다.
접근 제어자
란 클래스 자체, 클래스 내의 필드와 메서드의 접근에 제한을 두는 키워드이다.
클래스의 접근 제어자에 대한 내용은 나중에 알아보도록 하고, 클래스 내의 필드와 메서드의 접근에 대해서만 알아보자.
접근 제어자는 총 4가지가 존재한다.
public
protected
default
private
private -> default -> protected -> public
에서 오른쪽으로 갈수록 많은 범위의 접근을 허용한다.
클래스 자체에는 public 과 default 만 가능하다.
클래스 자체를 public 으로 설정할 경우 file.java 이름과 클래스명이 같아야 한다.
클래스 자체를 default 로 설정할 경우 file.java 이름과 클래스명이 달라도 되고, 같은 패키지 내에서 접근 가능하다.
static 키워드
는 필드와 메서드의 특성을 바꾸는 키워드이다.
static
이 적용된 필드나 메서드는 아래와 같은 특성을 가진다.
class Name{
/* 클래스 필드 : 클래스 자체에 귀속된다. */
static String staticName = "static";
/* 인스턴스 필드 : 각각의 인스턴스에 귀속된다. */
String name = "not static";
Name(){
}
Name(String name){
this.name = name;
}
/* 클래스 메서드 : 클래스 자체에 귀속된다. */
static void staticPrint() {
System.out.println("내 이름은 static 입니다.");
}
/* 인스턴스 메서드 : 각각의 인스턴스에 귀속된다. */
void print() {
System.out.println("내 이름은 static 이 아닙니다.");
}
}
public class Main() {
public static void main(String[] args) {
Name.staticPrint(); // 내 이름은 static 입니다.
/* 객체를 생성하지 않아도 호출 가능하다. */
System.out.println(Name.staticName); // static
/* 객체를 생성하지 않아도 호출 가능하고, 동시에 모든 객체들이 값을 똑같이 공유한다. */
Name name1 = new Name();
Name name2 = new Name("name");
System.out.println(name1.staticName); // static
System.out.println(name2.staticName); // static
name2.staticName = "static change";
System.out.println(Name.staticName); // static change
System.out.println(name1.staticName); // static change
System.out.println(name2.staticName); // static change
}
}
좀 더 자세한 기술적인 설명은 static 의 의미와 사용법 을 참고해보자.