[JAVA] 참조 자료형, 클래스와 객체

dejeong·2024년 9월 7일
0

JAVA

목록 보기
8/24
post-thumbnail

참조 자료형

참조 자료형은 번지를 통해 객체를 참조하는 방식으로 동작한다. 기본 자료형은 변수에 실제 값을 저장하지만, 참조 자료형은 메모리의 번지(주소)를 값으로 갖고, 이 번지를 통해 객체를 참조한다. 이로 인해 참조 자료형의 연산 시간은 기본 자료형보다 더 소요되며, 연산 효율도 더 낮다.

데이터 타입 분류

  • 기본 자료형: byte, char, short, int, long, float, double, boolean
  • 참조 자료형: Array, Enum, Class

기본 자료형의 변수는 스택(Stack) 영역에 실제 값 그대로 저장되지, 참조 자료형 변수는 메모리 번지(주소)를 저장하고, 이를 통해 힙(Heap) 영역에 있는 객체나 배열을 참조한다.

// [기본 타입 변수]
int count = 5;
double price = 10000;

// [참조 타입 변수]
String name = "Jo sung yeon";
String hobby = "조깅";

메모리 사용 영역

메모리 사용 영역은 변수의 선언 위치에 따라 달라지며, 크게 다음과 같이 구분된다.

  • 인스턴스 변수: 객체가 생성될 때마다 할당되며, 힙(Heap) 영역에 저장
  • 클래스 변수: static 키워드로 선언된 변수로, 프로그램이 시작될 때 메서드(Method) 영역에 저장
  • 지역 변수: 메서드 내에서 선언된 변수로, 스택(Stack) 영역에 저장되며 해당 메서드가 실행될 때만 존재
  • 매개 변수: 메서드의 파라미터로 전달된 값이며, 역시 스택 영역에 저장
// 저장되는 메모리 영역이 다르기 때문에 접근 방법도 다르다. 
// 다른 파일에 있는 Class명 접근도 가능하다.

public class Sample {
    // 클래스 변수 (전역 변수)
    static int value = 45;

    // 인스턴스 변수
    int value2 = 45;

    public static void main(String[] args) {
        // 지역 변수
        int localVariable = 10;

        // 클래스 변수 접근 : 클래스명.인덱스
        System.out.println(Sample.value);

        // 인스턴스 변수 접근 : 인스턴스 변수는 객체를 선언해야 접근이 가능하다.
        Sample sample = new Sample();
        System.out.println(sample.value2);
    }
}

클래스 변수는 클래스명으로 접근 가능하며, 인스턴스 변수는 객체를 생성한 후 접근해야 한다. 이와 같이 메모리 영역에 따라 변수의 접근 방식이 달라진다.

힙(Heap) 영역

  • Heap 영역은 객체나 배열이 생성되는 메모리 영역. 힙 영역에 생성된 객체나 배열은 스택 영역의 변수 또는 다른 객체에 의해 참조된다. 만약 참조하는 변수가 없다면 해당 객체는 의미가 없어지고, 이는 JVM의 가비지 컬렉터(GC)가 자동으로 제거한다.
  • 힙 메모리는 개발자가 조정할 수 있으며, 주로 메모리 관리를 위해 GC가 효율적으로 동작하도록 코드를 설계하는 것이 중요하다.

JVM 스택(Stack) 영역

  • Stack 영역은 LIFO(Last In, First Out) 방식으로 동작하며, 메소드 호출 시마다 작업 프레임이 스택에 추가되고, 메소드가 종료되면 해당 프레임이 제거된다.
  • 기본 자료형과 지역 변수, 메소드의 매개변수가 스택 영역에 저장된다. 참조 자료형의 경우, 힙 영역에 생성된 객체의 참조값이 스택에 할당된다.
int a = 10;  // 기본 자료형 - 스택에 값이 저장됨
String str = "hello";  // 참조 자료형 - 스택에 참조값이 저장되고, 실제 데이터는 힙에 저장됨

메서드(Method 또는 Static) 영역

  • Method 영역은 프로그램이 시작될 때 생성되며, JVM이 실행되는 동안 클래스 관련 정보가 저장되는 공간이다. 이 영역에는 클래스의 런타임 상수풀, 필드 정보, 메서드 정보 등이 저장되며, 모든 스레드가 공유하는 영역이다.
  • Java 8 이전에는 이 영역을 Permanent Generation이라고 불렀으나, 이후에는 Metaspace로 대체되었다.

메서드 영역은 프로그램의 시작과 함께 생성되며, 클래스가 로드될 때 그 클래스에 대한 정보들이 저장된다.

정리 :

  • 스택 영역: 지역 변수, 매개 변수
  • 힙 영역: 인스턴스 변수
  • 메서드 영역: 클래스 변수, 상수

메모리 공간의 효율적 사용과 GC에 의한 메모리 관리는 Java 프로그램 성능의 중요한 요소


참조 변수의 ==, != 연산

참조 타입 변수를 비교할 때 == 연산자는 두 객체가 동일한 메모리 주소를 참조하고 있는지 여부를 확인한다. 참조 변수의 값은 객체의 주소값이므로, 같은 객체를 참조하지 않는다면 == 연산자는 false를 반환하지만, 객체의 실제 값(내용)을 비교할 때는 equals() 메서드를 사용해야 한다.

public static void main(String[] args) {
        OutterClass outter = new OutterClass();
        OutterClass outter2 = new OutterClass();

        System.out.println(outter == outter2);

        String str1 = new String("문자1");
        String str2 = new String("문자1");
        System.out.println(str1 == str2); // false

        String str3 = "문자1";
        System.out.println(str1 == str3); // false

        String str4 = "문자1";
        System.out.println(str3 == str4); // true

        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str1.equals(str4)); // true

    }
  • 객체 비교 (==) outter1outter2는 각각 다른 객체이므로, == 연산자는 false를 반환한다. 이는 두 객체가 다른 메모리 주소를 참조하고 있기 때문이다.
  • new 키워드로 생성된 문자열 비교 str1str2new String("문자1")으로 생성된 서로 다른 객체이므로, == 연산자는 false를 반환한다. 이는 두 문자열이 동일한 값을 가지고 있더라도, 다른 메모리 주소를 참조하고 있음을 의미한다.
  • 리터럴 문자열 비교 str3str4"문자1" 리터럴로 생성되었다. 자바에서는 동일한 문자열 리터럴은 하나의 객체로 취급되어 String Constant Pool이라는 메모리 영역에 저장되기 때문에, str3 == str4true를 반환한다.
  • equals()를 이용한 값 비교 equals() 메서드는 두 객체의 실제 값을 비교한다. str1.equals(str2), str1.equals(str3), str1.equals(str4) 모두 true를 반환한다. 1, 2, 3 모두 힙 메모리 영역에 객체를 참조하고 있지만, 3처럼 리터럴로 선언된 문자열은 힙 메모리의 String Constant Pool에 저장된다. 이 때문에 동등성 비교(==)를 할 때 다른 객체로 인식될 수 있다.
    만약 str4를 "문자1"로 다시 선언하면, str3과 동일한 값을 참조하게 된다. 즉, 같은 리터럴 값이라면 같은 객체를 참조한다. 그러나 문자열 값을 비교할 때는 주소값이 아닌 문자열 자체의 값을 비교하기 위해 equals() 메서드를 사용하는 것이 좋다.

정리:

  • == 연산자는 객체의 참조(주소)를 비교
  • equals() 메서드는 객체의 을 비교
  • 문자열 리터럴은 String Constant Pool에 저장되며, 동일한 값이라면 같은 객체를 참조
  • 문자열 비교 시 항상 equals() 메서드를 사용하는 것이 좋다.

nullNullPointerException (NPE)

null이란?

null은 참조 타입 변수에서, 변수가 힙 영역의 어떤 객체도 참조하지 않는 상태를 의미. 참조 타입 변수는 null 값으로 초기화될 수 있으며, 이 경우 해당 변수는 스택 영역에 생성된다.

String str = null;  // str은 어떤 객체도 참조하지 않음

참조타입 변수가 null값을 갖는지 확인하기 위해서 동등비교를 통해 확인이 가능하다.

refValue1 == null  //결과: false
refValue1 != null  //결과: true

refValue2 == null  //결과: true
refValue2 != null  //결과: false
if(refValue1 != null){
	// refValue1의 null 체크
	refValue1.length();
}

NullPointerException (NPE)

참조하고 있는 객체가 없는 상태에서 참조 변수를 사용하려 할 때 발생. 예를 들어, null 값인 변수를 사용하여 메서드를 호출하거나 배열에 접근하려 하면 NPE가 발생한다.

int[] intArray = null;
intArray[0] = 10;  // NullPointerException 발생

위 코드에서 intArraynull로 초기화된 상태이므로 배열의 첫 번째 요소에 접근하려는 시도에서 NPE가 발생한다.

NPE가 발생하는 이유:

  • 참조하는 객체가 없는데 메서드나 필드를 호출하는 경우에 NPE가 발생
  • 이는 런타임 시점에만 발생하는 예외로, 프로그램이 실행될 때 확인할 수 있다.

NPE 방지 방법:

  • 참조 타입 변수를 선언할 때 null로 초기화하는 습관을 피해야 한다.
  • 변수를 사용할 때 미리 객체를 생성하거나 초기화해야 한다.
String str = " ";  // null 대신 빈 문자열로 초기화
System.out.println("총 문자수: " + str.length());  // 예외 발생하지 않음

또한, 객체가 생성되지 않은 상태에서 참조 변수를 사용하는 것을 피하려면, 객체를 생성자로 초기화하는 것이 좋다.

프론트에서 오는 필수 파라미터가 아닌 값을 받을 때 발생할 수도 있다.
그러다 .toString()을 쓰면 발생 (대신 String.valueOf()을 사용해 방지할 수 있다.)

정리:

  • 참조 타입 변수를 초기화할 때 null로 초기화하는 습관을 피하는 것이 NPE를 방지하는 좋은 방법
  • null 대신 빈 값으로 변수를 초기화하면 NPE를 예방할 수 있다.
  • equals()를 이용한 값 비교 시, NPE를 피하려면 null인지 여부를 먼저 확인하거나 값을 미리 초기화하는 습관을 들이는 것이 좋다.

intern() 메서드

intern() 메서드는 문자열이 이미 String Constant Pool에 있는지 확인하고, 있다면 해당 문자열의 참조를 반환한다. intern()을 사용하면 메모리 절약과 성능 최적화를 기대할 수 있다.

참고: String intern()


문자열(String) 타입

문자열이란?

문자열은 문자로 구성된 문장을 의미하며, Java에서는 String 클래스를 사용하여 문자열을 다룬다. String불변 객체(immutable)로, 한 번 생성된 문자열 객체는 변경할 수 없다.

String str = "a";
str = str + "b";

위 코드에서 "a""b"를 더했을 때, 기존 문자열이 변경되는 것이 아니라 새로운 문자열 객체가 생성되기 때문에 , str 변수는 새로운 메모리 공간을 참조하게 된다. 이러한 특징 때문에, 문자열을 반복적으로 변경하는 작업에서는 성능 저하가 발생할 수 있다.

문자열 내장 메서드

Java String 클래스는 다양한 내장 메서드를 제공하여 문자열을 쉽게 다룰 수 있다.

  • equals() 문자열 두 개가 같은지 비교하여 결과를 리턴
  • indexOf(문자) 특정 문자열이 시작되는 위치(인덱스 값)를 리턴
    String hello = "Hello JAVA";
    System.out.println(hello.indexOf("J"));  // 출력: 6
  • contains(특정 문자열) 문자열이 특정 문자열을 포함하고 있는지 여부를 리턴. (결과값: true 또는 false)
  • charAt(특정 위치 인덱스) 문자열에서 특정 위치의 문자를 반환
System.out.println(hello.charAt(hello.indexOf("J")));  // 출력: J
  • replaceAll(문자열, 문자열) 문자열에서 특정 문자열을 다른 문자열로 교체할 때 사용
    String hello2 = "Hello Java Java";
    String replaceStr = hello2.replaceAll("Java", "everyone");
    System.out.println(replaceStr);  // 출력: Hello everyone everyone
  • replace(정규 표현식, 문자열) 특정 패턴(정규 표현식)에 맞는 문자열을 교체할 때 사용
  • substring(시작 인덱스, 끝 인덱스) 문자열의 특정 부분을 추출할 때 사용되며, 끝 인덱스의 문자는 포함되지 않는다.
    String hello3 = "Hello everyone everyone";
    System.out.println(hello3.substring(8, 13));  // 출력: every
    System.out.println(hello3.substring(13));     // 출력: one everyone
  • toUpperCase() 문자열의 모든 문자를 대문자로 변환
  • toLowerCase() 문자열의 모든 문자를 소문자로 변환
    String hello4 = "Hello World";
    System.out.println(hello4.toUpperCase());  // 출력: HELLO WORLD
    System.out.println(hello4.toLowerCase());  // 출력: hello world
  • split(구분자) 문자열을 특정 구분자로 나누어 문자열 배열로 반환
  • concat(문자열) 문자열을 합치는 메서드로, 결과값은 합쳐진 문자열을 반환
  • trim() 문자열의 앞뒤 공백을 제거
System.out.println("     Hello     ".trim());  // 출력: Hello
  • 문자열 내장 메서드 예제 실습
    public class StringInnerMethod {
        // 문자열 내장 메서드 실습
        public static void main(String[] args) {
            // indexOf / "Hello Java" J의 위치 출력
            String hello = "Hello JAVA";
            System.out.println(hello.indexOf("J")); // 6
    
            // charAt / 위치 찾은 것을 문자로 출력
            System.out.println(hello.charAt(hello.indexOf("J"))); // J
    
            // replace()
            String hello2 = "Hello Java Java";
            String replaceStr =  hello2.replaceAll("Java","everyone");
            System.out.println(replaceStr); // Hello everyone everyone
    
            // substring
            String hello3 = "Hello everyone everyone";
            System.out.println(hello3.substring(8, 13)); // eryon
            System.out.println(hello3.substring(13)); // e everyone
    
            // toUpperCase, toLowerCase()
            String hello4 = "Hello World";
            System.out.println(hello4.toUpperCase());
            System.out.println(hello4.toLowerCase());
    
            //trim
            System.out.println("     hello4.trim(): ".trim());
            
            // "aaaaddccd" 문자열 한 글자씩 출력하기
            String str = "aaaabbccd";
            for(int i = 0; i < str.length(); i++){
                System.out.println(str.charAt(i));
            }
    
            // 단어 순서 뒤집기
            String str2 = "Hello Welcom Java";
            String[] arr = str2.split(" ");
            for (int i = arr.length - 1; i >= 0; i--) {
                System.out.print(arr[i] + " ");
            }
    
            System.out.println("-------------");
    
            // 공백 제외해서 하나의 문자로 출력
            String str3 = "    Hello Welcome Java   ";
            System.out.println(str3.replace(" ",""));
        }

문자열 포맷팅 메서드

Java에서 문자열 내의 특정 값을 동적으로 변경할 수 있도록 하는 방법 중 하나가 문자열 포맷팅이다. String.format() 메서드를 사용하면 문자열 안에 값을 삽입할 수 있다.

포맷팅 기호:

  • %d : 10진수 숫자
  • %s : 문자열
  • %f : 실수형 숫자
// 문자열 포맷(%s, %d, %f)
public static void main(String[] args) {
    String str = "..........%s......특정문자%s값";
    System.out.println(String.format(str,"치환값1", "치환값2"));

    System.out.println(String.format(str, 4, 5));

    String str2 = "치환값 : %d ...........치환값2 : %d";
    System.out.println(String.format(str2, 7, 8));

    String str3 = "치환값1 : %f ...... 치환값2 : %f";
    // System.out.println(String.format(str3, "문자", "문자2?")); 에러
    System.out.println(String.format(str3, 1.1, 2.2));
}

포맷팅을 사용할 때, 선언된 치환값 개수와 실제로 전달되는 치환값 개수가 동일해야 한다.
또한, 모든 치환값을 %s로 대체하여 사용할 수도 있다. 주로 템플릿 기반 문자열을 생성할 때 사용되며, 특정 값만 동적으로 치환할 수 있다.

ArrayList<Customer> customerInfo = xxx.getInfo();

for (Customer customer : customerInfo) {
    System.out.println(String.format("%s님의 고객정보 취급 약관...", customer.getName()));
}

정리:

  • String불변 객체로, 값이 변경되면 새로운 객체가 생성된다.
  • 문자열 처리 시 자주 사용되는 메서드로는 equals(), indexOf(), replaceAll(), substring(), split(), concat() 등이 있다.
  • 문자열 포맷팅 메서드인 String.format()은 문자열 내부에서 특정 값을 동적으로 변경할 수 있게 해준다.

StringBuffer / StringBuilder

StringBufferStringBuilderString 클래스의 불변성(immutable)을 보완하기 위한 클래스들로, 문자열을 추가하거나 변경하는 작업이 빈번할 때 주로 사용된다. String 객체는 불변이기 때문에 문자열을 조작할 때마다 새로운 객체가 생성되지만, StringBufferStringBuilder동일 객체 내에서 문자열을 수정할 수 있고, 이를 통해 불필요한 객체 생성을 줄이고 성능을 향상시킬 수 있다.

StringBuffer buffer = new StringBuffer();
buffer.append("문자열 추가");

StringBuffer와 StringBuilder의 차이점

  • StringBuffer
    • 멀티스레드 환경에서 thread-safe한 특성을 가진다.
    • 동기화된 메서드를 제공하므로, 여러 스레드가 동시에 접근하더라도 안전하게 사용할 수 있다.
  • StringBuilder
    • 단일 스레드 환경에서 사용을 권장
    • 동기화가 필요하지 않기 때문에 StringBuffer보다 성능이 우수하다.

멀티스레드와 성능

멀티스레드 환경에서는 여러 스레드가 동시에 하나의 자원에 접근할 수 있기 때문에 동기화(synchronized)가 필요하다. 동기화는 하나의 스레드가 작업을 완료할 때까지 다른 스레드의 접근을 차단하는 방식으로 이루어지며, 이는 안정성을 보장하는 반면, 성능을 저하시킬 수 있다.

StringBuffer는 동기화를 지원하는 반면, StringBuilder동기화가 적용되지 않아 성능이 더 뛰어나지만, 멀티스레드 환경에서는 안전하지 않을 수 있다.

StringBuffer buffer = new StringBuffer();
buffer.append("스레드 안전한 사용");

주요 메서드

append()

문자열을 추가하는 메서드,
이 메서드를 사용하면 새로운 객체를 생성하지 않고 기존 문자열에 이어붙힌다.

StringBuffer buffer = new StringBuffer("Hello");
buffer.append(" World!");
System.out.println(buffer);  // 출력: Hello World!

insert(위치, 문자열)

특정 위치에 원하는 문자열을 삽입할 수 있다.
문자열의 길이를 초과하는 인덱스를 지정하면 에러가 발생한다. 문자열의 끝에 붙이고 싶을 경우 buffer.length()를 이용할 수 있다.

StringBuilder builder = new StringBuilder("Hello World!");
System.out.println(builder.insert(6, "Java "));  // 출력: Hello Java World!
System.out.println(builder.insert(builder.length(), " 마지막에 추가"));  // 출력: Hello Java World! 마지막에 추가

substring(시작 인덱스, 끝 인덱스)

Stringsubstring() 메서드와 동일하게 동작
시작 위치에서 끝 위치까지의 문자열을 추출한다. 끝 인덱스는 포함되지 않는다.

StringBuffer buffer = new StringBuffer("Hello Java World!");
String substringResult = buffer.substring(6);  // 6번 인덱스부터 끝까지 추출
String substringResult2 = buffer.substring(6, 10);  // 6번 인덱스부터 9번 인덱스까지 추출

System.out.println(substringResult);  // 출력: Java World!
System.out.println(substringResult2);  // 출력: Java
  • StringBuffer/StringBuilder 실습 예제
    // StringBuffer/StringBuilder
    public static void main(String[] args) {
    
        String result = "";
        result += "Hello ";
        result += "Java ";
        result += "World!";
        System.out.println(result);
    
        StringBuffer buffer = new StringBuffer();
        buffer.append("Hello ");
        buffer.append("Java ");
        buffer.append("World! ");
        System.out.println(buffer);
        System.out.println(buffer.toString());
    
        StringBuilder builer = new StringBuilder();
        builer.append("Hello ");
        builer.append("Java ");
        builer.append("World! ");
        System.out.println(builer);
    
        // insert(), substring()
        System.out.println(builer.insert(0, "첫번째"));
        // System.out.println(builer.insert(50, "오십번째다")); // 문자열 길이를 초과하면 에러
        System.out.println(builer.insert(builer.length(),"마지막에 붙히기"));
    
        // substring();
        String substringResult = buffer.substring(6);
        String substringResult2 = buffer.substring(6, 7);
    
        System.out.println(substringResult); // Java World!
        System.out.println(substringResult2); // J
    
        // 연속된 문자의 반복 횟수로 문자열 압축해보기
        String str = "aaaabbccd";
    
        for(int i = 0; i < str.length(); i++){
    
        }
    }

동기화와 성능 차이

  • StringBuffer스레드 안전성(thread-safety)을 보장하기 위해 모든 메서드에 synchronized 키워드가 붙어 있다. 이를 통해 멀티스레드 환경에서도 데이터의 일관성을 유지할 수 있다. 그러나 동기화로 인해 성능이 저하될 수 있다.
  • StringBuilder는 동기화가 적용되지 않기 때문에 단일 스레드 환경에서 더 빠른 성능을 제공한다. 동기화가 필요 없는 상황에서는 StringBuilder를 사용하는 것이 좋다.

실제 사용 시 고려 사항

일반적으로, 멀티스레드 환경에서는 StringBuffer를 사용하고, 단일 스레드나 동기화가 필요하지 않은 경우에는 StringBuilder를 사용하는 것이 좋다.

StringBuffer safeBuffer = new StringBuffer();  // 멀티스레드 환경에서 사용
StringBuilder fastBuilder = new StringBuilder();  // 성능이 우선시되는 경우 사용

정리:

  • StringBuffer스레드 안전하고, StringBuilder성능이 뛰어남
  • 문자열을 추가하거나 변경하는 작업이 많을 때는 StringBuffer 또는 StringBuilder를 사용하여 성능을 최적화할 수 있음
  • 주요 메서드로는 append(), insert(), substring() 등이 있으며, 이들을 통해 문자열을 동적으로 조작할 수 있음

객체지향 언어

객체지향프로그래밍이란?

객체지향프로그래밍(Object-Oriented Programming, OOP)은 부품들을 조립하여 프로그램을 완성하는 개발 기법. 이를 이해하기 위해서는 객체객체 간의 상호작용에 대한 개념이 중요하다.
객체지향 프로그래밍에서 객체는 클래스에 의해 정의된 실체로, 속성(필드)기능(메서드)을 가지고 있다.

class Calculator {
    static int result = 0;

    static int add(int num) {
        result += num;
        return result;
    }
}

public class Sample {
    public static void main(String[] args) {
        System.out.println(Calculator.add(5)); // 출력: 5
        System.out.println(Calculator.add(4)); // 출력: 9
    }
}

위 코드에서 Calculator 클래스는 정적(static) 멤버를 가지고 있어서 계산기를 여러 대 생성할 수 없다. 만약 다른 계산기로 독립적인 계산을 하고 싶다면, 새로운 인스턴스를 생성해야 한다.

class Calculator {
    int result = 0;

    int add(int num) {
        result += num;
        return result;
    }
}

public class Sample {
    public static void main(String[] args) {
        Calculator cal1 = new Calculator();  // 계산기1 객체
        Calculator cal2 = new Calculator();  // 계산기2 객체

        System.out.println(cal1.add(5)); // 출력: 5
        System.out.println(cal1.add(4)); // 출력: 9

        System.out.println(cal2.add(1)); // 출력: 1
        System.out.println(cal2.add(10)); // 출력: 11
    }
}

이 코드에서는 각각의 계산기 객체를 생성하여 독립적으로 계산을 수행한다.클래스 정의만 만들어 놓고 필요할 때마다 객체를 생성하여 사용한다.


객체지향 프로그래밍의 특징

캡슐화

캡슐화는 클래스 내부의 데이터와 메서드를 외부로부터 보호하는 개념
외부에서는 객체의 내부 구조를 알 필요 없이, 정해진 메서드를 통해서만 객체와 상호작용한다.
이를 통해 데이터 보호데이터 은닉을 실현할 수 있다.

  • 데이터 보호: 클래스의 속성과 메서드를 외부로부터 보호하여 잘못된 접근을 막는다.
  • 데이터 은닉: 객체 내부의 동작을 감추고, 필요한 정보만 외부에 공개한다.

다형성

다형성은 같은 타입의 객체가 여러 형태로 동작할 수 있는 성질을 의미.
상위 클래스 타입의 참조 변수를 사용하여 여러 하위 클래스 객체를 참조할 수 있는 능력으로.
주로 인터페이스와 관련이 있으며, 상황에 맞게 객체가 다르게 행동할 수 있도록 한다.


클래스와 객체

클래스란?

클래스는 객체의 속성기능을 정의하는 청사진. 설계도라고 볼 수 있으며, 객체는 이 설계도를 기반으로 만들어진 실체이다.. 객체를 생성하려면 클래스 정의가 필요하다.

객체란?

객체는 클래스를 바탕으로 생성된 실제 실체로, 속성(필드)과 기능(메서드)을 가진다.

(참조타입) (변수) = new (클래스명);

참조타입에 클래스가 올 경우, 변수는 해당 클래스의 객체가 된다.

클래스의 구성 요소

  • 필드: 객체의 속성을 저장하는 곳으로, 인스턴스 변수가 주로 사용된다.
  • 생성자: 객체가 생성될 때 호출되며, 초기화를 담당한다.
  • 메서드: 객체가 수행할 동작을 정의한 실행 블록이다.
class Calculator {
    int result = 0; // 인스턴스 변수 (필드)

    int add(int num) {
        result += num;
        return result;
    }

    int multiple(int num) {
        result *= num;
        return result;
    }
}

위 코드에서:

  • 필드result는 계산 결과를 저장하는 속성
  • 메서드add()multiple()은 계산기를 통해 수행할 기능을 정의

정리 :

  1. 객체지향프로그래밍(OOP)은 객체를 기반으로 프로그램을 개발하는 기법
  2. 클래스는 객체를 만들기 위한 설계도이며, 객체는 이 설계도를 기반으로 실체화된 프로그램의 구성 요소
  3. OOP의 특징으로는 캡슐화다형성이 있으며, 이들은 데이터 보호유연한 객체 활용에 중요한 역할을 한다.
profile
룰루

0개의 댓글