2024. 10. 6. 14:07ㆍjava/에 대하여
내가 java를 얼마나 알고있나? 이것은 순전히 내 머리 속을 정리하기 위한 작성이다.
불친절하고 부정확할 수 있다. java에 대한 내 지식을 포석처럼 나열한다.
java란?
C를 발전시켜 편의성과 OOP를 추구한 lang. jvm을 통해 어떠한 환경에서도 구동될 수 있도록 한 lang이다.
개인적으로 C와 다르게 느끼는 점은 memory관리를 할 필요가 없다는 점 정도? 애초에 나는 C로 정말 큰 무언가를 만들어 본 적이 없으니.
그렇다면 OOP란?
Object Oriented Programming
객체 지향 프로그래밍
function, file, structure를 조합, 발전시켰다고 하면 조금 이상하지만, 적어도 필자의 머리 속에서는 얼추 모양새가 잡힌다.
그럼 객체는 뭔데?
마치 철학적인 용어처럼 들린다.
실존? 본질? 시뮬라크르일까? 어쩌면 이데아일지도 모른다.
객체는 class에 우선하나? 객체는 구토인가? 우리는 행복한 시지프를 상상해야만 하나?
이 객체를 보아라.
시덥잖은 농담이다.
아무튼 너무 신경 쓰지 말자. class라는 설계도를 바탕으로 컴퓨터 세상에 현현한 것이 객체, object, instance라고 생각하자. 아무리 생각해보아도 별로 중요한 일이 아니다.
아무래도 객체에 대해서 가장 우선되는 설명은 캡슐화일 것이다.
아마 특정 개념에 대한 호칭이 일관성 없이 변할 수도 있다. 아래에 내가 '편의상' 혼용하는 명칭에 대해 몇 가지 작성해두겠다.
$ 객체 = object = instance = module
$ 변수 = var = field
$ method = 기능 = logic
encapsulation
특별한 것은 없다. 하나의 class를 작성했다고 생각하자.
그 내부에 무엇이 있을까?
variable이 있을 것이다. 이제 또 그 var들을 가지고 무언가를 해야한다. function? 우리는 이제 method라고 부른다. 그럼 간단하게 하나 갈겨볼까 싶다. 두 정수를 합하는 클래스이다.
public Class Calc{
public static void plus() {
int a = 0;
int b = 0;
int result = 0;
Scanner s = new Scanner(System.in);
a = s.nextInt();
b = s.nextInt();
result = a + b;
System.out.println(result);
}
}
하나의 class, 하나의 capsule이다.
Calc class에 plus method가 있고, 그 안에 var들이 있다.
plus method는 두 정수를 입력받아, 합하고 출력하는 역할을 한다.
class는 var와 기능의 집합이다.
java에선 우리가 정의한 var를 field라고 부르기도 한다.
hiding
정보 은닉. 이것은 encapsulation에 부가적으로 따라온다.
외부로의 logic 노출을 최소화한다. 숨겨진 logic class에 접근하는 또 다른 수단들을 통한다. class간의 결합도를 낮추는 효과가 있다.
위 예제 class는 완전히 노출되어있다. 조금 만져볼까? GPT한테 시키기는 했지만.
public class Main {
public static void main(String[] args) {
InputHandler inputHandler = new InputHandler();
Calculator calculator = new Calculator();
int a = inputHandler.getInput("첫 번째 숫자 입력: ");
calculator.setA(a);
int b = inputHandler.getInput("두 번째 숫자 입력: ");
calculator.setB(b);
int result = calculator.plus();
System.out.println(result);
}
}
성모님 맙소사! 기능들이 다 사라졌어요! 다 어디갔지? 이래서는 어떻게 작동하는지 알 수가 없잖아!
저 inputHandler는 뭐지? 아무튼 저게 입력을 받는건가봐.
저 calc도 저게 계산을 해주는걸까?
public class InputHandler {
private Scanner scanner;
public InputHandler() {
scanner = new Scanner(System.in);
}
public int getInput(String prompt) {
System.out.print(prompt);
return scanner.nextInt();
}
}
public class Calculator {
private int a;
private int b;
public void setA(int a) {
this.a = a;
}
public void setB(int b) {
this.b = b;
}
public int plus() {
return a + b;
}
}
기능들이 돌아왔어요! 하지만 왜 이렇게 따로따로 쓴 거에요?
그것이... java이니까...
모양새를 다시 한 번 보자면, main class와 method가 실행된다.
시작하자마자, inputHandler의 객체가 생성되었다.
이어서, calculator도.
int a = inputHandler.getInput("첫 번째 숫자 입력: ");
inputHandler.getInput("첫 번째 숫자 입력: ")이 a라는게 대체 무슨 소리일까?
우리는 "첫 번째 숫자 입력: "을 iP class에 있는 getInput method에 인자(argument)로써 보낸다.
getInput은 String을 인수(parameter)로써 받는다. 우리가 뭘 보냈지? "첫번째숫자입력".
자동적으로 String prompt = "첫번째숫자입력: "이 일어난 것이다.
그 아래에 무엇이 있지? return scanner.nextInt();
반환한다 -> nextInt를 -> main으로 -> 그리고 해당 method 종료.
내가 10을 입력했다고 가정하자. inputHandler.getInput은 이제 10이다. 그리고 그 값을 a에 대입하니, a가 10이 되었다. 야호!
이제 Calc도 같은 방법을 통한다! a를 calc class에 있는 setA로 보내고, 받는다. 그리고 this.a에 대입한다. b도 같다.
this에 대한 정리는... 안할수도 있다.
calc에 a, b가 모두 준비되었다. main에서 다시 Clac.plus를 호출한다. plus의 기능은 a + b을 반환하는 것. 그 결과값이 main으로 반환되어 result에 할당된다. 그리고 출력한다.
첨언하자면 iP도 main이 아니라 clac 안에 있으면 좋았을것이다.
뭔가 멀리 돌아간 기분이다.
보다시피 하나의 class에 전부 잡아넣은 것이 아닌, 기능별로 분리되어있다. 접근과 호출과 출력, 입력받기, 계산하기... 각 class가 하나의 객체이고, instance이고, module이다.
그래서 왜 따로 썼냐고요!
- 재사용성이 좋아진다.
내가 작성한 것으로는 예시를 들 수 없지만, 큰 project를 했다고 가정하자. 그리고 당신이 지금 작성하는 class에 두 수를 더하는 기능이 필요하다. 다행히도 당신은 저 calc class를 만들어 놓았다. 그 덕에 당신은 간편하게 해당 class에 calc instance를 생성해 plus() method를 사용 할 수 있었다.
하지만 당신이 저것을 module화 하지 않았다면? 해당 class에 저 logic을 또 작성해야한다.
우리는 이렇게 결합도를 낮추고, 절대적인 codes를 줄였다. oop의 은총이다.
아마 다형성에 대해 작성할 때 더 자세하게 기술되리라. - 유지보수하기에도 좋다.
저 허접한 clac class를 보시라. 겨우 2개만 더할 수 있다. 너무 허접한 logic이라 나는 module로 만들지 않고, 모든 classes에 하나하나 써버렸다. 이미 encapsulation을 위배해버린 것이다. 재사용성의 혜택을 누릴 수 없다.
그런데 맙소사. 우리는 이제 3개의 수를 더하고자 한다.
나는 모든 classes에 있는 더하기 logics를 하나하나 찾아서 하나하나 수정해야한다. 그리고 iP 기능도 찾아서 '하나'의 값을 더 받도록 열심히 찾아서 수정해야한다. 아마 실수도 할 수도 있고, 뭔가 class에 영향을 미쳐 기능이 망가질 수도 있다.
하지만 당신을 똑똑했다. 당신은 calc와 ip만 조금 수정하면 기능을 수정할 수 있다. 당신의 1분은 나의 3시간만큼의 가치를 만들어냈다. - 정보은닉과 보안
정보가 잘못 수정되거나 손상되는 것을 방지한다. 무결성 유지라고 할 수 있을 것이다.
그리고 data에 직접적으로 접근하는 것을 막음으로써, 우리가 의도하지 않은 사용이나, exploit을 막아낼 수 있다.
정보 은닉과 보안성에 대해서는 개인적으로 체감한 바가 없어서 뭐라 말 하기가 어렵다.
Dasvidaniya!
이거 생각보다 힘드네. 다른 사람들은 어떻게 했는지 모르겠다.
이상으로 java의 oop 중, encapsulation에 대한 기술을 마치고자 한다.
좋은 하루.
'java > 에 대하여' 카테고리의 다른 글
java에 대해 처음부터 생각해보기-2 (4) | 2024.10.06 |
---|