자바에는 두 가지 타입이 있습니다
기본형 타입(primitive types)과 참조형 타입(reference types)입니다.
기본형 타입은 직접 값을 저장하고, 참조형 타입은 객체를 가리키는 변수입니다. 기본형 타입은 int, double, boolean, char 등이 있으며, 이러한 기본형 타입은 스택(stack)에 직접 저장됩니다.
참조형 타입은 클래스, 인터페이스, 배열 등이 있습니다. 이러한 참조형 타입은 힙(heap)에 객체가 생성되고, 변수는 해당 객체를 가리키는 주소를 저장합니다. 참조형 변수는 실제 객체를 가리키기 때문에, 객체의 메서드를 호출하거나 인스턴스 변수에 접근하고 조작할 수 있습니다. 이를 통해 객체의 속성과 동작을 활용할 수 있습니다. 아래 예시들을 통해 참조형 타입에 대해 자세히 알아보겠습니다.
클래스와 객체 생성
// Person 클래스 정의
class Person {
String name;
int age;
void sayHello() {
System.out.println("안녕하세요! 저는 " + name + "입니다.");
}
}
// Person 객체 생성 및 사용
Person person = new Person();
person.name = "John";
person.age = 25;
person.sayHello();
// 배열 생성
int[] numbers = new int[5];
numbers[0] = 1;
numbers[1] = 2;
numbers[2] = 3;
numbers[3] = 4;
numbers[4] = 5;
// 배열 값 출력
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
위 예시에서는 numbers라는 int 타입의 배열을 생성하였습니다. 배열은 참조형 타입이므로, 배열의 주소를 가리키는 변수인 numbers를 사용하여 배열에 접근합니다. 배열의 각 요소에 값을 할당하고, 반복문을 통해 배열의 값을 출력합니다.
// String 클래스 사용
String str = "Hello, Java!";
int length = str.length();
String uppercase = str.toUpperCase();
System.out.println("Length: " + length);
System.out.println("Uppercase: " + uppercase);
위 예시에서는 String 클래스를 사용하여 문자열을 다루는 방법을 보여줍니다. str 변수에 문자열을 할당하고, length() 메서드를 호출하여 문자열의 길이를 구합니다. 또한, toUpperCase() 메서드를 호출하여 문자열을 대문자로 변환합니다. 결과를 출력합니다.
// 부모 클래스 정의
class Animal {
void makeSound() {
System.out.println("동물이 소리를 냅니다.");
}
}
// 자식 클래스 정의
class Dog extends Animal {
void makeSound() {
System.out.println("강아지가 멍멍 짖습니다.");
}
}
class Cat extends Animal {
void makeSound() {
System.out.println("고양이가 야옹 소리를 내며 애교를 부립니다.");
}
}
// 객체 생성 및 사용
Animal animal = new Animal();
Dog dog = new Dog();
Cat cat = new Cat();
animal.makeSound(); // 동물이 소리를 냅니다.
dog.makeSound(); // 강아지가 멍멍 짖습니다.
cat.makeSound(); // 고양이가 야옹 소리를 내며 애교를 부립니다.
위 예시에서는 클래스 간의 관계와 상속을 보여줍니다. Animal 클래스는 makeSound()라는 메서드를 가지고 있습니다. Dog 클래스와 Cat 클래스는 Animal 클래스를 상속받아 각각의 makeSound() 메서드를 재정의(오버라이딩)합니다. 객체를 생성하고 해당 객체의 makeSound() 메서드를 호출하면, 상속 관계에 따라 해당하는 클래스의 메서드가 실행됩니다.
// 클래스 정의
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
// 객체 배열 생성 및 사용
Person[] people = new Person[3];
people[0] = new Person("John", 25);
people[1] = new Person("Amy", 30);
people[2] = new Person("Mike", 35);
for (Person person : people) {
System.out.println("Name: " + person.name + ", Age: " + person.age);
}
위 예시에서는 Person 클래스를 정의하고, Person 객체를 배열로 저장하고 사용하는 방법을 보여줍니다. people 배열은 Person 객체를 저장하기 위한 배열로 초기 크기를 3으로 설정합니다. 배열의 각 요소에 Person 객체를 생성하여 할당합니다. 반복문을 통해 배열의 객체를 순회하고, 객체의 속성에 접근하여 출력합니다.
// 클래스 정의
class Calculator {
int add(int a, int b) {
return a + b;
}
void multiply(int[] numbers, int factor) {
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] * factor;
}
}
}
// 객체 생성 및 메서드 호출
Calculator calculator = new Calculator();
int result = calculator.add(5, 3);
System.out.println("Addition Result: " + result);
int[] numbers = {2, 4, 6, 8};
calculator.multiply(numbers, 2);
System.out.println("Multiplication Result: ");
for (int number : numbers) {
System.out.println(number);
}
위 예시에서는 Calculator 클래스를 정의하고, 메서드를 통해 계산을 수행하는 방법을 보여줍니다. add() 메서드는 두 개의 정수를 매개변수로 받아 더한 값을 반환합니다. multiply() 메서드는 정수 배열과 정수를 매개변수로 받아 배열의 각 요소에 해당 정수를 곱하여 수정합니다. 객체를 생성하고 메서드를 호출하여 결과를 출력합니다.
import java.util.ArrayList;
// ArrayList 사용
ArrayList<String> fruits = new ArrayList<>();
fruits.add("Apple");
fruits.add("Banana");
fruits.add("Orange");
System.out.println(fruits.size()); // 3
System.out.println(fruits.get(1)); // "Banana"
fruits.remove(0);
System.out.println(fruits.size()); // 2
System.out.println(fruits.get(0)); // "Banana"
위 예시에서는 ArrayList를 사용하여 동적인 크기를 갖는 문자열 요소의 목록을 만듭니다. add() 메서드를 사용하여 요소를 추가하고, get() 메서드를 사용하여 특정 위치의 요소에 접근합니다. 또한, remove() 메서드를 사용하여 요소를 제거합니다.
import java.util.HashMap;
// HashMap 사용
HashMap<String, Integer> scores = new HashMap<>();
scores.put("John", 90);
scores.put("Jane", 95);
scores.put("Bob", 80);
System.out.println(scores.get("Jane")); // 95
scores.remove("John");
System.out.println(scores.containsKey("John")); // false
System.out.println(scores.size()); // 2
위 예시에서는 HashMap을 사용하여 키와 값을 연결하는 맵을 생성합니다. put() 메서드를 사용하여 키-값 쌍을 추가하고, get() 메서드를 사용하여 키에 해당하는 값을 조회합니다. 또한, remove() 메서드를 사용하여 특정 키와 그에 해당하는 값을 제거합니다. containsKey() 메서드는 맵에 특정 키가 있는지 확인합니다.
// 인터페이스 정의
interface Shape {
void draw();
}
// 구현 클래스1
class Circle implements Shape {
@Override
public void draw() {
System.out.println("원을 그립니다.");
}
}
// 구현 클래스2
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("사각형을 그립니다.");
}
}
// 사용 예시
Shape circle = new Circle();
circle.draw(); // "원을 그립니다."
Shape rectangle = new Rectangle();
rectangle.draw(); // "사각형을 그립니다."
위 예시에서는 Shape라는 인터페이스를 정의하고, 이를 구현하는 Circle 클래스와 Rectangle 클래스를 만듭니다. 각 클래스는 draw() 메서드를 오버라이딩하여 도형을 그리는 동작을 구현합니다. 인터페이스 타입의 변수를 사용하여 구현 클래스의 객체를 할당하고, 메서드를 호출합니다.
이러한 예시들을 통해 참조형 타입을 다루는 방법과 객체 지향 프로그래밍의 개념을 살펴보았습니다. 참조형 타입은 객체 지향 프로그래밍의 핵심 요소로서, 객체의 생성과 조작을 통해 다양한 기능을 구현할 수 있습니다.