ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 항해일지 - 5. 클래스
    공부일기/자바 스터디 2020. 12. 23. 20:45

    클래스란?

    '객체를 정의해놓은 것.' 클래스는 객체를 생성하는데 사용되며, 객체는 클래스에 정의된 대로 생성되기 때문에 '객체의 설계도 또는 틀'로도 설명할 수 있다.

    그렇다면 객체란 무엇일까? 객체의 사전적인 정의는 '실제로 존재하는 것' 이다. 흔히 붕어빵과 붕어빵 틀로 설명하곤 하는데, 붕어빵 틀이 클래스라면 붕어빵은 객체인 것이다. 

    설계도 하나로 여러 개의 동일한 제품을 만들어 낼 수 있듯이 클래스 하나의 정의로 여러개의 객체를 만들어낼 수 있다. 물론 다른 속성을 가진 제품들을 만들어 낼 수도 있다. 클래스의 구조를 살펴보며 클래스에 대해 좀 더 자세히 알아보자.

     

     

    • 클래스 정의하는 방법
      • 필드 : 클래스 객체의 상태 속성을 나타낸다. 멤버 변수라고 불리며 필드에서 초기화하는 것을 필드 초기화 혹은 명시적 초기화라고 부른다. 필드에서의 구성 요소는 인스턴스 변수와 클래스 변수가 있다.
        • 인스턴스 변수 : 인스턴스, 즉 객체가 생성될 때 갖는 변수이다. 각 객체마다 서로 독립적인 값을 가지게 되고 heap 영역에 할당된다. 그리고 garbage collector에 의해 관리된다.
        • 클래스 변수 : static 키워드를 통해 클래스 변수라는 것을 확인할 수 있다. 위에서 클래스가 설계도라고 예를 들었는데 이 설계도를 통해 만들어진 모든 제품들은 이 static 변수를 공유한다. 따라서 heap영역이 아니고 garbage collector의 관리를 받지 않는다. 또한 public 키워드까지 붙게되는 경우 전역 변수라고 볼 수 있다.
      • 메서드 : 해당 객체의 동작을 나타내고, 필드의 값을 조정하는 데 사용된다. 클래스(설계도)를 통해 만들어지는 객체(제품)들이 가지는 기능이라고 생각하면 된다. 마찬가지로 인스턴스 메서드와 클래스 메서드로 나눌 수 있다.
        • 인스턴스 메서드 : 인스턴스와 연관된 작업을 하는 메서드로 인스턴스를 통해 호출할 수 있기에 반드시 인스턴스 생성 후 만들어진 인스턴스를 통해 작동한다.
        • 클래스 메서드 : 정적 메서드라고 불리며 인스턴스 생성 없이 작동할 수 있는 메서드를 의미한다.
      • 생성자 : 객체지향에 대해 처음 알게 되고 이 생성자 개념이 정말 낯설었는데, 초기 값이라고 생각하면 될 것 같다. 인스턴스가 만들어질 때, 그 객체를 초기값들을 설정할 수 있는 구역이다.

     

    위에서 설명들을 참고로 실제로 클래스를 만들어보면 아래와 같은 구조를 지닌다.

    클래스에는 접근제어자라는 기능이 있는데, 클래스나 메서드, 변수 선언 시 부가적인 의미를 부여한다.

    • 접근제어자 : 멤버 또는 클래스에 사용되어 해당 멤버 또는 클래스를 외부에서 접근하지 못하도록 제한하는 역할.
      • private : 같은 클래스 내에서만 접근이 가능
      • default : 생략 가능하며, 같은 패키지 내에서만 접근이 가능하다.
      • protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능하다.
      • public : 접근 제한이 전혀 없다.
      • 접근 범위가 넓은 쪽에서 좁은 쪽의 순으로 public > protected> default > private 순으로 정렬한다.

     

    접근 제어자 같은 클래스 같은 패키지 자손 클래스  전체
    public O O O O
    protected O O O  
    default O O    
    private O      

     

     

    • 제어자
      • static : 변수, 메서드는 객체가 아닌 클래스에 속한다.
      • final : 클래스 앞에 붙게 되면 해당 클래스는 상속될 수 없고, 변수나 메서드 앞에 붙으면 변수의 수정이나 메서드의 오버라이딩이 불가능하다.
      • abstract : 클래스나 메서드 앞에 붙을 수 있다.
        클래스 앞에 붙게될 시 해당 클래스는 추상 클래스가 되어 객체 생성이 불가능하고, 해당 클래스를 상속받은 다른 클래스를 통해 객체 생성이 가능하다.
        메서드 앞에 붙는 경우 추상 클래스 내에서의 메서드에서만 가능하고, 선언만 하고 기능은 해당 클래스를 상속받은 클래스에서 구현해 작동한다. 

     

    제어자와 접근 제어자를 사용하는 이유는 외부로부터 데이터를 보호하고, 내부적으로만 사용되는 부분을 감추기 위해서이다.

     

    • 객체 만드는 방법 (new 키워드 이해하기)

    객체를 만드는 것은 설계도(클래스)를 가지고 제품을 만든다고 비유할 수 있다.

    실제 코드를 통해 나타내면 아래와 같다.

    package JavaStudy;
    
    public class Speaker {
        private int width = 30;
        private int height = 10;
        private boolean power;
        String constructor;
    
        Speaker() {}
    
        Speaker(int width, int height, boolean power) {
            setWidth(width);
            setHeight(height);
            setPower(power);
        }
    
        public int getWidth() {
            return width;
        }
    
        public int getHeight() {
            return height;
        }
    
        public boolean getPower() {
            return power;
        }
    
        public void setWidth(int width) {
            this.width = width;
        }
    
        public void setHeight(int height) {
            this.height = height;
        }
    
        public void setPower(boolean power) {
            this.power = power;
        }
    }
    
    package JavaStudy;
    
    public class Main {
        public static void main(String[] args) {
            Speaker speaker1 = new Speaker();
            Speaker speaker2 = new Speaker(10, 10, true);
    
            System.out.println("" + speaker1.getWidth() + ", " + speaker1.getHeight() + ", " + speaker1.getPower());
            System.out.println("" + speaker2.getWidth() + ", " + speaker2.getHeight() + ", " + speaker2.getPower());
        }
    }
    

     

    실행결과

    30, 10, false
    10, 10, true

    클래스에서 객체를 생성할 경우 위와 같이 new 키워드를 생성자 중 하나와 함께 사용하면 된다.

    위의 예제는 speaker1의 경우 기본 생성자를 통해 기본인스턴스 변수의 값을 지닌 speaker가 만들어지고, 10,10,true의 매개변수를 사용해 speaker2를 만든 후 각 값들을 출력하는 코드이다.

     

     

    메서드란? 

    기본적으로 수학의 함수와 유사하고 어떤 작업을 수행하는 일련의 문장들을 묶어 놓은 것이다. 어떤 값을 입력하거나, 해당 메서드를 실행하면 메서드에 적혀있는 문장대로 작업을 수행하고 결과를 반환한다. 메서드는 크게 두 부분, 선언부와 구현부로 이루어져있고 메서드를 정의한다는 것은 선언부와 구현부를 작성한다는 것을 뜻한다.

    public int getWidth() // 선언부
    {                     // -------- 
        return width;     // 구현부
    }                     // --------
    
    public int getHeight() { // 선언부
        return height;       // 구현부
    }
    
    public boolean getPower() {
        return power;
    }
    • 메서드 정의하는 방법

    메서드 각 부분의 구성을 살펴보면 다음과 같다.

    이미지 출처 : https://jeeneee.dev/java-live-study/week5-class/

    접근 제어자 혹은 제어자 : 해당 메서드에 접근할 수 있는 범위를 나타낸다. 위에서 설명한 부분.

    반환타입 : 메서드가 모든 작업을 수행한 뒤 반환할 타입을 나타낸다. void인 경우 반환없이 실행만 한다.

    메서드 이름 : 메서드명은 동사여야하고, loweCamelCase를 따른다.

    매개변수 리스트 : 메서드에서 사용할 매개변수들을 나타낸다.

    메서드 시그니처 : 컴파일러는 메서드 시그니처를 보고 오버로딩(한 클래스 내에 같은 이름의 메서드를 여러개 정의하는 것)을 구별한다.

     

     

    생성자란?

    생성자는 위에서 설명했듯이 인스턴스가 생성될 때 호출되는 일종의 '인스턴스 초기화 메서드'이다. 생성자는 생성자이지만 이해하기 쉽게 메서드에 비유했다. 메서드처럼 클래스 내에 선언되며, 구조도 메서드와 유사하지만 리턴값이 없다. 또한 클래스명과 동일한 이름을 가져야한다.

     

    • 생성자 정의하는 방법
    Speaker() {} // 기본 생성자, 매개변수가 없다.
    
    Speaker(int width, int height, boolean power) { // 매개변수가 있는 생성자. 
        setWidth(width);                            // 매개변수를 전달 받아 속성을 초기화한다.
        setHeight(height);
        setPower(power);
    }
    

     

    인스턴스는 반드시 연산자 new를 통해서 생성된다. 생성자가 인스턴스를 생성하는 것이 아님에 유의하자.

     

     

    • this 키워드 이해하기

    this는 객체 자신을 가리키는 참조변수이다. 또한 한 생성자에서 다른 생성자를 호출 할 때 첫 줄에서 호출함으로 써 생성자의 이름으로 클래스 이름 대신 this()를 사용할 수 있다.

     

    class Car {
        String color;
        String gearType;
        int door;
        
        Car(String color, String gearType, int door) {
            this.color = color;
            this.gearType = gearType;
            this.door = door;
        }
        
        Car() {
        	this("black", "auto", 4); // Car(String color, string gearType, int door)를 호출
        }
        
        Car(String color) {
        	this(color, "auto", 4); // Car(String color, string gearType, int door)를 호출
        }
    }

    두 번째 코드는 첫 번째 코드의 생성자 Car(String color, String gearType, int door)를 활용해 간략하게 나타낸 것이다. 만약 Car car = new Car(); 와 같이 인스턴스를 생성한 경우, 인스턴스 변수는 각 black, auto, 4로 초기화 된다.

    아무 매개변수 없이 인스턴스를 만들게 될 경우 기본적으로 black, auto, 4로 만들어 지게 되어 있는 코드이고, 세 번째 코드는 color를 매개변수로 삼아 입력되는 값을 가진 color를 가진 auto, 4개짜리 문을 가진 차를 만드는 코드이다.

     

     

     


    과제 (Optional)

    • int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.
    • int value, Node left, right를 가지고 있어야 합니다.
    public class Node {
    
        private int value;
        private Node left;
        private Node right;
    	
        public Node(int value) {
            this(value, null, null);
        }
    
        public Node(int value, Node left, Node right) {
            this.value = value;
            this.left = left;
            this.right = right;
        }
    
        public int getValue() {
            return value;
        }
    
        public void setValue(int value) {
            this.value = value;
        }
    
        public Node getLeft() {
            return left;
        }
    
        public void setLeft(Node left) {
            this.left = left;
        }
    
        public Node getRight() {
            return right;
        }
    
        public void setRight(Node right) {
            this.right = right;
        }	
    }

     

     

    • BinrayTree라는 클래스를 정의하고 주어진 노드를 기준으로 출력하는 bfs(Node node)와 dfs(Node node) 메소드를 구현하세요.

     

     

    • DFS는 왼쪽, 루트, 오른쪽 순으로 순회하세요.
Designed by Tistory.