들어가며
이번 포스트에서는 OOP와 자바에서 활용하는 방법을 정리합니다.
원래 어노테이션에 대해 정리해보려고 했는데 해당 개념을 먼저 공부해보는 것이 이해하기 더좋다고 생각이 들어 먼저 정리했습니다.
JAVA , C++ , Python 등의 많은 소프트웨어에서 지원하는 프로그래밍 방법입니다.
이번 포스트에서는 자바에서 어떤식으로 OOP 즉, 객체 지향을 사용하고
확장하여 개발자들이 사용하게 하였는지에 대한 정리를 하며 공부한 내용을 공유합니다.
OOP는 이전 포스트에서 정리하여서 관련 링크를 함께 첨부합니다.
OOP?
OOP는 Object-Oriented Programming(객체 지향 프로그래밍)
자세한 설명은 아래 링크를 통해 확인해보세요
Abstract
이전 포스트에서도 언급하였듯이 추상에 대한 개념입니다.
추상은 간단히 말하여 특정 부분을 부각 - 즉, 공통된 특징을 부각하여 강조하기 위한 방법입니다.
JAVA에서는 Abstract Method (추상 메서드)를 지원합니다.
특징은 추상 메서드가 없어도 추상 클래스를 선언할 수 있다는 점입니다.
abstract class Shape {
// 추상 메서드가 없는 추상 클래스
// 추상 클래스 내에는 추상 메서드가 없어도 됩니다.
// 필드
protected String color;
// 생성자
public Shape(String color) {
this.color = color;
}
// 일반 메서드
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
// 추상 메서드가 없지만, 이 클래스는 추상 클래스로 선언되어 있습니다.
}
이런식으로 추상 메서드없이 선언하여 사용할 수 있습니다.
만약 추상메서드가 있다면 이런 식으로 만들어볼 수 있습니다.
abstract class Shape {
// 추상 메서드
abstract double getArea();
// 필드
protected String color;
// 생성자
public Shape(String color) {
this.color = color;
}
// 일반 메서드
public void setColor(String color) {
this.color = color;
}
public String getColor() {
return color;
}
}
그럼 추상 메서드가 없는 추상 메서드는 동작은 어떻게 구현할 수 있을까요?
public class Main {
public static void main(String[] args) {
// 추상 클래스는 직접 객체를 생성할 수 없습니다.
// Shape shape = new Shape(); // 컴파일 에러
// 하지만 추상 클래스의 하위 클래스를 통해 객체를 생성할 수 있습니다.
Circle circle = new Circle("red", 5.0);
System.out.println("Color of circle: " + circle.getColor());
System.out.println("Area of circle: " + circle.getArea());
}
}
class Circle extends Shape {
private double radius;
// 생성자
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
// 원의 넓이를 계산하는 메서드
public double getArea() {
return Math.PI * radius * radius;
}
}
이런식으로 extends -확장하여 상속받아 자식 클래스에서 메서드를 구현하면 됩니다.
그렇다면 부모 추상 클래스에 메서드를 선언했다면 어떻게 구현할 수 있을까요?
public class Main {
public static void main(String[] args) {
// 추상 클래스는 직접 객체를 생성할 수 없습니다.
// Shape shape = new Shape(); // 컴파일 에러
// 하지만 추상 클래스의 하위 클래스를 통해 객체를 생성할 수 있습니다.
Circle circle = new Circle("red", 5.0);
System.out.println("Color of circle: " + circle.getColor());
System.out.println("Area of circle: " + circle.getArea());
}
}
class Circle extends Shape {
private double radius;
// 생성자
public Circle(String color, double radius) {
super(color);
this.radius = radius;
}
// 원의 넓이를 계산하는 메서드
@Override
double getArea() {
return Math.PI * radius * radius;
}
}
이전 포스트에서 이야기한 Overriding - 덮어쓰기를 통해 Circle 자식클래스에서 메서드를 구현하면 됩니다.
이렇게 구현하는 경우에는 부모 클래스에서 접근제어자를 선택한다는 점이 있습니다.
저는 이런식으로 사용합니다.
만약, 추상 클래스를 통해 메서드를 구현하고 싶다.
자식 메서드를 통해 구현 - 부모 클래스에서 선언X
메서드 중 접근제어를 따로 관리해야 하는 경우, 특정 부분만 해당 메서드를 사용하는 경우
부모 메서드를 통해 구현
메서드 중 접근제어가 모두 동일하고, 기능이 대부분의 경우 사용하는 경우
제가 지금까지 해봤던 범위에서는 Abstract 가 필요한 경우 부모 메서드를 통해 구현하는 것이 유리한 경우가 많았습니다. (코드 가독성, 재사용성)
근데 추상 클래스는 new가 안되네 왜?
new는 말 그래도 새로 생성한다는 의미입니다.
자바에서 클래스의 인스턴스를 새로 생성한다는 의미인데 이것은 곧, 객체를 새로 만드는 다는 의미입니다.
그런데 추상 클래스의 장점이 추상 메서드를 여러 방향으로 구현할 수 있어 유연한 코드를 만드는 것입니다.
즉, 부모 클래스의 해당하는 추상 클래스의 경우 불안정한 메서드 상태 , 구현이 다 되지 않은 메서드를 가지고 있습니다.
그렇기 때문에 자바에서 추상 클래스가 새로운 객체를 만들지 못하도록 한것 입니다. (불안정하기 때문에)
따라서 자식 클래스의 해당 하는 부분에서 완벽하게 객체에 대한 정의를 하고 나서 해당하는 실체화 (concrete)된 클래스를 new 를 통해 생성할 수 있도록 유도한 것입니다.
New - 생성자에 대하여
위 소개한 new 키워드는 생성자를 의미합니다. - 객체를 새로 만든다.
사람 양세진 = new 사람();
() 이거는 메서드에서 사용하는 인자를 받기 위한방법인데?
즉, 클래스명() = 메서드 → 객체를 생성하는 메서드 = 객체 생성자 메서드 = 생성자
자바가 자동으로 기본 생성자를 만들어 준다는 것을 알 수 있는 방법입니다.
이런 방법이 저번 포스트에서 언급한 오버로딩을 활용한 방법이라고 알 수 있는 것입니다.
따라서 이런식으로 하면 에러가 나옵니다.
사람 양세진 = new 사람("Java");
사람 손흥민 = new 사람();
위에서 객체를 생성하며 인자가 한개 이상있는 생성자를 만들면
이후 부터는 자바가 자동으로 기본생성자를 만들어 주지 않는다는 것을 알 수 있습니다.
Final - 최종
final 키워드는 최종 이라는 의미입니다.
클래서 , 변수 , 메서드 에 붙여 사용하는데
이 의미는 더이상 상속을 허용하지 않겠다. 즉, 오버라이딩을 할 수 없게 하겠다 라는 의마가 됩니다.
예로,js에서 변수를 불변하게 선언할 때 const를 쓰는것과 같은 의미로 받아드리면 됩니다.
public final class 사람();
public class 양세진 extends 사람 (){}
이런식으로 사용하면 에러가 나겠죠. 왜냐하면 class 가 최종적으로 선언되어있고 이후에는 상속을 허용하지 않았기 때문입니다.
스프링에서는 주로 가져온 Package를 필요에 맞게 오버라이딩하고 해당 클래스를 final로 선언하여 이후에는 수정이 불가능하게 만들어 둡니다.
이런식으로 만들어 두면 상속을 통해 충돌하거나 중복되는 경우를 예방할 수 있게 돼서 사용하는 것으로 알고 있습니다. (정확한 내용은 아니라 다른 이유가 있다면 댓글 부탁 드립니다.)
정리
오늘은 OOP를 실제 자바에서 어떻게 구현할 수 있는지에 대해 이야기 해봤습니다.
추상화에 대한 Abstract에 대해 이야기 해보며 어떤 식으로 사용하는지
관련된 new와 final 키워드에 대한 내용도 정리해보며 이야기를 나누었습니다.
인터페이스에 대한 이야기도 추상화와 관련이 있어 함께 정리하려 했는데
내용이 길어져 다음포스트에서 이어 진행하겠습니다.
'JAVA' 카테고리의 다른 글
JAVA - 결합도에 대하여 (0) | 2024.06.03 |
---|---|
JAVA - interface (0) | 2024.05.29 |
JAVA-OverLoding & OverRiding (0) | 2024.05.29 |
JAVA-스레드 (0) | 2024.05.28 |
JAVA- 메모리 (0) | 2024.05.28 |