[스터디할래 05] 클래스
이 글은 ‘백기선’ 개발자님과 함께하는 온라인 자바 스터디에 참여하여 준비/학습한 내용을 정리하는 글입니다.📚
- 5주차 : https://github.com/whiteship/live-study/issues/5
- 목표 : 자바의 Class에 대해 학습
정리는 ‘Java in a nutshell’를 기반으로 하였습니다.
클래스
클래스는 자바의 근본 구조 요소이다. 클래스 없이는 자바 프로그램을 작성할 수 없다.
Class
- 데이터 필드와 메서드를 가지고 있는 집합이다.
- 클래스는 새로운 reference type을 정의하는 것이다.
Object
- object는 클래스의 instance 이다.
- new키워드로 클래스를 초기화하여 생성한다.
클래스 정의하는 방법
keyword class class_name (extends) {
	// class members
}
- keyword에는 접근 제한자(public,protected,(default),private) 이외에도abstract, final, strictfp가 붙을 수 있다. (strictfp는 거의 사용되는 경우가 없어서 생략)
- abstract: 인스턴스화 될 수 없는 불완전환 클래스이다.- abstract메소드를 하나 이상 포함하면- abstract class로 정의해야 한다.
- final: 상속을 금지시킨다.- abstract과- final은 함께 사용할 수 없다.
필드와 메소드
클래스의 멤버({} 안에 있는 요소들)는 크게 4가지로 나뉜다.
- Class field
- Class method
- Instance field
- Instance method 위 4가지 중 클래스 멤버인지 인스턴스 멤버인지에 따라 메모리 영역이 달라지기 때문에 이 둘을 구분하는 것은 아주 중요하다.
- static키워드가 붙는 멤버는 클래스가 로딩되는 시점에 스태틱 영역 메모리에 올라간다. 즉, 인스턴스를 생성하지 않아도 사용할 수 있고, 인스턴스와 무관하게 하나의 고유 값을 공유한다.
- 한편, static키워드가 없는 멤버는 인스턴스 멤버로,new를 통해 인스턴스를 생성한 시점에 힙 영역의 메모리에 올라가게 된다.
객체 만드는 방법 (new 키워드 이해하기)
- 클래스의 객체는 Circle c = new Circle();과 같이new키워드로 생성한다.
- Circle()은 클래스 멤버 중 하나인 생성자이다.
- new키워드를 선언하면, 새 객체를 위한 메모리가 할당되고 생성자의 body가 호출된다.
- 모든 클래스는 적어도 하나의 생성자를 가져야만 한다. 별도로 정의하지 않으면, javac컴파일러가 몸체가 빈 기본 생성자를 생성한다.
생성자 정의하는 방법
생성자는 다음 조건을 만족해야 한다.
- 생성자의 이름은 클래스 이름과 동일해야 한다.
- return과- void를 선언하지 않는다.
- 생성자의 몸체는 객체를 초기화하는 것이다. this레퍼런스의 내용을 채우는 것이다.
this 키워드 이해하기
- 자바에서 메소드가 자신의 클래스에 속한 인스턴스 필드를 호출할 때에 자기 자신 객체를 가리키는 변수인 this를 통해 호출한다. 즉,this는 인스턴스 자기 자신을 가르키는 변수이다.
- 대게의 경우 불필요한 코드의 일부이므로 생략된다.
- this는 인스턴스를 가르키기 때문에 인스턴스 메소드에서만 사용될 수 있고, 클래스 메소드에서는- this키워드를 사용할 수 없다.
Optional 과제
int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.(int value, Node left, right를 가지고 있어야 합니다.)
public class Node {
	private int value;
	private Node left;
	private Node right;
	Node(int value) {
		this.value = value;
	}
	
	public int getValue() {
		return this.value;
	}
	public int setValue(int value) {
		return this.value = value;
	}
	public Node getLeft() {
		return this.left;
	}
	public void setLeft(Node left) {
		this.left = left;
	}
	public Node getRight() {
		return this.right;
	}
	public void setRight(Node right) {
		this.right = right;
	}
}
BinrayTree라는 클래스를 정의하고 주어진 노드를 기준으로 출력하는 bfs(Node node)와 dfs(Node node) 메소드를 구현하세요.(DFS는 왼쪽, 루트, 오른쪽 순으로 순회하세요.)
class BinaryTree {
	private Node root;
	BinaryTree(Node root) {
		this.root = root;
	}
	public void bfs() {
		Queue<Node> queue = new LinkedList<>();
		queue.add(root);
		while (!queue.isEmpty()) {
			Node currentNode = queue.poll();
			System.out.println(currentNode.getValue());
			if (Objects.nonNull(currentNode.getLeft())) {
				queue.add(currentNode.getLeft());
			}
			if (Objects.nonNull(currentNode.getRight())) {
				queue.add(currentNode.getRight());
			}
		}
	}
	public void dfs() {
		visitInorder(root);
	}
	public void visitInorder(Node node) {
		if (Objects.nonNull(node.getLeft())) {
			visitInorder(node.getLeft());
		}
		System.out.println(node.getValue());
		if (Objects.nonNull(node.getRight())) {
			visitInorder(node.getRight());
		}
	}
}