상속, 추상화, 인터페이스 및 접근제한자의 상호작용 관계
강의 내용 복습 : 코리아IT 신촌점 강의 (2024-05-02,03 강의)
🔔 접근제한자
📌 접근제한자 개념
- 접근제한자는 객체 지향 프로그래밍에 있어서 캡슐화 및 데이터 보호에 있어 필수적입니다.
- 접근제한자는 public, private, protected로 구분되며 링크된 글에 상세 설명이 있습니다.
- public : 외부로부터의 자유로운 접근이 가능합니다.
- private : 동일 클래스 내부에서만 접근 가능합니다.
- protected : 동일 패키지 내부, 해당 클래스를 상속 받은 자식 클래스에서 접근 가능합니다.
- default : 동일 패키지 내부에서만 접근 가능합니다.
📌 접근제한자와의 상호작용
- 이들 접근제한자는 상속-추상화-인터페이스와 밀접한 관련이 있습니다.
- public : 인터페이스의 메서드는 보통 public으로 선언됩니다.
- private : 클래스의 내부 구현을 숨길 수 있기 때문에 견고하게 추상화 할 수 있습니다.
- protected : 자식 클래스에서 protected 멤버에 접근할 수 있습니다.
🔔 상속(Inheritance)
📌 상속 소개
- 상속은 하나의 클래스가 다른 클래스의 속성 또는 메서드를 사용할 수 있는 기능입니다.
- 그러므로 상속은 캡슐화 된 객체를 계층화하여 코드의 재사용성을 높입니다.
- 예를들면 Person 객체를 상속받는 Student, Actor, Employee 객체가 존재할 수 있습니다.
- 또는 Animal 객체를 상속받는 Dog, Cat, Tiger 객체가 존재할 수 있습니다.
- ex : create, update 등의 데이터베이스 코드를 반복하여 작성하지 않아도 됨
📌 상속 계층화
- 상속 관계의 객체는 상하 계층이 구분되어 있습니다.
- 상위 계층은 상위 클래스(Superclass) 또는 부모 클래스(Parent Class)라고 합니다.
- 하위 계층은 하위 클래스(Subclass) 또는 자식 클래스(Child Class)라고 합니다.
- 상위 클래스는 속성 또는 기능을 하위 클래스에 상속합니다.
- 하위 클래스는 속성 또는 기능을 상위 클래스로부터 상속 받습니다.
- 하위 클래스 정의 시 extends 키워드를 이용하여 상위 클래스를 상속시킵니다.
📌 상속 특징
🚩 오버라이딩/오버라이드(Overriding)
- 상위 클래스의 메서드 기능을 하위 클래스의 성격에 맞게 재정의 할 수 있습니다.
- 이때 명시적으로 @Override 어노테이션을 사용하는 것이 좋습니다.
- 아래는 오버라이딩에 대한 예시입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class bark {
public static void main(String[] args) {
class Animal {
public void bark() {
System.out.println("");
}
}
// 기본 생성자 생성
Animal animal = new Animal();
// Animal 객체의 bark 메서드 사용
animal.bark();
class Dog extends Animal {
@Override
public void bark() {
System.out.println("멍멍");
}
}
// 기본 생성자 생성
Dog dog = new Dog();
// Dog 객체의 bark 메서드 이용
dog.bark();
class Cat extends Animal {
@Override
public void bark() {
System.out.println("야옹");
}
}
// 기본 생성자 생성
Cat cat = new Cat();
// Cat 객체의 bark 메서드 이용
cat.bark();
}
}
🚩 super 키워드
- super 키워드를 이용하여 상위 클래스의 기능 또는 생성자를 호출할 수 있습니다.
- super 키워드에 대한 예시는 아래 상속 구현 란에 있습니다.
🚩 final 키워드
- final 키워드로 선언된 클래스는 상속될 수 없습니다.
- final 키워드로 선언된 메서드는 오버라이딩 될 수 없습니다.
- 즉, final 키워드로 선언된 클래스 또는 메서드는 변경될 수 없습니다.
🚩 단일 상속
- Java에서는 클래스의 단일 상속만을 허용합니다.
- 즉, 하위 클래스는 하나의 상위 클래스로부터만 메서드 등을 상속받을 수 있습니다.
- 대신 인터페이스를 이용하면 다중 상속과 유사한 기능을 구현할 수 있습니다.
📌 상속 구현
- 클래스 간의 상속 방법은 매우 간단하며 extends 키워드를 사용하면 됩니다.
- 아래는 상속 기능을 구현한 예시입니다.
🚩 Person 객체 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// 다양하게 응용할 Person 객체를 정의하였습니다.
public class Person {
// 핵심 요소는 private으로 선언하였습니다.
private String name;
private int age;
private String gender;
// 각 요소에 대한 getter/setter 메서드는 public으로 선언하였습니다.
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
🚩 Actor 객체 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Actor extends Person {
private String myMovie;
// 생성자를 정의하였습니다.
public Actor(String name, int age, String gender, String myMovie) {
super(name, age, gender);
this.setMyMovie(myMovie);
}
// myMovie에 대한 getter/setter 메서드입니다.
public String getMyMovie() {
return myMovie;
}
public void setMyMovie(String myMovie) {
this.myMovie = myMovie;
}
}
🚩 Employee 객체 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Employee extends Person {
public Employee(String name, int age, String gender, String company) {
super(name, age, gender);
this.setCompany(company);
}
private String company;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
}
🔔 추상화(Abstraction)
📌 추상화 소개
- 추상화는 단어 그대로 실제 세계의 복잡한 무언가를 단순화하는 과정입니다.
- 추상화는 프로그래밍에 필요한 기능 또는 데이터를 강조하고 세부 사항은 숨기는 과정입니다.
- 개발자는 추상화를 통해 코드의 복잡성을 관리하고 유지/보수를 용이하게 할 수 있습니다.
- 추상화는 완성되지 않은 설계도이기 때문에 하위 클래스에게 구현을 위임합니다.
- 추상화는 크게 데이터 추상화 및 프로세스 추상화로 구분할 수 있습니다.
- 참고로 추상 클래스/메서드에 대한 설명은 하단의 용어 정리 파트에 있습니다.
📌 데이터 추상화(data abstraction)
- 데이터 추상화는 전체 모델링 내용 중 일부만 사용자에게 제공하는 개념입니다.
- 데이터 추상화는 클래스 정의 과정에서 이뤄집니다.
- 데이터 추상화는 어떤 속성 또는 기능이 외부로 노출될지 결정하고 세부사항은 숨깁니다.
- 예를들면 자동차의 세부 구조를 다 공개하는 것이 아니라 일부 기능만 공개하는 것입니다.
- 예를들면 accelerate()이나 brake() 메서드만을 사용자에게 제공하는 방식입니다.
- 예를들면 Java에서 기본적으로 제공하는 List 인터페이스가 있습니다.
📌 프로세스 추상화(process abstraction)
- 프로세스 추상화는 복잡한 로직을 하나의 메서드 등으로 캡슐화하는 개념입니다.
- 예를들면 서버에 데이터를 요청하는 복잡한 쿼리를 하나의 메서드로 요약하는 것입니다.
- 예를들면 데이터베이스에서 정보를 추출하는 로직을 하나의 메서드로 요약하는 것입니다.
- 개발자는 해당 메서드 하나만을 가지고도 복잡하게 구현된 기능을 간단하게 이용할 수 있습니다.
- 예를들면 Java에서 기본적으로 제공하는 Scanner 클래스가 있습니다.
📌 추상화와 인터페이스의 관련성
- 말 그대로 추상적인 개념인 추상화는 예시와 같이 클래스 또는 인터페이스로 구현됩니다.
- 그중에서도 인터페이스는 클래스의 기능을 핵심 수단으로 사용합니다.
- 개발자는 인터페이스를 이용하여 특정 클래스가 담당할 특정 기능을 정의할 수 있습니다.
- 즉, 인터페이스의 모든 메서드는 추상 메서드이고 인터페이스에는 구체적인 로직이 없습니다.
- 단, 하나의 클래스가 인터페이스를 사용할 때는 모든 메서드를 구체적으로 구현해야 됩니다.
📌 추상화 구현 예시
- 추상화 구현의 예시를 들기 위해 상속, 추상화, 인터페이스 개념을 이용하였습니다.
- Car 클래스는 추상 클래스인 Vehicle의 기능을 상속 받습니다.
- Car 클래스는 Vehicle 클래스에 정의된 drive 메서드를 오버라이딩합니다.
- Drivable 인터페이스는 drive 기능 실행을 담당하는 역할을 합니다.
- Bicycle 클래스를 이용하여 Drivable 인터페이스를 구현(implements)하였습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public class AbstractionTest {
/* 추상 클래스 */
// 추상 클래스는 이를 상속받는 클래스에 구현을 요구합니다.
// Vehicle 추상 클래스를 정의하였습니다.
public abstract class Vehicle {
/* 추상 메서드 */
// 추상 메서드는 이를 포함하는 클래스를 상속받는 클래스에서의 구현을 요구합니다.
// drive 추상 메서드를 정의하였습니다.
// 메서드에 기능은 없는 상태입니다.
public abstract void drive();
// start 메서드를 정의하였습니다.
// '시동'이라는 문구를 출력합니다.
public void start() {
System.out.println("시동");
}
}
/* 추상 클래스 상속 */
// Vehicle 클래스를 상속시켰습니다.
public class Car extends Vehicle {
// drive 메서드 오버라이딩하였습니다.
// drive 메서드에 기능을 부여하였습니다.
// '운전'이라는 문구를 출력합니다.
@Override
public void drive() {
System.out.println("차량 운전");
}
}
/* 인터페이스 */
// Drivable 인터페이스를 정의하였습니다.
public interface Drivable {
// drive 메서드를 정의하였습니다.
// drive 메서드에 구현 내용은 없습니다.
// 객체 지향 프로그래밍의 다형성 원리를 따라 drive 메서드 중복 문제는 없습니다.
public void drive();
}
/* 인터페이스 구현 */
public class Bicycle implements Drivable {
@Override
public void drive() {
System.out.println("자전거 운전");
}
}
}
🔔 인터페이스(Interface)
📌 인터페이스 소개
- 추상화가 미완성 설계도라면, 인터페이스는 완성된 설계도이자 레시피입니다.
- 인터페이스는 메서드 및 상수 등을 포함할 수 있습니다.
- 여러 클래스에서는 동일한 인터페이스를 구현함으로써 프로그래밍을 일관되게 할 수 있습니다.
- Java에서는 다양한 인터페이스를 제공하고 개발자는 인터페이스를 구현할 수 있습니다.
- 해당 예시로는 컬렉션 관련 인터페이스인 List, Map, Set이 대표적입니다.
📌 인터페이스 효용성
- 인터페이스에 정의된 메서드에는 리턴 타입, 메서드명, 파라미터가 기술됩니다.
- 그리고 인터페이스를 구현(implements)하면 해당 메서드를 전부 구현해야 됩니다.
- 따라서 개발팀의 시니어가 인터페이스를 이용하여 특정 기능에 대한 틀을 구현할 수 있습니다.
- 주니어 개발자는 해당 인터페이스를 구현하여 메서드를 오버라이드 할 수 있습니다.
- 즉, 특정 프로그램의 기능을 통일시킬 수 있는 것이 인터페이스의 장점 중 하나입니다.
📌 인터페이스 특징
- 인터페이스에 정의되는 메서드는 기본적으로 추상 메서드입니다.
- 추상 메서드이기 때문에 실질적인 구현 내용은 숨겨진 상태입니다.
- 하나의 객체에서는 다수의 인터페이스를 구현할 수 있으며 이들은 콤마로 구분됩니다.
- 다양한 객체를 동일한 방식으로 처리할 수 있는 Java 다형성 원리의 장점입니다.
- 참고로 Java 8 이후부터는 인터페이스에 정적 또는 디폴트 메서드도 포함시킬 수 있습니다.
📌 인터페이스 생성 및 구현 예시
- 한국 남자 또는 한국 여자를 모델링하기 위한 코드를 작성하였습니다.
- Human 인터페이스에는 사람과 유관한 기능을 정의하였습니다.
- Man 인터페이스에는 남자와 유관한 기능을 정의하였습니다.
- Woman 인터페이스에는 여자와 유관한 기능을 정의하였습니다.
- KoreanMan 객체에는 Human 및 Man 인터페이스를 구현하였습니다.
- 참고로 하나의 인터페이스에서 다른 인터페이스로 확장할 때는 extends 키워드를 사용합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class InterfaceTest {
public interface Human {
// 정의된 메서드는 전부 추상 메서드입니다.
// 리턴 타입, 메서드명, 파라미터를 기술하였습니다.
// 간결함을 위해 abstract 키워드는 생략하였습니다.
public void eat(String food);
public void sleep(int sleepTime);
}
public interface Man {
// 간결함을 위해 abstract 키워드는 생략하였습니다.
public void serveMilitary(int servicePeriod);
}
public interface Woman {
// 간결함을 위해 abstract 키워드는 생략하였습니다.
public void bePregnant(int pregnancyPeriod);
}
public class KoreanMan implements Human, Man {
@Override
public void eat(String food) {
System.out.println(food + "을(를) 먹습니다.");
}
@Override
public void sleep(int sleepTime) {
System.out.println("잠을 " + sleepTime + "시간 잡니다.");
}
@Override
public void serveMilitary(int servicePeriod) {
System.out.println("군 복무 기간은 " + servicePeriod + "달 입니다.");
}
}
}
🔔 Java 용어 정리
📌 클래스 용어
🚩 Object 클래스(Object Class)
- Object 클래스는 모든 클래스들 중에서 최상위 클래스입니다.
- 즉, Java의 모든 클래스는 직간접적으로 Object 클래스를 상속받습니다.
- 따라서 Java에서는 Object 클래스에 정의된 메서드를 기본적으로 사용할 수 있습니다.
- 예시로는 toString, hashCode, equals 메서드가 있습니다.
🚩 엔터티 클래스(Entity Class)
- 엔터티 클래스는 객체의 목적인 실제 현실에 있는 무언가를 모델링하기 위한 것입니다.
- 정확히는 현실 세계에 있는 무언가의 속성(상태) 및 기능을 정의하는 클래스입니다.
- 예를들어 커피 판매와 관련된 속성(변수) 및 기능(메서드)을 정의할 수 있습니다.
- 정의되는 변수는 보통 private으로 선언되고 이를 getter/setter 메서드로 접근/설정합니다.
- 엔터티 클래스의 인스턴스에 저장되는 데이터는 데이터베이스의 엔터티와 연결됩니다.
- 즉, 엔터티 클래스는 데이터베이스의 테이블과 매핑되는 클래스를 지칭합니다.
🚩 실행 클래스(Execution Class)
- 실행 클래스는 애플리케이션에 진입하는 특정 로직을 포함합니다.
- 실행 클래스는 main 메서드를 포함하고 프로그램을 실제로 실행시킵니다.
- 실행 클래스에는 애플리케이션의 동작 원리가 구현되고 관리됩니다.
- 실행 클래스와 엔터티 클래스를 캡슐화하여 구분하면 프로그램을 유지/보수하기 좋습니다.
- 참고로 실행 클래스는 Application Entry Point라고도 표현됩니다.
🚩 추상 클래스(Abstract Class)
- 추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스입니다.
- 추상 클래스는 abstract 키워드로 생성됩니다.
- 추상 클래스는 추상 클래스를 상속받는 하위 클래스에게 구현을 위임합니다.
- 하위 클래스는 추상 클래스에서 정의된 추상 메서드를 반드시 구현시켜야 됩니다.
- 단, 추상 클래스에서 정의된 일반적인 멤버 메서드 등은 오버라이딩하지 않아도 됩니다.
- 추상 클래스는 상속을 위한 기반 클래스이기에 미완성 설계도라고 표현됩니다.
📌 메서드 용어
🚩 클래스/정적/스태틱 메서드(Static Method)
- 클래스 메서드는 static 키워드로 선언된 메서드이고 클래스의 모든 요소와 유관합니다.
- 클래스 메서드의 특징은 다른 객체에서 별도의 생성자 없이도 사용 가능하다는 것입니다.
- 클래스 메서드의 예시로는 main 메서드, Math.ramdom() 메서드가 있습니다.
🚩 멤버/인스턴스 메서드(Instance Method)
- 멤버 메서드는 객체의 기능을 정의하는 메서드이고 객체의 속성(상태)을 이용합니다.
- 멤버 메서드를 사용하려면 호출된 객체명을 입력하고 점 연산자로 호출해야 됩니다.
- 멤버 메서드의 선언 위치는 클래스 내부(Class Level)입니다.
🚩 생성자 메서드(Constructor)
- 생성자 메서드는 클래스의 인스턴스를 생성하기 위해 사용하는 메서드입니다.
- 생성자 메서드의 주된 역할은 객체의 인스턴스를 초기화하는 것입니다.
- 생성자 메서드의 이름은 클래스의 이름과 동일해야 됩니다.
- 생성자 메서드는 반환 타입이 없습니다.
- 생성자 메서드는 new 키워드와 함께 사용되고 new 키워드는 객체의 인스턴스를 초기화합니다.
🚩 추상 메서드(Abstract Method)
- 추상 메서드는 선언만 되어있고 구현되지 않은 메서드를 의미합니다.
- 추상 메서드는 abstract 키워드로 정의되고 보통 추상 클래스 또는 인터페이스에 선언됩니다.
- 추상 메서드의 장점은 반드시 구현되어야 한다는 조건을 부여할 수 있다는 것입니다.
- 추상 클래스 또는 인터페이스를 상속받는 클래스는 추상 메서드를 반드시 구현해야 됩니다.
- 위임하기 때문에 개발의 틀
- 그래서 추상 메서드를 이용하면 프로그램 개발의 틀을 잡을 수 있습니다.
📌 변수 용어
🚩 클래스/정적/스태틱 변수(Static Variable)
- 실무적 표현으로 클래스 변수의 선언 위치는 객체 내부 어느 곳이든 상관 없습니다.
- 클래스 변수란 static 키워드로 선언된 변수이며 클래스의 모든 요소와 유관합니다.
- 클래스 변수의 특징은 다른 객체에서 별도의 인스턴스 생성 없이도 사용 가능하다는 것입니다.
- 클래스 변수는 프로그램 실행 시 메모리에 할당됩니다.
- 클래스 변수의 예시로는 Math.PI가 있으며 이는 원주율 값을 표현하는 상수입니다.
🚩 멤버/인스턴스 변수(Instance Variable)
- 실무적 표현으로 멤버 변수의 선언 위치는 메서드의 외부(Class Level)입니다.
- 멤버 변수는 객체의 상태를 저장하는 변수를 의미하고 각 객체에 독립적으로 존재합니다.
- 멤버 변수는 각종 데이터 타입(기본, 참조, 사용자 정의 타입 등)으로 선언될 수 있습니다.
- 멤버 변수는 생성될 때마다 각각의 인스턴스에 고유하게 존재하며 속성을 뜻합니다.
- 멤버 변수는 객체 생성 시 메모리에 저장되고 객체 삭제 시 메모리에서 삭제됩니다.
- 멤버 변수에 접근하기 위해서는 this 키워드가 필요합니다.
- 멤버 변수는 private으로 선언되기도 하고 getter/setter 메서드로 활용되기도 합니다.
🚩 로컬 변수(Local Variable)
- 실무적 표현으로 로컬 변수의 선언 위치는 메서드의 내부(Method Level)입니다.
- 로컬 변수는 객체의 인스턴스를 저장하는 변수를 의미하고 각 메서드에 독립적으로 존재합니다.
- 로컬 변수는 메서드 호출 시 생성되고 메서드 종료 시 소멸됩니다.
- 각 변수 용어에 대한 예시는 아래와 같습니다.
📌 Java 용어 예시
- 아래는 엔터티/실행 클래스, 클래스/멤버 메서드, 클래스/멤버/로컬 변수에 대한 예시입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/* 엔터티 클래스 정의 */
public class BasicTerm {
static String gender; // 클래스 변수 정의
private String name; // 멤버 변수 정의
private int age; // 멤버 변수 정의
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void printInfo() { // 멤버 메서드 정의
System.out.println(name);
System.out.println(age);
System.out.println(gender);
}
/* 실행 클래스 정의 */
class ExeTest {
public static void main(String[] args) { // 클래스 메서드 정의
BasicTerm firstVariable = new BasicTerm(); // 로컬 변수 정의
// 생성자 메서드 = BasicTerm() 메서드
// 객체 초기화 = new 키워드
firstVariable.setName("이름"); // 로컬 변수를 통해 인스턴스에 값 할당
firstVariable.setAge(30); // 로컬 변수를 통해 인스턴스에 값 할당
firstVariable.gender = "남성"; // 클래스 변수에 값 할당
firstVariable.printInfo(); // 멤버 메서드 사용
/* 출력 내용 */
// 이름
// 30
// 남성
BasicTerm secondVariable = new BasicTerm(); // BasicTerm 객체 인스턴스 초기화
secondVariable.printInfo();
/* 출력 내용 */
// null
// 0
// 남성 // 클래스 변수로 선언됐기 때문에 BasicTerm 객체 인스턴스 초기화와 무관
}
}
}
📌 메모리 영역 용어
🚩 메서드 영역(Method Area) / 스태틱 영역(Static Area)
- 메서드 영역에는 클래스 정보 및 클래스 변수가 저장됩니다.
- 메서드 영역에 저장된 데이터는 모든 스레드에 의해 공유됩니다.
- 메서드 영역의 데이터는 프로그램이 시작될 때 할당되고 종료될 때 소멸됩니다.
- 클래스가 사용되지 않으면 가비지 컬렉션의 대상이 되고 소멸될 수 있습니다.
- 참고로 스레드(thread)는 실행 흐름이나 경로를 의미합니다.
🚩 힙 영역(Heap Area)
- 힙 영역에는 객체와 멤버 변수가 저장됩니다.
- 힙 영역에 저장된 데이터 역시 모든 스레드에 의해 공유됩니다.
- 힙 영역의 데이터는 프로그램이 실행되면 동적으로 할당되고 실행이 종료되면 소멸됩니다.
- 객체가 사용되지 않으면 가비지 컬렉션의 대상이 되고 소멸될 수 있습니다.
🚩 스택 영역(Stack Area)
- 스택 영역의 스택 프레임에는 로컬 변수가 저장됩니다.
- 스택 영역에는 하나의 스레드가 메서드를 호출할 때마다 스택 프레임이 생성됩니다.
- 스택 영역의 데이터는 메서드의 호출이 완료되는 동시에 소멸됩니다.
- 메서드 호출이 완료(종료)되면 해당 스택 프레임(frame)은 스택 영역에서 제거됩니다.
- 같은 원리로 스택 프레임이 제거될 때 로컬 변수도 소멸되는 것입니다.
📌 static 키워드
- 클래스 메서드/변수는 공유 메모리를 사용하기 때문에 모든 인스턴스에 접근 가능합니다.
- 예시로 main 메서드는 애플리케이션 실행의 진입점이므로 static으로 선언되어야 됩니다.
- 왜냐하면 인스턴스 생성 없이 바로 호출되어야 되기 때문입니다.
- static으로 변수와 메서드를 선언하면 사용하기 편리합니다.
- 하지만 static 선언을 절제하지 않으면 프로그램 유지/보수에 있어 문제가 발생될 수 있습니다.
- 왜냐하면 코드가 언제, 어디서, 어떻게 영향을 받는지 파악하기 어렵기 때문입니다.
- 게다가 static으로 변수 또는 메서드를 선언하면 오버라이딩 등으로 응용될 수 없습니다.
- static 키워드로 선언된 것은 특정 인스턴스에 속하지 않기 때문입니다.
📌 어노테이션(@; annotation)
- 어노테이션이란 Java에서 메타 데이터를 코드에 추가하는 데 사용됩니다.
- 즉, 어노테이션은 클래스, 메서드, 변수 등에 추가적인 정보를 제공합니다.
- 어노테이션을 이용하면 컴파일러에게 특정 처리를 지시할 수 있습니다.
- 예를들면 프로그램 런타임 중에 특정 동작을 이행할 수 있도록 합니다.
📌 데이터 전달 방식
🚩 콜바이밸류(Call by Value)
- 콜바이밸류란 메서드나 함수에 필드에 있는 데이터를 전달하는 방식입니다.
- 콜바이밸류란 값이 전달될 때 데이터의 복사본을 생성하여 전달하는 방식입니다.
- Java에서 기본 데이터 타입(int, double 등)의 데이터는 콜바이밸류 방식으로 전달 됩니다.
- 이때 Java에서 전달되는 데이터에 대한 메모리 주소는 알 수 없습니다.
- 즉, Java에서는 주소를 생성할 수는 있어도 주소를 변경할 수는 없습니다.
🚩 콜바이래퍼런스(Call by Reference)
- 콜바이래퍼런스란 메서드나 함수에 데이터의 주소를 인자로 전달하는 방식입니다.
- 콜바이래퍼런스로 데이터를 전달하면 데이터가 저장된 메모리 주소에 직접 접근 가능합니다.
- 그래서 함수 호출 결과가 원본 데이터에 직접적으로 반영됩니다.
- 콜바이래퍼런스 전달 방식은 C, C++ 언어 프로그래밍에서 가능합니다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.