Java 클래스와 객체

LIM JAEHO·2022년 6월 29일
0

Java 학습

목록 보기
10/19

클래스와 객체

클래스와 객체를 이해할 때 생각하면 좋은 것은 붕어빵 틀(클래스)이고, 붕어빵(객체) 가 붕어빵이다.
클래스란 객체를 정의하는 설계도이고, 객체란 클래스에서 만들어진 실체를 의미한다.

여기서 인스턴스 라는 단어도 등장하는데, 인스턴스 는 클래스와 객체의 관계를 의미한다.
'클래스로부터 객체를 선언하는 행위를 인스턴스화 한다' 라고 하고,
'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()
    클래스 자신의 생성자 함수를 호출한다.

클래스의 특성

오버로딩

오버로딩 이란 한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것을 의미한다.
오버로딩 규칙은 아래와 같다.

  • 메서드의 이름이 같아야 한다.
  • Parameter 의 개수 / 타입이 달라야 한다.
  • return type 이 달라도 parameter 가 같으면 안 된다.
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 키워드 는 필드와 메서드의 특성을 바꾸는 키워드이다.
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 의 의미와 사용법 을 참고해보자.

0개의 댓글