자바는 순수한 객체지향 언어일까?

Seop·2023년 6월 21일
0

객체지향

목록 보기
2/4
post-thumbnail

저는 항상 자바의 기능을 설명하는 책이나 게시물을 보면 항상 다른 언어에서 함수에 해당하는 부분을 메소드라고 표기하는 것을 항상 봤었습니다.

그리고는 문득 궁금해졌습니다.
왜 자바는 메소드라고 부르는 걸까??

Function / 함수 vs Method / 메소드

Function (함수)

A Function is a reusable piece of code. It can have input data on which it can operate (i.e. arguments) and it can also return data by having a return type. It is the concept of procedural and functional programming languages.

Function in Geeks for Geeks

함수는 재사용가능 코드 덩어리로서 인자와 같은 입력 데이터를 받을 수 있고, 특정 반환형으로 데이터를 반환할 수 있는 기능(function)을 가지고 있습니다.

우리가 예전에 수학 시간에 배운 그 함수와 기능이 동일하다고 볼 수 있겠네요

f(x, y) = x + y
f(1, 3) = 4
#inlcude <iostream>
using namespace std;

int sum(int x, int y){
	return x + y;
}

int main(){
	cout << sum(1, 3) << "\n"; // 4
	return 0;
}

Method (메소드)

The working of the method is similar to a function i.e. it also can have input parameters/arguments and can also return data by having a return type but has two important differences when compared to a function.

Method explain in Geeks for Geeks

메소드는 함수와 기능적인 측면으로는 거의 유사합니다.
하지만 두 가지 주요한 차이점이 존재 합니다...!!!

  1. 메소드는 정의된 클래스의 객체와 연관되어 있다.
  2. 메서드는 메서드가 포함된 클래스 내의 데이터에서 작동하는 것으로 제한된다.

위와 같은 차이점이 발생하는 이유는 객체지향 언어라는 특성 때문입니다.

Function 함수Method 메소드
본인의 이름으로 또는 독립적으로 호출된다객체의 이름이나 레퍼런스(참조)를 통해서 호출된다
독립적으로 호출되므로 데이터가 명시적 또는 외부적으로 전달됨을 의미함데이터가 암묵적으로 또는 내부적으로 전달됨을 의미하는 종속적으로 호출됩니다.

간단한 절댓값 예제로 함수와 메소드의 차이점을 한 번 살펴보겠습니다.

C 언어 sum 함수

#include <stdio.h>  
int sum(int a, int b) {
	return a + b;
}
int main(){  
	int a = 45;
	int b = 55;
	printf("%d\n", sum(a, b));  // 100
	
	return 0;  
}

Java sum 메소드

public class Sum {
	int a;
	int b;

	public Sum(int a, int b){
		this.a = a;
		this.b = b;
	}

	public int getResult(){
		return a + b;
	}
}


public class Main {
	
	public static void main(String[] args) {  
	
	Sum s = new Sum(45, 55); 
	
	System.out.println(s.getResult()); // 100
	
	}  
}

위에서 보시는 것과 같이 Function(함수)라는 용어를 사용하는 C언어에서는 사용하고자 하는 함수가 속해 있는 헤더 파일을 추가한 다음 함수의 이름을 호출하는 것 만으로도 해당 함수를 사용할 수 있습니다.

그에 반해 자바는 s.getResult() 와 같이 객체를 통해서 메소드를 호출해야 합니다.

그렇다면 왜 이런 객체 지향과는 밀접한 자바는 왜 완전한 객체지향 언어가 아닐까요??


객체 지향 프로그래밍

객체 지향 프로그래밍(영어: Object-Oriented Programming, OOP)은 컴퓨터 프로그래밍의 패러다임 중 하나이다. 객체 지향 프로그래밍은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립된 단위, 즉 "객체"들의 모임으로 파악하고자 하는 것이다. 각각의 객체는 메시지를 주고받고, 데이터를 처리할 수 있다.

[위키 백과 - 객체 지향 프로그래밍](https://ko.wikipedia.org/wiki/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D)

순수객체지향(Purely Object Oriented)

순수한 객체 지향 언어는 다음의 7가지 특성을 모두 만족해야 합니다.

  1. Abstraction / 추상화
  2. Encapsulation / 캡슐화
  3. Inheritance / 상속
  4. Polymorphism / 다형성
  5. All predefined types are objects / 모든 사전에 정의된 타입은 객체여야 함
  6. All operations performed on objects must be only through methods exposed at the objects. / 객체에 대해서 수행되는 모든 작업은 반드시 객체의 메소드를 통해서만 이루어 져야 함
  7. All user-defined types are objects. / 모든 사용자가 정의한 타입은 객체여야 함

그리고 위와 같은 특성들을 모두 만족 하는 순수 객체지향 언어 스몰토크(SmallTalk) 라고 합니다

스몰토크(Smalltalk)는 동적 형반영을 지원하는 객체 지향 프로그래밍 언어이다.

위키 백과 - 스몰토크

현재까지도 유일한 순수 객체 지향 언어라고도 불리며 최초의 GUI를 제공하는 언어였으며, 이후 Objective-C, Java, Scratch 등 많은 언어에 영향을 미친 언어입니다.

그럼 자바는...

자바는 크게 3가지 이유로 Java 는 순수한 객체지향 언어가 아닙니다.

Primitive type (원시타입)

자바에는 int, long, bool, float, char, short 와 같은 원시 타입이 다수 존재합니다.
이들은 객체가 아니지만, 우리가 선언한 타입이 아니기 때문에 위의 조건들 중 5번을 만족시키지 못합니다.

스몰토크는 정수, char 이러한 모든 자료형이 객체입니다...!!
그에 반해 자바는 아니죠

Static 키워드의 존재

static 키워드를 사용하면 객체를 명시적으로 만들지 않고도 메소드를 사용할 수 있습니다.

public class Main {  
	public static void main(String[] args) {  
	int a = 1;  
	int b = -2;  
	System.out.println(Math.abs(a) + ", " + Math.abs(b)); // 1, 2 
	}  
}

위와 같이 static 메소드인 absMath 클래스의 내부에 위치해 있지만, static 메소드로 선언된 덕분에 별도의 명시적인 객체 생성 없이 메소드의 사용이 가능합니다.

Wrapper 클래스

원시 자료형을 감싸 주는 Wrapper 클래스이지만, 우리는 Wrapper 클래스를 다음과 같이 사용할 수 있죠

Integer a = 12;
Integer b = 13;
Integer c = a + b;

어디가 문제일까요??

바로 + 연산자의 사용 때문입니다.
기준 6번을 다시 보면 객체 간의 연산은 객체의 메소드를 통해서만 이루어져야 합니다.
하지만 우리는 원시 타입과 같이 Wrapper 클래스 또한 내부 메소드를 통해서 뿐만 아니라 수리 연산자를 통한 연산도 가능하다는 사실을 알고 있습니다.

Integer 라는 Wrapper 클래스는 내부적으로 int로 연산을 하기 때문이죠

Integer class

Number class

Wrapper 클래스라고 할지라도, 연산의 순간에는 Auto Boxing/UnBoxing을 통해 연산을 하기 때문에 +-/* 와 같은 수리 연산자를 통해서도 연산이 가능합니다.

이는 개발자에게는 매우 편한 기능이죠

하지만 객체지향적으로 보면 순수한 객체지향 언어가 되기에는 기준에 미달되게 됩니다.

하지만 순수한 객체지향이 정말 좋은걸까요??

굳이.... 순수 객체지향??

Wrapper 클래스와 다르게 원시 타입을 사용하면 메모리도 덜 사용하고 속도도 더 빠릅니다.
그리고 굳이 가장 많이 사용하는 자료형들을 객체로 만들면서 까지 속도의 이득을 포기할 이유도 없어 보이죠...

위에서 계속 예시로 들었던 스몰토크는 1972년 발표되어, 1980년 마지막 버전이 발표되었죠

웹 개발시 REST의 모든 원칙을 지키기 보다는 RESTful 방식으로 부분적으로 원칙을 고수하면서 개발을 진행합니다.
REST의 모든 원칙을 고수하면서 개발하기에는 정말 어려운 뿐더러, 굳이 이렇게 까지 해야하나...??
라는 생각이 들 수도 있으니까요.

저는 순수 객체 지향과 같이 하나의 방향만을 고수하는 것 보다는 여러 패러다임의 다양한 장점을 섞어서 개발자의 편의성 + 개발 효율성 + 성능 모두를 잡는 것이 더 좋다고 생각합니다.

Java 언어를 만들 때도 위와 같이 여러 요소들을 생각해서 유연하게 만든 것이라고 생각이 드네요

곧 자바 21이 출시됩니다.
이에 따라 위와 같은 짤들이 돌아다니기 시작했는데요

기존에 객체지향을 지향하고 있던 자바에서 사용자의 편의성이 어느 정도 강화된 것 같아서 신기했습니다.

더욱이 순수객체지향에서는 더욱 멀어졌지만.... 오히려 좋은 것 같기도 하고요.

출처

What is the difference between a method and a function?
Difference Between Function and Method

Why Java is not 100% Object-Oriented?
# Why Java is not a purely Object-Oriented Language?

profile
어제보다 더 나은 개발자가 되고파요

1개의 댓글

comment-user-thumbnail
2023년 6월 24일

책 '소트웍스 앤솔러지'의 객체지향 생활 체조 원칙에

'모든 원시값과 문자열을 포장한다.'

라는 문장이 있는데, 이 부분이 Java가 Primitive Type 으로 인해 객체 지향을 지키지 못하는 부분을 보완하는 것이었음을 깨닫네요. 포스팅 잘 읽었습니다 :)

답글 달기