공부방/JAVA

클래스와 이진트리 구현 - 백기선 자바라이브스터디

EVO. 2023. 8. 12. 01:21

클래스와 객체


클래스는 인스턴스 생성을 위한 청사진 또는 템플릿 역할을 합니다. 인스턴스가 보유하게 될 구조와 동작을 정의합니다.

인스턴스가 생성되면 해당 클래스에 정의된 데이터와 동작으로 초기화 됩니다. 클래스와 인스턴스 간의 이러한 관계는 코드 재사용성을 가능하게 하고 캡슐화, 상속, 다형성의 원칙을 촉진합니다. 

 

 

클래스 정의하는 방법


클래스의 구조

  • 멤버변수(member variable) : 멤버변수는 해당 클래스 객체의 속성이며, 두가지 형식이 있습니다
    • 클래스 변수: 클래스의 모든 인스턴스간에 공유되는 static 변수 입니다. 그렇기 때문에 heap영역이 아닌 data의 static영역에 할당되고 gc의 관리를 받지 않습니다. 
    • 인스턴스 변수: 각 인스턴스가 고유한 값 집합을 유지할 수 있도록 합니다. 이렇게 하면 인스턴스가 동일한 클래스에서 만들어진 경우에도 독립적인 동작과 상태를 가질 수 있습니다. heap영역에 할당되고 gc에 의해 관리됩니다.
public class Employee {
	public String name; // public 접근 지정자인 인스턴스 변수 name.
	private int salary ; // private 접근지정자로 선언한 인스턴스 변수 salary.
	public static String company; // company는 정적이므로 인스턴스 변수가 아니며, 보유하는 값은 클래스에 따라 다르지만 인스턴스가 아닙니다.
}
  • 초기화 블록(initializer) :  초기화 블록 내에서 조건문,반복문을 사용해 명시적 초기화에선 불가능한 초기화를 수행할 수 있습니다. 초기화블록은 위에서 아래순으로 지정된 순서로 실행됩니다.
    • 인스턴스 초기화 블록 : 인스턴스 변수 초기화에 쓰입니다. 생성자문은 인스턴스 초기화가 실행된 후에 실행됩니다. 
    • 클래스 초기화 블록 : 클래스 변수 초기화에 쓰입니다.
class Order{
	String name; // 인스턴스 변수
    static int money; // 클래스 변수
    
    static{			//클래스 초기화 블록
    	money = 1000;
     }
     
     {				// 인스턴스 초기화 블록
     	name = "Instance Variable";
     }
  • 메서드(method) : 메서드는 해당 객체의 행동을 나타내며, 보통 필드의 값을 조정하는데 쓰인다. 
    • 인스턴스 메서드 : 인스턴스 변수와 연관된 작업을 하는 메서드입니다. 인스턴스를 통해 호출할 수 있으므로 반드시 먼저 인스턴스를 생성해야 합니다.
    • 클래스 메서드 : 정적 메서드라고도 합니다. 일반적으로 인스턴스와 관계없는 메서드를 클래스 메서드로 정의합니다.
  • 생성자(constructor) : 생성자는 객체가 생성된 직후에 클래스의 객체를 초기화하는 데 사용되는 코드 블록입니다. 메서드와 달리 리턴 타입이 없으며, 클래스엔 최소 한 개 이상의 생성자가 존재합니다.
  • 접근제어자 : public, private, protected와 같은 접근제어자는 인스턴스 멤버에 대한 액세스를 제어하는 데 중요한 역할을 합니다. 중요한 데이터에 대한 액세스를 제한하고 개체와의 상호작용에 필요한 메서드만 노출하여 캡슐화를 적용하는데 도움이 됩니다. 
    • 인스턴스 변수는 기본적으로 키워드 "private"로 선언됩니다. 그러나 인스턴스 변수를 public 또는 protected로 만들 수 있습니다.
    • 이렇게 접근제어자를 선언하면 해당 객체를 사용하는 개발자들이 잘 모르고 접근하면 안될 변수를 접근하는것을 사전에 방지할 수 있습니다.

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


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

클래스에서 객체를 생성하려면 new 키워드를 생성자 중 하나와 함께 사용하면 됩니다.

public class Remocon{
	private int channel;
    private String chennelName;
    
    public Remocon(){}
    
    public void changeChannel(int channel){
    	this.channel = channel;
     }
   }
public class Main{
	public static void main(String[] args){
    	Remocon remocon1 = new Remocon();
        remocon1.changeChannel(100);
     }
  }

new 키워드는 해당 클래스에 대해 객체를 만들고 메모리에 할당합니다. 해당 메모리에 대한 참조값을 반환하여 remocon1인 참조변수에 집어넣습니다. 일반적으로 객체가 메모리에 할당되면 인스턴스라 부릅니다.

 


메서드 정의하는 방법

public      void    setX(int x)              //선언부
-----       -----   -----------
접근제어자  반환타입  메서드이름(매개변수 리스트)
{
	//구현부
}
  • 접근제어자 : 위에서 설명했듯이 해당 메서드에 접근할 수 있는 범위를 지정합니다(public,protected,private 등)
  • 반환 타입 : 메서드가 모든 작업을 수행한 뒤에 반환할 타입을 명시합니다
  • 메서드 이름 - 메서드명은 동사여야하고 lowerCamelCase를 따르며 뜻이 명확해야 합니다
  • 매개변수 리스트 : 메서드에서 사용할 매개변수들을 명시합니다
  • 메서드 시그니처 : 메서드이름(매개변수리스트)를 뜻하며 컴파일러는 메서드 시그니처를 보고 오버로딩을 구별합니다 매개변수 리스트의 순서도 동일해야 합니다

생성자 정의하는 방법

생성자는 객체를 초기화하는 데 사용되는 특수 메서드 입니다. 생성자는 클래스의 객체가 생성될 때 호출됩니다.

객체 멤버변수의 초기 값을 설정하는 데 사용할 수 있습니다.

 

public class Main {
  int x;  
  public Main() {
    x = 5; 
  }
  public Main(int y) {
    x = y;
  }
  public static void main(String[] args) {
    Main myObj = new Main(); 
  
  }
}

주의할 점

  • 생성자 이름은 클래스 이름과 일치해야 하며, 반환 유형을(ex: void) 가질 수 없습니다.
  • 생성자는 객체가 생성될 때만 호출됩니다
  • 모든 클래스에는 기본적으로 생성자가 있습니다. 클래스 생성자를 직접 생성하지 않으면 Java가 기본 생성자(인자값 없는것)을 생성합니다. 그러나 이 경우 객체 속성의 초기값을 설정할 수 없습니다.
  • 생성자(Constructor)란 Class를 통해 인스턴스를 생성시 호출되는 서브루틴을 말합니다.
  • 생성자는 메서드의 선언과 비슷하지만, 반환값을 가지고 있지 않기때문에 엄밀히 말하면 함수라고 할 수 없습니다.
  • 생성자를 통해 여러 필드를 초기화할 수 있습니다.
  • 생성자의 파라미터 갯수, 혹은 파라미터 타입이 다르다면 여러 생성자를 가질 수 있습니다.
  • 어떠한 생성자도 선언하지 않을 경우, 컴파일러가 자동적으로 어떠한 파라미터도 가지지 않는 디폴트 생성자를 만들어줍니다.
  • 컴파일러가 만들어주는 디폴트 생성자의 경우, 상위클래스(super class)의 no-argument 생성자를 호출하기 때문에, 상위 클래스의 no-argument 생성자를 확인하는 것이 좋습니다.
  • 만약 상위 클래스에서 no-argument 생성자가 존재하지않고, 하위 클래스는 컴파일러에 의해 디폴트 생성자가 생성되는 경우에는 컴파일러 에러가 발생합니다.
  • 어떤한 생성자라도 선언되어있다면, 컴파일러는 디폴트 생성자를 만들지 않습니다.

this 키워드 이해하기


Java에서 'this'는 현재 객체를 참조하는 참조 변수 또는 현재 객체 인스턴스를 참조하는 키워드라고 할 수 있습니다.현재 클래스 메서드 및 필드를 호출하거나 현재 클래스의 인스턴스를 매개변수로 전달하고, 로컬변수와 인스턴스 변수를 구분하는 데 사용할 수 있습니다. this 참조는 코드 가독성을 개선하고 이름 충돌을 줄일 수 있습니다.

 

public class ThisExample {
    int num = 10;
 
    public ThisExample()
    {
        System.out.println("Inside constructor");
    }
 
    public ThisExample(int num)
    {
        // 기본 생성자 호출
        this();
        this.num = num;
    }

}

this 용도

  1. this 키워드를 사용하여 현재 클래스 인스턴스 변수를 참조
  2. this()를 사용하여 현재 클래스 생성자 호출
  3. this 키워드를 사용하여 현재 클래스 인스턴스 반환 
  4. 메서드 매개변수로 this 키워드 사용
  5. this 키워드를 사용하여 현재 클래스 메서드 호출
  6. 생성자 호출에서 this 키워드를 인수로 사용
더보기
  1. this 키워드를 사용하여 현재 클래스 인스턴스 변수를 참조
class Test {
    int a;
    int b;
 
    // 매개변수화된 생성자
    Test(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

2. this()를 사용하여 현재 클래스 생성자 호출

class Test {
    int a;
    int b;
 
    // 기본생성자
    Test()
    {
        this(10, 20);
        System.out.println(
            "Inside  default constructor \n");
    }
    Test(int a, int b)
    {
        this.a = a;
        this.b = b;
        System.out.println(
            "Inside parameterized constructor");
    }

 3. this 키워드를 사용하여 현재 클래스 인스턴스 반환 

class Test {
    int a;
    int b;
 
    // Default constructor
    Test()
    {
        a = 10;
        b = 20;
    }
 
    // Method that returns current class instance
    Test get() { return this; }

 4. 메서드 매개변수로 this 키워드 사용

class Test {
    int a;
    int b;
 
    // Default constructor
    Test()
    {
        a = 10;
        b = 20;
    }
 
    // Method that receives 'this' keyword as parameter
    void display(Test obj)
    {
        System.out.println("a = " + obj.a
                           + "  b = " + obj.b);
    }
 
    // Method that returns current class instance
    void get() { display(this); }

 5. this 키워드를 사용하여 현재 클래스 메서드 호출

class Test {
 
    void display()
    {
        // calling function show()
        this.show();
 
        System.out.println("Inside display function");
    }
 
    void show()
    {
        System.out.println("Inside show function");
    }
 
    public static void main(String args[])
    {
        Test t1 = new Test();
        t1.display();
    }
}

6. 생성자 호출에서 this 키워드를 인수로 사용

class B {
    int x = 5;
 
    // Default Constructor that create an object of A
    // with passing this as an argument in the
    // constructor
    B() { A obj = new A(this); }

 

 

 코드 출처 : https://www.geeksforgeeks.org/this-reference-in-java/


과제


  • int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.
  • int value, Node left, right를 가지고 있어야 합니다.
  • BinrayTree라는 클래스를 정의하고 주어진 노드를 기준으로 출력하는 bfs(Node node)와 dfs(Node node) 메소드를 구현하세요.
  • DFS는 왼쪽, 루트, 오른쪽 순으로 순회하세요

메서드 추가

  • BinaryTree 클래스에 새 노드를 삽입하는 메서드 추가 

 

BinaryTree란

  • 이진트리는 각 노드가 최대 2개의 자식을 가질 수 있는 재귀적 자료구조
  • 이진트리의 일반적 유형은 이진 검색트리로, 모든 노드가 왼쪽 하위트리의 노드 값보다 크거나 같고 오른쪽 하위 트리의 노드 값보다 작거나 같은 값을 가짐
  •  

Node 클래스

https://gist.github.com/minsang-alt/6bccb1e27f6071d45bce9557d0ab1987

 

Node클래스

Node클래스. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

BinaryTree 클래스 

https://gist.github.com/minsang-alt/9fd8736ff36550c82f02e65018dc96fc

 

이진검색트리

이진검색트리. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

BinaryTreeTest

https://gist.github.com/minsang-alt/f7fd2863c667eed9d9ae93cbf2fbdddd

 

이진트리테스트

이진트리테스트. GitHub Gist: instantly share code, notes, and snippets.

gist.github.com

참고


Java 인스턴스: Java에서 인스턴스 변수란 무엇입니까? 구문 등 - 훌륭한 학습 (mygreatlearning.com)

https://www.baeldung.com/java-binary-tree

https://github.com/ByungJun25/study/tree/main/java/whiteship-study/5week#%EC%83%9D%EC%84%B1%EC%9E%90-%EC%84%A0%EC%96%B8