포스트

상속, 추상화, 인터페이스 및 접근제한자의 상호작용 관계

강의 내용 복습 : 코리아IT 신촌점 강의 (2024-05-02,03 강의)

  • Tool :
    Java Eclipse


🔔 접근제한자

📌 접근제한자 개념

  • 접근제한자는 객체 지향 프로그래밍에 있어서 캡슐화 및 데이터 보호에 있어 필수적입니다.
  • 접근제한자는 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 라이센스를 따릅니다.
<>