본문 바로가기
Study/Live-Study

[Live-Study] 클래스

by 검프 2021. 2. 18.

목표

자바의 Class에 대해 학습하세요.

학습할 것 (필수)

  • 클래스 정의하는 방법
  • 객체 만드는 방법 (new 키워드 이해하기)
  • 메소드 정의하는 방법
  • 생성자 정의하는 방법
  • this 키워드 이해하기

마감일시

2020년 12월 19일 토요일 오후 1시까지.

과제 (Optional)

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

늦게 시작한 감이있어 빠르게 하려하니 집중이 안되고, 정리도 대충하게 되는 것 같습니다. 이번주는 객체를 표현하기위한 수단인 Class에 관한 과제입니다.

 

클래스 정의하는 방법

클래스를 프로그래밍 적으로 봤을땐, 객체의 변수(variable), 메소드(method)의 집합이라 표현할 수 있습니다.

객체지향의 관점으로 봤을 때는 동적인 객체들의 상태와 행동을 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구입니다.

클래스를 정의하는 방법을 알기 앞서 클래스의 작성 규칙에 대해 알아보겠습니다.

클래스 작성 규칙

  • 하나 이상의 문자로 이루어져야 함.
  • 첫 번째 글자에는 숫자가 올 수 없음.
  • $,_ 외에는 특수문자 사용불가 (공백 포함)
  • 자바 Api 명령어, 키워드는 사용할 수 없음.(while, for, int 등 사용불가)
  • 이름은 대소문자로 구분함.(첫번째 글자 대문자 카멜케이스 적용 )

작성규칙을 지키지 않으면 컴파일단에서 error를 표출합니다.

클래스 구성 멤버

클래스의 구성 멤버로는 필드(field), 생성자(constructor), 메소드(method), 초기화 블럭(initializer)가 있습니다. 이 멤버들은 생략되거나 여러개가 작성될 수 있습니다.

필드 = 객체의 데이터(상태)가 저장되는 곳

객체 고유의 데이터, 상태 정보를 저장하는 곳입니다.

인스턴스 변수, 클래스 변수가 포함되며, 인스턴스 변수는 클래스 변수, static 메소드를 제외한 클래스 전체의 스코프를 가지고, 클래스 변수는 클래스 전체의 스코프를 가집니다.

생성자 = 객체 생성시 초기화 할때 사용

클래스의 이름으로 되어있고, 리턴타입이 없습니다.

생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없기 때문에 중요합니다.

사용자가 생성자를 작성하지 않으면 기본생성자(파라미터가 없는 생성자)가 자동적으로 생성됩니다.

메소드 = 객체의 행동을 수행하는 곳

메소드를 호출하게 되면 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행됩니다. 메소드는 필드를 읽고 수정하는 역할도 하지만, 다른 객체를 생성하여 다양한 기능을 수행하기도 합니다. 또한, 객체 간의 데이터 전달의 수단으로도 사용됩니다. 외부로부터 매개 값을 전달받을 수도 있고, 실행한 값을 리턴할 수도 있습니다.

객체지향의 관점으론, 수신된 메시지에 따른 적절한 행동을 수행하기 위한 수단입니다.

메시지는 '어떻게' 수행될지는 명시하지 않음, 단지 오퍼레이션을 통해 '무엇'이 실행되기를 바라는지만 명시

  • ex) 예매하라

어떤 메서드를 선택할 것인지는 전적으로 수신자의 결정에 좌우( 실행시간에 메서드를 선택함. 즉 다형성 )

초기화 블록(initializer)

  • 클래스 초기화 블록 - 클래스 변수 초기화에 쓰입니다..
  • 인스턴스 초기화 블록 - 인스턴스 변수 초기화에 쓰입니다.
  • class Class { // 클래스 String constructor; String instanceVar; // 인스턴스 변수 static String classVar; // 클래스 변수 static { // 클래스 초기화 블록 classVar = "Class Variable"; } { // 인스턴스 초기화 블록 instanceVar = "Instance Variable"; } Class() { // 생성자 constructor = "Constructor"; } void instanceMethod() { // 인스턴스 메서드 System.out.println(instanceVar); } static void classMethod() { // 클래스 메서드 System.out.println(classVar); } }

https://user-images.githubusercontent.com/48986787/106110350-eda18280-618d-11eb-9c7e-cc98146ffac5.png

클래스 정의하는법 ( 필드에 private를 안해뒀네요.. 착한사람한테만 보이는걸로 )

 

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

앞서 클래스가 동적인 객체들의 상태와 행동을 정적인 텍스트로 표현하기 위해 사용할 수 있는 추상화 도구라 했습니다. 그렇다면 텍스트로 표현은 했는데, 이걸로 어떻게 객체를 만들 수 있을까요?

이때 new 키워드가 필요합니다.

new 키워드

클래스로부터 객체를 만들때 사용합니다. 이때의 과정을 클래스의 인스턴스화라 정의합니다.

메모리의 힙 영역에 데이터를 저장할 영역을 할당 받은 후 해당 영역의 주소를 객체(인스턴스 변수)에게 반환하여 객체를 사용할 수 있도록 만들어 줍니다.

생성자가 없으면 객체를 생성할 수 없습니다.

클래스이름 변수명 = new 클래스이름(생성자의 전달인자);
Exam01 exam = new Exam01(15);
String something = "brand new!";
List<String> hello = new ArrayList<>();

 

메소드 정의하는 방법

클래스 내부의 메소드는 접근지정자, static (옵션) , 리턴타입, 메소드명, 파라미터(옵션)로 구성된 정의부메소드의 기능을 호출하는 호출부로 구성됩니다.

// 접**근지정자, static (옵션) , 리턴타입, 메소드명, 파라미터(옵션)**
public static int getAge(){ }
public String findById(Long id){ 호출부 }

메소드를 정의하는 법을 알아봤으니, 메소드를 정의하는 기법을 알아 보겠습니다

  • 메소드 오버로딩(Method Overloading)
  • 메소드 오버라이딩()Method OverrRiding)

위 두 기법은 자바의 객체지향의 특징인 다형성을 이용한 방법으로 코드의 변경과 확장을 용이하게 해줍니다.

메소드 오버로딩(Method Overloading)

  • 컴파일 타임에 동작합니다. → 컴파일 타임 다형성
  • 반환 타입과 이름은 같게, 파라미터의 유형과 갯수를 다르게 하여 정의하여 사용합니다.
  • Static 메소드를 오버로딩 할 수 있습니다.
public class Calculator {
    public static void main(String args[]) {
        Calculator calculator = new Calculator();
        System.out.println("Add two numbers: " + calculator.add(20, 21));
        System.out.println("Add two long numbers: " + calculator.add(41L, 45L));
    }

    int add(int n1, int n2) {
        return n1 + n2;
    }

    int add(Long n1, Long n2) {
        return (int) (n1 + n2);
    }
}

Output:

Add two numbers: 41
Add two long numbers: 63

메소드 오버라이딩(Method OverrRiding)

  • 런타임에 동작합니다. → 런타임 다형성
  • 상위 클래스가 가지고 있는 메서드를 하위 클래스가 재정의하여 사용합니다.
  • Static 메소드는 재정의 할 수 없습니다(Static 메서드는 컴파일 타임에 메모리에 할당되기 때문).
//메소드 오버라이딩 예제
public class Exam03 {
    public static void main(String[] args) {
        Car suv = new Suv(20);
        suv.go();
        System.out.println("distance = " + suv.getDistance());
    }

    interface Car {
        void go();

        void back();

        int getDistance();
    }

    static class Suv implements Car {
        private int distance;

        Suv(int distance) {
            this.distance = distance;
        }

        @Override
        public void go() {
            distance += 2;
        }

        @Override
        public void back() {
            distance -= 2;
        }

        @Override
        public int getDistance() {
            return distance;
        }
    }
}

 

생성자 정의하는 방법

생성자는 객체를 초기화하는데 사용되는 특수 메서드입니다. 클래스 인스때 호출되며, 객체 속성(상태)에 대한 초기 값을 설정하는데 사용할 수 있습니다. (오버로딩이 가능함)

생성자의 종류

  • 기본 생성자: 클래스 내부에 선언된 생성자가 없는 경우 객체 생성 시에 컴파일러가 자동으로 추가해주는 생성자
  • 묵시적 생성자: 파라미터 값을 가지지 않는 생성자
  • 명시적 생성자: 파라미터 값을 가지는 생성자이다.
package whiteship.week5;

// 생성자 예제
public class Exam04 {
    public static void main(String[] args) {
        Student student1 = new Student(25, "김부각");
        Student student2 = new Student(23);
        System.out.println(student1.toString());
        System.out.println(student2.toString());
    }

    static class Student {
        private int age;
        private String name;

                //묵시적 생성자
        public Student() {
            this.age = 10;
            this.name = "초등학생";
        }

                //명시적 생성자
        public Student(int age, String name) {
            this.age = age;
            this.name = name;
        }

        public Student(int age) {
            this.age = age;
            this.name = "";
        }

        @Override
        public String toString() {
            return "Student{" +
                    "age=" + age +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
}

output

Student{age=25, name='김부각'}
Student{age=23, name=''}

 

생성자의 특징

  • 클래스 이름과 동일한 이름을 가짐
  • 리턴 타입을 가지지 않음
  • 모든 클래스는 생성자가 반드시 존재하고, 한개 이상의 생성자를 가짐.
  • 클래스 내부에 생성자를 선언하지 않으면 컴파일러가 기본 생성자를 선언해 사용(객체의 상태의 초기 값을 설정할 수 없음) .
  • 명시적 생성자가 선언되있는 경우 기본생성자는 자동 생성되지 않는다.
  • 참고: https://www.w3schools.com/java/java_constructors.asp

this 키워드 이해하기

this 키워드

Java의 this는 클래스가 인스턴스화 되었을때 자기자신의 메모리 주소를 담고있는 키워드입니다.

즉, this는 인스턴스 자신을 가르키는 참조 변수입니다.

도트연산자(.)을 이용해 멤버변수와 메소드에 접근가능합니다.

또한, 클래스 내부의 멤버변수 이름과 메소드를 통해 넘어온 파라미터의 변수명이 동일한 경우 this키워드를 이용해 클래스 내부의 멤버변수 이름과 파라미터를 구분할 수 있습니다.

class Student {
    private String name;

    public Student(String name) {
        this.name = name;   // 클래스 멤버변수 name = 파라미터 name
    }

    public void changeName(String name){    // 클래스 멤버변수 name = 파라미터 name
        this.name = name;
    }
}

 

this()

같은 클래스의 다른 생성자를 호출 할때 사용합니다.

// this()
public class Exam04 {
    public static void main(String[] args) {
        Long id = 1L;
        Student student1 = new Student(id++);
        Student student2 = new Student(id++);
        System.out.println(student1.toString());
        System.out.println(student2.toString());
    }

    static class Student {
        private Long id;
        private String name;

        public Student(Long id, String name) {
            this.id = id;
            this.name = name;
        }

        public Student(Long id) {
            this(id, "노 네임");
        }

        @Override
        public String toString() {
            return "Student{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
}

output

Student{id=1, name='노 네임'}
Student{id=2, name='노 네임'}

this() 제약사항

  1. 생성자에서만 호출가능
  2. 제일 첫 문장에서 호출해야 함

 

과제 (Optional)

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

이진트리란?

각각의 노드가 최대 두 개의 자식 노드를 가지는 트리 자료구조로, 자식 노드를 각각 왼쪽 자식 노드오른쪽 자식 노드라 합니다.

int 값을 가지고 있는 이진 트리를 나타내는 Node 라는 클래스를 정의하세요.

public class Node {
    private int value;
    private Node left;
    private Node right;

    public Node(int value) {
        this.value = value;
        this.left = null;
        this.right =null;
    }

    public int getValue() {
        return 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;
    }
}

이진탐색트리의 조건

  1. 이진 탐색트리의 자식 노드 개수는 2개이하입니다.
  2. 모든 원소는 중복된 값을 가져서는 안됩니다.
  3. 왼쪽 서브트리에 존재하는 노드들의 값은 그 트리의 루트 값보다 반드시 작습니다.
  4. 오른쪽 서브트리에 존재하는 노드들의 값은 그 트리의 루트 값보다 반드시 큽니다.

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

Futher Works...

댓글