본문 바로가기
Backend/Backend 관련 학습 내용

Static과 JVM 모델 이해

by pjhcsol 2024. 11. 29.

객체지향의 전반과 특히 JVM의 경우 추후 디버깅이나 에러 해결에 직접적인 도움이 되기 때문에, 꼭 숙지하면 좋다

 

CH5. 배열과 클래스의 관계

* 동일한 구조와 이질적인 구조

* 개념: 배열은 동일한 데이터 형식을 가진 요소들로 구성될 수 있으며, 이를 동일한 구조라고 합니다. 반면에 서로 다른 데이터 형식이나 클래스의 요소들로 이루어진 배열은 이질적인 구조를 가집니다.

* 예시:

* // 동일한 구조 

* int[] numbers = {1, 2, 3, 4, 5}; 

* 

* // 이질적인 구조 

* Object[] objects = {newString("Hello"), new Integer(10), new Double(3.14)};

* 

* 

* 기본배열과 객체배열의 관계

* 개념: 기본배열은 기본 데이터 형식(int, double, char 등)의 요소로 이루어진 배열입니다. 반면에 객체배열은 객체의 참조를 요소로 가지는 배열입니다.

* 예시:

* // 기본배열 

* int[] numbers = {1, 2, 3, 4, 5}; 

* // 객체배열 

* String[] names = new String[5];

* 

* 

 

 

CH6. Static과 JVM 모델 이해

* Static과 메모리의 관계

* 개념: Static 멤버는 클래스가 로드될 때 메모리에 할당되어 프로그램의 수명 동안 유지됩니다.

* 예시:

* class Example { static int count = 0; }

* 

* 

* Static과 none static 멤버들의 접근 방법

* 개념: Static 멤버는 클래스 이름을 통해 접근할 수 있습니다.

* 예시:

* Example.staticMethod();

* 

* 

* JVM이 사용하는 메모리 영역

* 개념: JVM은 메모리를 여러 영역으로 나눠 관리합니다.

* 예시:

* class Example { static int count = 0; 

* // 메소드 영역(Method Area)에 할당됨 

* int number; // 힙 영역(Heap)에 할당됨 

* }

* 

* 

* 객체생성과 Static과의 관계

* 개념: 객체 생성과정에서 Static 멤버는 한 번만 메모리에 할당되고, 모든 인스턴스가 공유합니다.

* 예시:
Example ex1 = new Example(); Example ex2 = new Example(); System.out.println(Example.count); // 출력 결과: 0

* 

* 

* class, object, instance의 상호관계

* 개념: 클래스는 객체를 생성하기 위한 틀이며, 객체는 클래스를 기반으로 생성된 실체화된 인스턴스를 말합니다.

* Class(클래스): 클래스는 객체를 생성하기 위한 틀이며, 객체의 특성(속성)과 동작(메서드)을 정의합니다. 클래스는 객체의 설계도이며, 실제로 메모리에 올라가지 않습니다.

* Object(객체): 객체는 클래스를 기반으로 생성된 실체화된 인스턴스를 말합니다. 즉, 클래스의 인스턴스가 객체입니다. 객체는 메모리에 할당되어 실제로 프로그램에서 사용됩니다.

* Instance(인스턴스): 객체와 인스턴스는 동의어이며, 클래스로부터 생성된 구체적인 실체를 의미합니다. 따라서 클래스의 인스턴스를 생성하면 객체가 만들어지는 것이며, 이를 인스턴스라고 부릅니다.

* 예시에서 Car 클래스는 객체를 생성하기 위한 틀로서, **color**와 drive() 메서드를 정의합니다. 이 클래스로부터 생성된 **myCar**는 Car 클래스의 인스턴스이며, 객체입니다. 이렇게 생성된 인스턴스는 클래스의 특성과 동작을 가지고 있습니다.

* 예시

* // 클래스 정의 

* class Car { String color; void drive() { System.out.println("Driving..."); } } 

* // 객체 생성 

* Car myCar = new Car(); // 여기서 myCar는 Car 클래스의 인스턴스이자 객체입니다.

* 

* 

part4. 객체지향 프로그래밍 설계하기

CH1. 자바에서 상속이란

* 상속의 컨셉

* 상속은 객체지향 프로그래밍에서 중요한 개념으로, 한 클래스가 다른 클래스의 특성과 동작을 이어받는 것을 말합니다. 이는 부모 클래스(상위 클래스 또는 슈퍼 클래스)의 모든 기능을 자식 클래스(하위 클래스 또는 서브 클래스)가 물려받게 됨을 의미합니다. 자식 클래스는 부모 클래스의 멤버 변수와 메서드를 그대로 사용할 수 있으며, 필요에 따라 새로운 멤버 변수나 메서드를 추가하거나 부모 클래스의 메서드를 재정의할 수 있습니다.

* 예시:
// 부모 클래스 정의

* class Animal {

* void sound() {

* System.out.println("Animal makes a sound");

* }

* }

* 

* // 자식 클래스 정의

* class Dog extends Animal {

* void sound() {

* System.out.println("Dog barks");

* }

* }

* 

* // 자식 클래스의 객체 생성 및 사용

* public class Main {

* public static void main(String[] args) {

* Dog myDog = new Dog();

* myDog.sound(); // 출력 결과: "Dog barks"

* }

* }

* 
위 예시에서 Animal 클래스는 소리를 내는 기능을 가지고 있고, Dog 클래스는 Animal 클래스를 상속받아서 새로운 소리를 내는 기능을 추가하였습니다. 따라서 Dog 클래스는 Animal 클래스의 특성을 이어받아 사용하고, 필요에 따라 재정의하여 사용하고 있습니다.

* 수직적 구조와 수평적 구조의 설계 방법
개념:

* 수직적 구조: 상속을 통해 부모 클래스와 자식 클래스가 계층적으로 구성되는 설계 방법입니다. 부모 클래스에서 상위 개념을 정의하고, 자식 클래스에서는 보다 구체적인 개념을 정의합니다. 이렇게 함으로써 클래스 간의 상속 관계가 형성되며, 상위 클래스의 기능을 하위 클래스가 재사용할 수 있습니다. 계층적으로 설계가 됨으로서 새로운 요구사항에 따른 확장성이 보장되며 상속을 함으로써 중복 코드가 줄어드는 장점이 존재합니다.

* 수평적 구조: 클래스들이 동등한 수준에서 관련성을 가지며 서로 연관된 기능을 제공하는 설계 방법입니다. 클래스 간에 상속 관계가 없으며, 각 클래스는 독립적으로 기능을 구현합니다. 따라서 새로운 요구사항을 충족시키기 위해서는 중복 코드가 발생하고 확장성이 떨어집니다.

* 예시:

* 수직적 구조:
class Animal {

* void sound() {

* System.out.println("Animal makes a sound");

* }

* }

* 

* class Dog extends Animal {

* void sound() {

* System.out.println("Dog barks");

* }

* }

* 
위 예시에서 Dog 클래스는 Animal 클래스를 상속받아 상위 개념인 Animal 클래스의 기능을 이어받고 있습니다.

* 수평적 구조:
class Circle {

* void draw() {

* System.out.println("Draw a circle");

* }

* }

* 

* class Rectangle {

* void draw() {

* System.out.println("Draw a rectangle");

* }

* }

* 
위 예시에서 Circle 클래스와 Rectangle 클래스는 동등한 수준에서 각각 원과 사각형을 그리는 기능을 제공하고 있습니다.

* 클래스를 계층화 하여 사용할 때 장점
개념:

* 클래스를 계층화하여 사용하는 것은 객체지향 프로그래밍에서 중요한 개념 중 하나입니다. 클래스를 계층화함으로써 코드의 재사용성을 높일 수 있으며, 코드의 유지보수성과 확장성을 향상시킬 수 있습니다. 또한 상위 클래스의 기능을 하위 클래스에서 공통적으로 사용할 수 있어 중복을 최소화할 수 있습니다.

* 예시:

* 계층화된 클래스를 이용한 설계: 예시에서 Shape 클래스는 모든 도형의 공통적인 특성을 정의하고 있으며, Circle 클래스와 Rectangle 클래스는 각각 원과 사각형의 특성을 추가로 정의하고 있습니다.
class Shape {

* void draw() {

* System.out.println("Draw a shape");

* }

* }

* 

* class Circle extends Shape {

* void draw() {

* System.out.println("Draw a circle");

* }

* }

* 

* class Rectangle extends Shape {

* void draw() {

* System.out.println("Draw a rectangle");

* }

* }

* 

* 

* 메모리를 통한 상속(extends)의 이해
개념:

* 상속을 통한 메모리 구조는 부모 클래스와 자식 클래스가 서로 다른 메모리 영역을 가지고 있지만, 자식 클래스는 부모 클래스의 멤버 변수와 메서드를 상속받아 사용할 수 있습니다. 자식 클래스의 인스턴스를 생성할 때는 부모 클래스의 멤버 변수와 메서드가 먼저 메모리에 할당되고, 그 후에 자식 클래스의 멤버 변수와 메서드가 할당됩니다.

* 예시:

* 메모리를 통한 상속의 이해: 예시에서 Dog 클래스의 인스턴스를 생성할 때는 먼저 Animal 클래스의 멤버 변수인 **type**이 메모리에 할당되고, 그 후에 Dog 클래스의 멤버 변수인 **breed**가 할당됩니다.
class Animal {

* String type;

* 

* Animal() {

* System.out.println("Animal constructor");

* }

* }

* 

* class Dog extends Animal {

* String breed;

* 

* Dog() {

* System.out.println("Dog constructor");

* }

* }

* 

* public class Main {

* public static void main(String[] args) {

* Dog myDog = new Dog();

* }

* }

* 

* 상속관계에서 객체 생성 및 객체 초기화
개념:

* 상속관계에서 객체 생성 및 초기화는 부모 클래스와 자식 클래스 간의 생성자 호출 순서에 주의해야 합니다. 자식 클래스의 생성자가 호출될 때, 먼저 부모 클래스의 생성자가 호출되어 부모 클래스의 멤버 변수가 초기화되고, 이후에 자식 클래스의 멤버 변수가 초기화됩니다.

* 예시:

* 객체 생성 및 초기화의 순서:위 예시에서 Dog 클래스의 인스턴스를 생성할 때, 먼저 Animal 클래스의 생성자가 호출되어 type 멤버 변수가 초기화되고, 이후에 Dog 클래스의 생성자가 호출되어 breed 멤버 변수가 초기화됩니다.
class Animal {

* String type;

* 

* Animal() {

* this.type = "Unknown";

* System.out.println("Animal constructor");

* }

* }

* 

* class Dog extends Animal {

* String breed;

* 

* Dog() {

* this.breed = "Labrador";

* System.out.println("Dog constructor");

* }

* }

* 

* public class Main {

* public static void main(String[] args) {

* Dog myDog = new Dog();

* }

* }

*