뭐라도 끄적이는 BLOG

Java Class 본문

Java/Java 기본

Java Class

Drawhale 2023. 7. 1. 23:30

객체지향

객체지향 프로그래밍(Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍의 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보여주는 절차적인 시각에서 벗어나 여러 개의 독립된 단위인 "객체"들의 모임으로 파악하고자 하는 것이다.

객체지향의 기본 개념은 실 세계의 모든 것은 객체간의 상호작용에 의해 이루어진다는 개념하에 모든 것을 객체로 정의하는 것이다. 객체지향의 개념을 적용하여SW 시스템을 기본 구성이 객체(Object)단위로 구성되며, 객체들이 서로 관계성을 가지는 시스템으로 구성된다.

객체지향의 특징

  • 캡슐화: 객체의 속성(data field)과 행위(methods)를 하나로 묶고 실제 구현 내용 일부를 외부에 감추어 은닉하여 외부 간섭과 오용으로부터 안전하게 보호하는 객체 지향 프로그래밍 개념
  • 정보은닉: 캡슐화를 통해 가능해지는 개념으로 외부로부터 정보를 은닉하는 기능. java에서는 private, default, protected, public의 접근 제어자로 구현하고 있다.
  • 상속성: 이미 정의된 객체(부모 클래스)의 속성과 메소드를 다른 객체(자식 클래스)가 물려받을 수 있는 기능
  • 추상화: 현상에 존재하는 객체의 주요특징을 추출하는 과정을 말한다. 즉, 두사람이 있다고 가정하면 두사람은 서로 다르지만 사람이라는 주요 특징을 하나 추출할 수 있다.
  • 다형성: 객체지향에서 다형성이란 여러 가지 형태를 가질 수 있는 능력을 의미한다. java에서는 한 타입의 참조변수로 여러 타입의 객체를 참조할 수 있도록함으로써 다형성을 프로그램적으로 구현하였다. 

클래스 정의하는 방법

클래스

java에서 클래스(class)란 객체를 정의하는 틀 또는 설계도와 같은 의미로 사용된다. 클래스는 객체의 상태를 나타내는 필드(field)와 객체의 행동을 나타내는 메소드(method)로 구성된다.

public class Animal{

}
public class Animal{
    int age; // field
    int getAge(){ // method
        return this.age;
    }
}

인스턴스

java에서 클래스를 사용하기 위해 해당 클래스 타입의 객체를 선언해야 한다. 클래스로부터 객체를 선언하는 과정을 클래스의 인스턴스화라고 한다. 또 이렇게 선언된 해당 클래스 타입의 객체를 인스턴스라고 한다. 즉, 인스턴스란 메모리에 할당된 객체를 의미한다.

접근 제어자

객체지향에서 정보은닉을 위해 접근 제어자(access modifier)라는 기능을 제공한다. 접근 제어자를 사용하면 클래스 외부에서 직접적인 접근을 허용하지 않는 멤버를 설정하여 정보은닉을 구체화할 수 있다.

접근 제어자 같은 클래스의 멤버 같은 패키지의 멤버 자식 클래스의 멤버 그외
public O O O O
default O O O X
protected O O X X
private O X X X

private

private 접근 제어자를 사용하여 선언된 클래스 멤버는 외부에 공개되지 않으며, 외부에서는 직접 접근할 수 없다. 즉, 자바 프로그램은 private 멤버에 직접 접근할 수 없으며, 해당 객체의 public 메소드를 통해서만 접근할 수 있다.

따라서 private 멤버는 public 인터페이스를 직접 구성하지 않고, 클래스 내부의 세부적인 동작을 구현하는 데 사용된다.

www.tcpschool.com/java/java_modifier_accessModifier

default

자바에서는 클래스 및 클래스 멤버의 접근 제어의 기본값으로 default 접근 제어를 별도로 명시하고 있다. default를 위한 접근 제어자는 따로 존재하지 않으며, 접근 제어자가 지정되지 않으면 자동적으로 default 접근 제어를 가지게 된다.

default 접근 제어를 가지는 멤버는 같은 클래스의 멤버와 같은 패키지에 속하는 멤버에서만 접근할 수 있다.

www.tcpschool.com/java/java_modifier_accessModifier

protected

자바 클래스는 private 멤버로 정보를 은닉하고, public 멤버로 사용자나 프로그램과의 인터페이스를 구축한다.

여기에 부모 클래스(parent class)와 관련된 접근 제어자가 하나 더 존재한다.

protected 멤버는 부모 클래스에 대해서는 public 멤버처럼 취급되며, 외부에서는 private 멤버처럼 취급된다.

 

클래스의 protected 멤버에 접근할 수 있는 영역은 다음과 같다.

  1. 이 멤버를 선언한 클래스의 멤버
  2. 이 멤버를 선언한 클래스가 속한 패키지의 멤버
  3. 이 멤버를 선언한 클래스를 상속받은 자식 클래스(child class)의 멤버

www.tcpschool.com/java/java_modifier_accessModifier

public

public 접근 제어자를 사용하여 선언된 클래스 멤버는 외부로 공개되며, 해당 객체를 사용하는 프로그램 어디에서나 직접 접근할 수 있다. 자바 프로그램은 public 메소드를 통해서만 해당 객체의 private 멤버에 접근할 수 있다.

따라서 public 메소드는 private 멤버와 프로그램 사이의 인터페이스(interface) 역할을 수행한다고 할 수 있다.

www.tcpschool.com/java/java_modifier_accessModifier

메소드 정의하는 방법

Java에서 메소드란 어떠한 특정 작업을 수행하기 위한 명령문의 집합이라 할 수 있습니다.

①접근제어자 ②반환타입 ③메소드이름(④매개변수목록) { // 선언부
    // ⑤구현부
}
  1. 접근 제어자 : 해당 메소드에 접근할 수 있는 범위를 명시합니다.
  2. 반환 타입(return type) : 메소드가 모든 작업을 마치고 반환하는 데이터의 타입을 명시합니다.
  3. 메소드 이름 : 메소드를 호출하기 위한 이름을 명시합니다.
  4. 매개변수 목록(parameters) : 메소드 호출 시에 전달되는 인수의 값을 저장할 변수들을 명시합니다.
  5. 구현부 : 메소드의 고유 기능을 수행하는 명령문의 집합입니다.

자바에서는 하나의 클래스에 같은 이름의 메소드를 둘 이상 정의할 수 없다. 하지만 메소드 오버로딩(overloading)을 이용하면, 같은 이름의 메소드를 중복하여 정의할 수 있다.

메소드 오버로딩이란 매개변수의 개수나 타입을 다르게 하여 같은 이름의 또 다른 메소드를 작성하는 것이다. 반환타입만 변경하지는 못한다.

생성자 정의하는 방법

클래스를 가지고 객체를 생성하면, 해당 객체는 메모리에 즉시 생성된다. 하지만 이렇게 생성된 객체는 모든 인스턴스 변수가 아직 초기화 되지 않은 상태이다. Java에서 클래스 변수와 인스턴스 변수는 별도로 초기화하지 않으면, 다음값으로 자동으로 초기화 된다.

변수의 타입 초기값
char '\u0000'
byte, short, int 0
long 0L
float 0.0F
double 0.0 or 0.0D
boolean false
배열, 인스턴스 등 null

사용자가 원하는 값으로 인스턴스 변수를 초기화하려면, 일반적인 초기화 방식으로는 초기화할 수 없다. 

생성자(constructor)

자바에서는 객체의 생성과 동시에 인스턴스 변수를 원하는 값으로 초기화할 수 있는 생성자(constructor)라는 메소드를 제공한다. 생성자의 이름은 해당 클래스의 이름과 같아야 한다.

이러한 생성자는 아래와 같은 특징이 있다.

  1. 생성자는 반환값이 없지만, 반환 타입을 void형으로 선언하지 않습니다.
  2. 생성자는 초기화를 위한 데이터를 인수로 전달받을 수 있습니다.
  3. 객체를 초기화하는 방법이 여러 개 존재할 경우에는 하나의 클래스가 여러 개의 생성자를 가질 수 있습니다. 즉, 생성자도 하나의 메소드이므로, 메소드 오버로딩이 가능하다는 의미입니다.

다음 예제는 Car 클래스를 선언하면서 여러 개의 생성자를 선언하는 예제이다.

Car(String modelName) {}
Car(String modelName, int modelYear) {}
Car(String modelName, int modelYear, String color) {}
Car(String modelName, int modelYear, String color, int maxSpeeds) {}

위와 같이 생성자 중에는 매개변수를 전달받아 인스턴스 변수를 초기화하는 생성자도 선언할 수 있다.

Car(String modelName, int modelYear, String color, int maxSpeeds) {
    this.modelName = modelName;
    this.modelYear = modelYear;
    this.color = color;
    this.maxSpeed = maxSpeed;
    this.currentSpeed = 0;
}

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

자바에서는 new 키워드를 사용하여 객체를 생성할 때 자동으로 생성자가 호출된다.

기본 생성자(default constructor)

자바의 모든 클래스에는 하나 이상의 생성자가 정의되어 있어야 한다. 하지만 특별히 생성자를 정의하지 않고도 인스턴스를 생성할 수 있다. 이것은 자바 컴파일러가 기본 생성자(default constructor)라는 것을 기본적으로 제공해 주기 때문이다.기본 생성자는 매개변수를 하나도 가지지 않으며, 아무런 명령어도 포함하고 있지 않다.

자바 컴파일러는 컴파일 시 클래스에 생성자가 하나도 정의되어 있지 않으면, 자동으로 다음과 같은 기본 생성자를 추가한다. 기본 생성자는 어떠한 매개변수도 전달받지 않으며, 기본적으로 아무런 동작도 하지 않습니다.

만약 매개변수를 가지는 생성자를 하나라도 정의했다면, 기본 생성자는 자동으로 추가되지 않는다. 따라서 매개변수를 가지는 생성자를 하나 이상 정의한 후 기본 생성자를 호출하면, 오류가 발생한다.

this 키워드 이해하기

this 참조 변수

this 참조 변수는 인스턴스가 바로 자기 자신을 참조하는 데 사용하는 변수이다. 이러한 this 참조 변수는 해당 인스턴스의 주소를 가리키고 있다.

class Car {
    private String modelName;
    private int modelYear;
    private String color;
    private int maxSpeed;
    private int currentSpeed;
 
    Car(String modelName, int modelYear, String color, int maxSpeed) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.color = color;
        this.maxSpeed = maxSpeed;
        this.currentSpeed = 0;
    }
}

위의 예제처럼 생성자의 매개변수 이름과 인스턴스 변수의 이름이 같을 경우에는 인스턴스 변수 앞에 this 키워드를 붙여 구분해만 한다. 이렇게 자바에서는 this 참조 변수를 사용하여 인스턴스 변수에 접근할 수 있다.

이러한 this 참조 변수를 사용할 수 있는 영역은 인스턴스 메소드뿐이며, 클래스 메소드에서는 사용할 수 없다. 모든 인스턴스 메소드에는 this 참조 변수가 숨겨진 지역 변수로 존재하고 있다.

this() 메소드

this() 메소드는 생성자 내부에서만 사용할 수 있으며, 같은 클래스의 다른 생성자를 호출할 때 사용한다. this() 메소드에 인수를 전달하면, 생성자 중에서 메소드 시그니처가 일치하는 다른 생성자를 찾아 호출해 준다.

메소드 시그니처(method signature)란 메소드의 이름과 메소드의 원형에 명시되는 매개변수 리스트를 말한다.
class Car {
    private String modelName;
    private int modelYear;
    private String color;
    private int maxSpeed;
    private int currentSpeed;
 
    Car(String modelName, int modelYear, String color, int maxSpeed) {
        this.modelName = modelName;
        this.modelYear = modelYear;
        this.color = color;
        this.maxSpeed = maxSpeed;
        this.currentSpeed = 0;
    }
 
    Car() {
        this("소나타", 2012, "검정색", 160); // 다른 생성자를 호출함.
    }
 
    public String getModel() {
        return this.modelYear + "년식 " + this.modelName + " " + this.color;
    }
}
 
public class Method05 {
    public static void main(String[] args) {
        Car tcpCar = new Car(); System.out.println(tcpCar.getModel());
    }
}

위의 예제에서 매개변수를 가지는 첫 번째 생성자는 this 참조 변수를 사용하여 인스턴스 변수에 접근하고 있다. 또한, 매개변수를 가지지 않는 두 번째 생성자는 내부에서 this() 메소드를 이용하여 첫 번째 생성자를 호출한다. 이렇게 내부적으로 다른 생성자를 호출하여 인스턴스 변수를 초기화할 수 있다.

super 키워드 이해하기

super 참조변수

super는 this와는 다르게 자식 클래스가 부모 클래스로부터 상속받은 멤버를 사용하려고 할 때 사용된다.

super() 메소드

super() 메소드는 this()메소드와 비슷하게 생성자를 호출하는 함수이다. 하지만 자기자신의 생성자가 아닌 부모 클래스의 생성자를 호출한다.

반응형

'Java > Java 기본' 카테고리의 다른 글

Java 패키지  (0) 2023.07.02
Java 상속(Inheritance)  (0) 2023.07.02
Java 제어문  (0) 2023.07.01
Java 연산자  (0) 2023.07.01
Java Variables와 Data Types  (0) 2023.06.30