Java:Class&Object

aiden·2023년 8월 28일

Java

목록 보기
6/30

Object-Oriented

Encapsulation

캡슐화를 통해 객체 내부 접근을 제한하고 보호한다. 다만 외부와의 상호작용을 위해 일부만 접근 가능하도록 한다.
클래스로 변수와 함수를 묶는데, 이 때 멤버 변수를 필드, 멤버 함수를 메소드라 부른다. 클래스를 통해 객체를 생성한다.

필드는 객체의 속성, 메소드는 행동/동작이라고 생각할 수 있다.

Inheritance

클래스는 상속 관계를 가지는데, 자식 클래스가 부모 클래스의 속성과 기능을 물려받고 확장하기 위함이다. 자바에서는 부모 클래스를 슈퍼 클래스, 자식 클래스를 서브 클래스라 부른다.
슈퍼 클래스와 서브 클래스는 다음과 같은 관계를 가진다.

Polymorphism

다형성은 동일한 이름의 다른 메소드를 여러 개 가질 수 있는 개념이다. 다형성에는 두 가지 종류가 있는데 오버라이딩(overriding)과 오버로딩(overloading)이다. 오버라이딩은 덮어쓰기, 오버로딩은 동명이인과 같이 생각할 수 있다.
오버라이딩은 슈퍼 클래스의 메소드를 서브 클래스에서 새로 구현하는 것이고 오버로딩은 메소드의 이름은 동일하지만 메소드의 매개변수 종류나 개수가 달라 다른 함수로 취급되는 것이다.

Class

클래스는 객체를 생성하기 위한 틀이라고 할 수 있다. 클래스를 통해 생성된 객체를 인스턴스라 부른다. 클래스는 필드와 메소드로 이루어지는데, 클래스로부터 객체 생성 시 객체는 이 클래스의 필드와 메소드를 가지고 있다.
클래스의 구성은 다음과 같다.

클래스 선언 시 접근 지정자, 클래스 선언, 클래스 이름, 필드, 메소드를 포함한다.

접근 지정자는 해당 클래스의 접근 가능 범위를 어떻게 지정할 지를 나타내며, 클래스의 이름은 대문자로 시작한다. 필드는 클래스 내의 변수, 메소드는 클래스 내의 함수라고 생각할 수 있다.
생성자는 클래스 이름과 동일한 이름의 메소드인데, 객체를 생성할 때 자동으로 호출된다.

객체 생성

객체를 생성할 때에는 new 연산자를 이용한다.

Circle c;
c = new Circle();
//또는
Circle c = new Circle();

객체에 대한 레퍼런스 변수를 선언한 뒤 객체를 생성한다. 선언과 동시에 객체를 생성할 수 있다. 이 때, 레퍼런스 변수의 선언으로는 객체가 생성되지 않는다. 클래스의 객체에 대한 레퍼런스를 저장하는 변수만을 생성한 것이기 때문이다. 객체 생성 전에는 null로 초기화된다.

new 연산자를 통해 객체를 생성하면 Circle 타입 크기만큼의 메모리가 할당되고 클래스의 생성자가 실행된다.

객체 생성 시 생성자에 인자를 전달하여 필드를 초기화할 수 있다.

객체 멤버 접근

객체의 멤버에 접근할 때에는 레퍼런스 변수에 . 연산자를 붙인다. 필드와 메소드 모두에 동일하게 사용할 수 있다.

생성자

생성자는 클래스로부터 객체 생성 시 초기화를 위해 사용한다. 같은 클래스를 통해 생성한 객체라도 생성자에 어떤 값을 전달하느냐에 따라 다른 초기값을 가진 객체를 만들 수 있다.
객체를 생성하는 동시에 호출되며 한 번만 호출되는 메소드이다.

생성자의 이름은 클래스 이름과 동일해야 한다. 또한 같은 이름의 생성자를 여러 개 작성할 수 있다. 아 때, 매개변수의 개수와 종류가 달라야 하며 객체를 생성할 때 전달하는 인자에 따라 생성자가 호출된다. 생성자는 반환값이 없으므로 리턴 타입을 지정하면 안된다.

기본 생성자

기본 생성자는 작성하지 않아도 기본적으로 존재하며 매개 변수가 없는 생성자이다.

생성자를 따로 정의하지 않은 경우 객체 생성 시 자동으로 기본 생성자가 호출된다.
하지만 생성자를 작성한 경우 기본 생성자가 없어도 자동으로 삽입해주지 않는다. 따라서 생성자를 따로 작성했다면 인자 전달 없이 객체 생성 시 오류가 발생한다. 초기화 없이 객체를 생성하려면 기본 생성자도 작성해주어야 한다.

this

this는 자바에서 현재 실행 중인 객체 자신을 가리키는 레퍼런스이다. this는 변수 이름이 중복되는 경우 매개 변수와 필드를 구분하기 위해 사용될 수 있다.

또, 메소드에서 객체 자신의 레퍼런스를 리턴할 때 사용한다.

한 클래스로부터 여러 객체를 생성한 경우에도 this는 각각 자신이 속한 객체의 레퍼런스를 의미한다.

this()

this()는 클래스 내에서 생성자가 다른 생성자를 호출할 때 사용한다. 다음과 같이 활용한다.

public class Book {
    String title;
    String author;

    public Book(){
        this("", "");
    }

    public Book(String t){
        this(t, "");
    }
    public Book(String t, String a){
        this.title = t;
        this.author = a;
    }
}

❗this()는 생성자 내에서만 호출 가능하며 생성자의 첫 번째 문장에 와야 한다.

객체 배열

자바에서 객체 배열은 객체 레퍼런스를 원소로 갖는 배열이다. 객체 배열의 생성 코드는 다음과 같다.

배열에 대한 레퍼런스 변수를 선언하고, 레퍼런스 배열을 생성해 대입한다. 이 때, 레퍼런스에 대한 배열만 생성된 것이므로 각 배열 원소에 대해 객체를 생성해야 한다.

상황을 그림으로 살펴보면 다음과 같이 표현된다.

배열에 대한 레퍼런스 변수 선언, 레퍼런스 배열 생성, 각 원소에 객체 생성 세 단계를 거쳐야 객체 배열을 만들 수 있다.

Method

메소드는 클래스의 멤버 함수로 다음과 같은 구조를 가진다.

자바의 함수는 반드시 클래스 내에 작성되어야 한다.

Argument Passing

메소드 호출 시 기본 자료형의 경우 값에 의한 호출로 인자 전달이 이루어진다. 인자값이 매개변수에 복사되어 전달된다. 따라서 메소드 내에서 값이 변경되어도 메소드 외부에서 변수에 저장된 값은 변하지 않는다.

인자로 객체나 배열이 전달되는 경우 참조에 의한 호출이 발생한다. 객체나 배열 자체가 복사되는 것이 아니라 레퍼런스 값이 전달된다.
객체를 전달받은 메소드 내에서 필드값을 변경하는 경우, 객체의 필드 값이 아예 변경된다.

배열 또한 메소드 내에서의 변경이 적용된다.

Overloading

자바에서 하나의 클래스 내에 이름이 동일한 여러 개의 메소드를 둘 수 있다. 메소드 오버로딩은 두 조건을 만족해야 하는데, 두 메소드의 이름이 같고 매개변수의 타입이나 개수가 달라야 한다.

❗리턴타입이 다른 것은 포함되지 않는다. 반드시 매개변수가 달라야 한다.

오버로딩 된 메소드 호출 시 인자에 따라 메소드가 호출된다.

Access Specifier

자바 프로그램은 여러 개의 패키지로 구성되며, 패키지는 여러 클래스 파일로 이루어져 있다. 클래스와 멤버의 접근 가능 범위를 정하는 것이 접근 지정자이다. 접근 지정자에는 4종류가 존재한다.

클래스 접근 지정

클래스 접근 지정은 다른 클래스에서 해당 클래스를 사용할 수 있는지에 대한 제한이다. 클래스 접근 지정에는 두 가지 유형이 있다.

Public

public 클래스는 패키지에 상관없이 다른 클래스에서 import하여 사용하는 것이 허용된다. main 메소드를 포함하고 있는 클래스라면, public으로 선언해야 한다.

Default

접근 지정자를 따로 기재하지 않으면 default 접근지정으로 선언된다. default의 경우 같은 패키지 내의 클래스들이 사용할 수 있다.

멤버 접근 지정

멤버 접근 지정은 클래스 멤버에 대한 접근 지정을 말한다. 멤버 접근 지정에는 네 가지 유형이 있다.

Public

public으로 선언된 멤버는 패키지에 상관 없이 모든 클래스에서 접근 가능하다.

Protected

protected 멤버는 같은 패키지의 모든 클래스와 다른 패키지의 자식 클래스에 대해 접근이 허용된다.

Default

접근 지정자를 명시하지 않은 default 멤저의 경우, 같은 패키지 내의 모든 클래스에 대해 접근이 허용된다.

Private

private 멤버의 경우 클래스 내의 멤버들에게만 접근이 허용된다. 다른 패키지 혹은 다른 클래스에서 접근할 수 없도록 보호된다.
main 메소드가 포함된 클래스에서 private 멤버는 같은 클래스에 존재하므로 main 메소드에서도 접근 가능하다.

Static

클래스의 멤버는 static멤버와 non-static한 인스턴스 멤버로 나뉜다. static 멤버는 클래스를 통한 객체 생성 이전에 생성되어 사용할 수 있는 멤버이다. static이 아닌 일반적인 멤버의 경우, 객체를 생성하게 되면 그에 따라 함께 생성되고 이후의 시점부터 사용할 수 있다. 하지만 static 멤버는 각 객체의 멤버라기보다는, 클래스 당 하나 보유하며 객체들이 공동으로 사용 가능한 클래스의 멤버라고 생각할 수 있다. static 멤버는 main 함수가 실행되기도 전에 생성된다.

static 멤버는 다음과 같이 앞에 static 키워드를 붙임으로 만들 수 있다.

static int n;
static double func();

static 멤버의 접근 방법은 다른 멤버들과 동일하게 객체의 이름에 . 연산자를 붙여 접근할 수 있으며 또 다른 방법으로는 클래스 이름에 . 연산자를 붙이는 것이다.

static 멤버는 전역 변수/함수를 만들 때, 혹은 공유할 필요가 있는 멤버를 만들 때 사용할 수 있다.
객체를 생성하지 않고도 사용할 수 있기 때문에 public으로 선언하여 다른 모든 클래스에서 접근 가능한 전역 변수, 전역 함수로 사용할 수 있다.
또는 클래스 객체들이 공동으로 사용하는 변수 등으로 활용할 수 있다.

❗static 메소드는 static 멤버만 접근할 수 있음에 주의한다. 객체 생성 전에 이미 사용 가능해야 하므로 non-static 필드나 메소드를 사용할 수 없다.

❗static 메소드는 클래스의 모든 객체가 공동으로 사용하므로 this를 사용할 수 없다.

Final

Final Class

final 키워드가 붙은 클래스는 상속 불가하다.

Final Method

final 키워드가 붙은 메소드는 오버라이딩 불가하다.

Final Field

final 키워드가 붙은 필드는 상수가 되므로 값을 변경할 수 없다.
이 때, 필드를 public static void로 선언하게 되면 프로그램 전체에서 사용 가능한 상수가 된다.

profile
파인애플 좋아하세요?

0개의 댓글