☕️[Java] Object와 OCP - 2.
1️⃣ Object.
- Java에서
'Object'
는 모든 클래스의 최상위 부모 클래스이자, Java 클래스 계층 구조의 최상위에 위치하는 클래스입니다. - Java에서 모든 클래스는 암묵적으로
'Object'
클래스를 상속받으며, 이로 인해'Object'
클래스가 제공하는 메서드를 사용할 수 있습니다.- 이는 Java의 객체 지향 프로그래밍(OOP)에서 중요한 역할을 합니다.
1️⃣ Object 클래스의 주요 역할.
-
1. 최상위 클래스.
- 모든 Java 클래스는
'Objcet'
클래스를 상속받기 때문에'Object'
클래스에서 제공하는 메서드는 모든 객체에서 사용할 수 있습니다.
- 모든 Java 클래스는
-
2. 기본 메서드 제공.
-
'Object'
클래스는 모든 객체가 기본적으로 사용할 수 있는 몇 가지 중요한 메서드를 제공합니다.- 예를 들어 다음과 같습니다.
-
'equals(Object obj)'
- 두 객체가 같은지를 비교합니다.
-
'hashCode()'
- 객체의 해시 코드를 반환합니다. 이 값은 객체를 식별하는 데 사용됩니다.
-
'toString()'
- 객체를 문자열로 표현합니다.
-
'clone()'
- 객체를 복제합니다.(단, 클래스에서
'Cloneable'
인터페이스를 구현해야 사용 가능)
- 객체를 복제합니다.(단, 클래스에서
-
'finalize()'
- 객체가 가비지 컬렉션되기 전에 호출됩니다.
-
- 예를 들어 다음과 같습니다.
-
-
3. 다형성 지원.
-
'Object'
타입으로 모든 객체를 참조할 수 있으므로, 다양한 객체를 처리하는 메서드나 컬렉션에서 유연성을 제공합니다.- 예를 들어, Java의 컬렉션 프레임워크에서는
'Object'
타입을 사용하여 다양한 타입의 객체를 저장할 수 있습니다.
- 예를 들어, Java의 컬렉션 프레임워크에서는
-
-
4. 공통 기능의 확장.
- 모든 클래스가
'Object'
를 상속받기 때문에,'Object'
클래스의 메서드를 재정의(Override)하여 클래스에 맞는 동작을 구현할 수 있습니다.- 예를 들어,
'toString()'
메서드를 재정의하여 객체의 상태를 의미 있는 문자열로 표현할 수 있습니다.
- 예를 들어,
- 모든 클래스가
2️⃣ 예시.
- 다음은
'Object'
클래스의 메서드를 활용하는 간단한 예시입니다.
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Person person = (Person) obj;
return age == person.age && name.equals(person.name);
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + "}";
}
public static void main(String[] args) {
Person person1 = new Person("Alice", 30);
Person person2 = new Person("Alice", 30);
System.out.println(person1.equals(person2)); // true
System.out.println(person1.toString()); // Person{name='Alice', age=30}
}
}
- 이 예시에서
'equals'
와'toString'
메서드는'Object'
클래스에서 제공하는 메서드를 재정의하여'Person'
클래스의 객체에 적합한 동작을 정의하고 있습니다.
3️⃣ 결론.
- Java의
'Object'
클래스는 모든 클래스의 공통 조상으로서 중요한 역할을 하며, 기본적인 객체 비교, 해시 코드 생성, 문자열 표현 등의 기능을 제공합니다.- 이는 Java에서의 객체 지향 프로그래밍의 기초를 이루며, 다양한 클래스 간의 상호작용을 가능하게 합니다.
2️⃣ OCP
- OCP는 “Open/Closed Principle”의 약자로, 객체 지향 설계의 중요한 원칙 중 하나입니다.
- 이 원칙은 Robert C. Martin에 의해 정의된 SOLID 원칙 중 하나로, 소프트웨어 설계의 유연성과 유지보수성을 높이기 위한 지침을 제공합니다.
1️⃣ OCP(Open/Closed Principle)의 정의
-
“소프트웨어 엔티티(클래스, 모듈, 함수 등)는 확장에 열려 있어야 하고, 수정에는 닫혀 있어야 한다.” 라는 원칙입니다.
-
확장에 열려 있어야 한다(Open for extension)
- 새로운 기능이나 요구사항이 추가될 때, 기존 코드를 변경하지 않고도 기능을 확장할 수 있어야 한다는 뜻입니다.
- 이를 통해 소프트웨어를 유연하게 확장할 수 있으며, 새로운 기능을 도입할 때 기존 코드에 영향을 주지 않게 됩니다.
-
수정에 닫혀 있어야 한다(Closed for modification)
- 기존에 잘 작동하던 코드를 수정하지 않고도 새로운 기능을 추가할 수 있어야 한다는 뜻입니다.
- 이는 소프트웨어의 안정성을 유지하면서 변경의 영향을 최소화할 수 있습니다.
-
확장에 열려 있어야 한다(Open for extension)
2️⃣ OCP의 구현 방법.
- OCP를 구현하는 가장 일반적인 방법은 추상화 와 다형성 을 사용하는 것입니다.
- 추상 클래스나 인터페이스를 통해 기본 구조를 정의하고, 이를 상속하거나 구현하여 구체적인 기능을 확장합니다.
- 이렇게 하면 기존 코드베이스를 변경하지 않고도 새로운 기능을 추가할 수 있습니다.
- 추상 클래스나 인터페이스를 통해 기본 구조를 정의하고, 이를 상속하거나 구현하여 구체적인 기능을 확장합니다.
3️⃣ 예시.
// 기존 코드: Shape 인터페이스 정의
interface Shape {
double calculateArea();
}
// 기존 코드: Rectangle 클래스 정의
class Rectangle implements Shape {
private double width;
private double height;
public Rectangle(double width, double height) {
this.width = width;
this.height = height;
}
@Override
public double calculateArea() {
return width * height;
}
}
// 확장 코드: Circle 클래스 정의 (기존 코드를 수정하지 않음)
class Circle implements Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double calculateArea() {
return Math.PI * radius * radius;
}
}
// 클라이언트 코드
public class Main {
public static void main(String[] args) {
Shape rectangle = new Rectangle(10, 20);
Shape circle = new Circle(5);
System.out.println("Rectangle Area: " + rectangle.calculateArea());
System.out.println("Circle Area: " + circle.calculateArea());
}
}
설명
- 이 예시에서
'Shape'
인터페이스는 면적을 계산하는'calculateArea()'
메서드를 정의합니다. -
'Rectangle'
클래스는 이 인터페이스를 구현하여 사각형의 면적을 계산하는 기능을 제공합니다. - 이후,
'Circle'
클래스를 추가하면서 새로운 기능을 확장합니다.- 이 과정에서 기존의
'Rectangle'
클래스나'Shape'
인터페이스의 코드는 전혀 수정하지 않고 새로운 기능을 추가할 수 있었습니다.
- 이 과정에서 기존의
이처럼 OCP를 잘 준수하면 소프트웨어가 변화하는 요구사항에 유연하게 대응할 수 있으며, 유지보수 비용을 줄이고 코드의 재사용성을 높일 수 있습니다.
3️⃣ Object와 OCP의 관계.
-
'Object'
와'OCP(Open/Closed Principle)'
는 둘 다 객체 지향 프로그래밍의 개념과 밀접하게 관련되어 있지만, 그 역할과 목적은 다릅니다.- 이 둘의 관계ㄴ를 이해하려면 먼저 각각의 역할을 간단히 요약하고, 그 후에 이들이 어떻게 상호작용하는지 설명할 수 있습니다.
1️⃣ ‘Object’ 클래스의 역할
- Java에서
'Object'
클래스는 모든 클래스의 최상위 부모 클래스입니다.- 모든 Java 클래스는 암묵적으로
'Object'
를 상속받으며,'Object'
클래스에서 제공하는 메서드를 사용할 수 있습니다. - 이 클래스는 Java에서 객체의 기본적인 기능(예:
'equalse'
,'hashCode'
,'toString'
)을 제공합니다. -
'Object'
클래스 자체는 특정한 설계 원칙을 강제하지 않지만, 객체 지향 프로그래밍의 근본적인 기초를 제공합니다.
- 모든 Java 클래스는 암묵적으로
2️⃣ OCP(Open/Closed Principle)의 역할.
- OCP는 소프트웨어 설계 원칙으로, 소프트웨어가 확장에는 열려 있어야 하고, 수정에는 닫혀 있어야 한다 는 원칙을 따릅니다.
- 이 원틱은 소프트웨어를 설계할 때 변화하는 요구사항에 유연하게 대응하고, 코드의 수정 없이도 기능을 확장할 수 있도록 구조화하는 방법론입니다.
- 이는 주로 인터페이스, 추상 클래스, 상속, 다형성 등을 통해 구현됩니다.
- 이 원틱은 소프트웨어를 설계할 때 변화하는 요구사항에 유연하게 대응하고, 코드의 수정 없이도 기능을 확장할 수 있도록 구조화하는 방법론입니다.
3️⃣ ‘Object’와 OCP의 관계.
-
1. 기본 클래스 구조 제공.
-
‘Object’ 클래스는 모든 클래스의 기본이 되며, OCP 원칙을 적용하기 위한 기본 구조를 제공합니다.
- 예를 들어, 모든 클래스가
'Object'
를 상속받기 때문에, 클래스 설계자는'Object'
클래스에서 제공하는 메서드(예:'equals'
,'hashCode'
) 를 재정의할 수 있습니다.- 이를 통해 각 클래스가 자신만의 독특한 행동을 가지도록 확장할 수 있습니다.
- 예를 들어, 모든 클래스가
-
‘Object’ 클래스는 모든 클래스의 기본이 되며, OCP 원칙을 적용하기 위한 기본 구조를 제공합니다.
-
2. 추상화와 다형성의 기초.
- OCP를 실현하기 위해서는 추상화와 다형성이 중요한데,
'Object'
클래스는 이 둘의 기초를 제공합니다. - 모든 클래스는
'Object'
타입으로 참조될 수 있으므로, OCP를 구현할 때 다형성을 활용할 수 있습니다.- 예를 들어, 다양한 타입의 객체를
'Object'
로 처리하면서도, 각 객체가 특정 행위를 다르게 구현하도록 설계할 수 있습니다.
- 예를 들어, 다양한 타입의 객체를
- OCP를 실현하기 위해서는 추상화와 다형성이 중요한데,
-
3, OCP 준수에 대한 도움.
-
'Object'
클래스는 모든 클래스가 공통적으로 가져야 하는 기본적인 기능을 제공하기 때문에, 설계자는 이 기능을 바탕으로 필요한 부분만 재정의하여 기능을 확장할 수 있습니다.- 이는 OCP를 준수하는 데 도움이 됩니다.
- 예를 들어, 특정 객체가
'equals'
메서드를 새롭게 구현함으로써 비교 방식을 확장하면서도, 기존의'Object'
클래스 코드를 수정할 필요는 없습니다.
- 예를 들어, 특정 객체가
- 이는 OCP를 준수하는 데 도움이 됩니다.
-
4️⃣ 결론.
-
'Object'
클래스는 모든 클래스의 기반이 되며, OCP를 준수하는 소프트웨어 설계에 있어 중요한 역할을 합니다. -
Object
는 직접적으로 OCP를 구현하지 않지만, 그 위에서 개발자들이 OCP 원칙을 적용할 수 있도록 추상화와 다형성의 기초를 제공합니다. - OCP를 준수하는 설계를 통해 개발자는 객체 지향 프로그래밍의 이점을 극대화할 수 있습니다.