JAVA의 철학과 객체지향언어

.·2022년 4월 3일
1

JAVA의 등장

JAVA는 1991년 썬 마이크로시스템즈의 제임스 고슬링에 의해 탄생한 객체 지향적 프로그래밍 언어이다. 처음에는 가전제품 내에 탑재해 동작하는 프로그램을 위해 개발 했지만 현재는 웹 어플리케이션 개발에 가장 많이 사용하는 언어 가운데 하나로 발전하였다.

JAVA는 다양한 네트워크 분산 환경에서 어플리케이션을 실행하기 위해 개발 되었다. 이러한 과제 중 가장 중요한 것은 최소한의 시스템 리소스를 사용하고 모든 하드웨어 및 소프트웨어 플랫폼에서 실행할 수 있으며 동적으로 확장 가능한 어플리케이션을 제공하는 것 이었다.

JAVA의 목표는 작고,신뢰할 수 있고,쉽게 이식할 수 있는 OS 플랫폼을 개발하는 것이었다. 처음 프로젝트를 시작할 때 전 세계적으로 C++가 주류 언어로 사용되고 있었지만 C++이 가지고 있던 어려움은 새로운 언어 플랫폼의 필요성을 느끼게 했다. JAVA는 SmallTalk, Objective C, Cedar/Mesa 등 다양한 언어에서 디자인과 구조를 가져와 객체 지향적인 언어로 설계되었다.

JAVA의 철학

Simple, Object Oriented, and Familiar

  • JAVA의 기본 개념은 쉽게 파악되고 처음 개발을 시작하는 개발자도 높은 생산성을 발휘할 수 있다.
  • 복잡한 네트워크 기반 환경에서 프로그래밍 시스템은 객체 지향 개념을 사용해야 한다. JAVA는 사용하기 쉽고 효율적은 객체 기반 개발 플랫폼을 제공한다.
  • C++의 복잡성을 제거하고 객체 지향 언어의 특징만을 가져왔기 때문에 C++에 익숙한 개발자는 쉽게 적응할 수 있다.

Robust and Secure

  • JAVA는 매우 신뢰할 수 있는 소프트웨어를 만들기 위해 설계되었다. 컴파일 타임 체킹, 런타임 체킹를 제공해 개발자가 신뢰할 수 있는 프로그래밍을 하도록 안내한다.
  • 네트워크 환경에서 Java 프로그래밍 언어로 작성된 어플리케이션은 백그라운드에서 바이러스를 만들거나 파일 시스템을 침입하려는 악성 코드에 의한 침입으로부터 보호된다.

Architecture Neutral and Portable

  • JAVA는 다양한 네트워크 환경에 도입되는 어플리케이션을 배포할 수 있도록 설계되었다.
  • JAVA 컴파일러는 다양한 하드웨어와 소프트웨어에 배포될 수 있도록 중립적인 포맷을 지닌 바이트 코드를 생성한다.
  • JVM은 컴파일러가 생성한 바이트 코드를 해석해 기계어로 바꾸어 실행한다.
  • JVM이 인터프리터가 되어서 같은 바이트코드를 가지고 여러 CPU에서 실행이 가능해진다.

High Performance

  • JAVA 플랫폼은 인터프리터가 런타임 환경을 확인할 필요 없이 최대 속도로 실행할 수 있는 방식을 채택해 실행 속도가 빠르다.
  • 가비지 컬렉터는 자동으로 실행되기 때문에 필요할 때 메모리 정리를 자동으로 해준다.

Interpreted, Threaded, and Dynamic

  • JAVA 인터프리터는 인터프리터 및 런타임 시스템이 존재하는 환경에서는 모두 자바 바이트 코드를 실행 할 수 있다.
  • JAVA 기술은 멀티스레딩 기능을 통해 여러개의 스레드를 동시에 사용하는 어플리케이션을 구축할 수 있도록 도와준다.
  • java 컴파일러는 컴파일 시 정적 체킹를 제공하지만, 언어와 런타임 시스템은 링크 단계에서 동적 체킹을 제공한다.

객체지향언어

  • JAVA의 핵심 철학은 객체 지향 언어이다. 그렇다면 객체 지향 언어라는 말은 어디서 처음 등장했을까 ? 객체 지향의 시초는 1960년대 시작된 simula67이라는 언어이지만 처음에는 주목을 받지 못했다. 객체 지향 언어의 실질적인 시초는 앨런 케이가 만든 SmallTalk라는 언어로 가장 순수한 객체 지향 언어로 만들어졌으며 현재에도 인정받고 있다.

객체 지향 프로그래밍

  • 객체 지향 프로그래밍이라는 용어는 시대가 지나면서 많은 사람들에 의해 사용되고 있으며 명확히 그 의미를 정의하기 어렵다. 객체 지향 프로그래밍의 실질적인 창시자인 앨런 케이와 스테픈 람이 주고 받은 이메일을 살펴보면 앨런 케이가 정의한 객체 지향 프로그래밍에 대해 알 수 있다.

OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things.

Dr. Alan Kay on the Meaning of "Object-Oriented Programming"

  • OOP의 핵심은 messaging, local retention, late-binding이다.
  • 앨런 케이와 스테픈 람이 주고 받은 이메일과 An Introduction To Object Oriented Programming 책에 나온 OOP에 대한 앨런 케이의 자세한 정의를 통해 해당 개념에 대해 자세히 알아보자.

local retention

"local retention" is a new notion to me in the context of OOP, and I assume it refers to state-process and means that an object is in possession of its state-process, so that the state of an object is kept locally with the object and not elsewhere.

Dr. Alan Kay on the Meaning of "Object-Oriented Programming"

  • 객체들은 자신의 상태,행동을 지닌다.
  • 상태는 외부로 노출되지 않으며 지역적으로 유지된다.

메세징

Computation is performed by objects communicating with each other, requesting that other objects perform actions. Objects communicate by sending and receiving messages. A message is a request for action bundled with whatever arguments may be necessary to complete the task.

  • 프로그램은 객체들이 메세지를 서로 주고 받으며 진행된다.
  • 메세지 : 행동에 대한 요청 + Task를 완료하기 위해 필요한 인자
  • 메세지란 객체가 특정 행동을 하도록 만들어준다.

동적 바인딩

Usually, the specific receiver for any given message will not be known until run time, so the determination of which method to invoke cannot be made until then. Thus, we say there is late binding between the message (function or procedure name) and the code fragment(method) used to respond to the message

An Introduction To Object Oriented Programming

  • 메세지를 받는 객체는 프로그램의 실행 시간이 되기 전까지 알 수 없다.
  • 해당 메세지를 수신해 어떤 함수가 실행될지 모른다.
  • 동적 바인딩이란 메세지와 메세지에 응답하는 함수가 프로그램이 실행될 때 연결되는 것을 의미한다.

JAVA가 지향하는 OOP

객체란 무엇인가?

  • 객체는 상태와 행동을 지니고 있는 소프트웨어 프로그래밍 모델이다.
  • 객체의 행동의 메서드에 의해 정의된다.
  • 객체의 메서드는 다른 객체가 인스턴스 변수에 접근하거나 변경할 수 있는 유일한 수단이다.

JAVA의 객체지향 프로그래밍

  • 객체지향 프로그래밍은 4가지 개념을 지원해야 한다.
  • 캡슐화 : 정보를 숨기고 모듈화 시킨다.
  • 동적 바인딩 : 객체는 어디에서나, 네트워크를 통해서도 올 수 있다. 개발자는 코드를 작성할 때 객체로 메세지를 보내면서 해당 객체의 특정한 타입을 알 필요 없다. 동적 바인딩은 프로그램 실행 시 엄청난 유연성을 제공한다.
  • 다형성 : 같은 메세지더라도 메세지를 전달받는 객체에 따라 행동이 달라진다.
  • 상속 : 코드 재사용 및 코드 조직화를 위해 기존 클래스를 기반으로 새롭게 정의할 수 있다.
  • 기존 앨런케이가 정의한 객체지향 프로그래밍에서 다형성, 상속이 추가되었다.

"polymorphism" was imposed much later (I think by Peter Wegner) and it isn't quite valid, since it really comes from the nomenclature of functions, and I wanted quite a bit more than functions. I made up a term "genericity" for dealing with generic behaviors in a quasi-algebraic form.

I didn't like the way Simula I or Simula 67 did inheritance though I thought Nygaard and Dahl were just tremendous thinkers and designers). So I decided to leave out inheritance as a built-in feature until I understood it better.

The second phase of this was to finally understand LISP and then using this understanding to make much nicer and smaller and more powerful and more late bound understructures.

Dr. Alan Kay on the Meaning of "Object-Oriented Programming"

하지만 2003년 앨런케이와 스테픈 람이 주고 받은 이메일을 살펴보면 앨런 케이는 다형성은 함수의 명명법에서 나온 것이기 때문에 객체지향의 핵심 개념으로는 타당하지 않으며 Simula의 상속을 좋아하지 않았기 때문에 LISP에 대한 이해를 통해 동적 바인딩을 만들었다.

앨런 케이가 지향한 객체 지향 프로그래밍과 자바에서 지향한 객체 지향 프로그래밍을 구분할 필요가 있으며 자바에서 생각하는 핵심 가치인 다형성과 상속은 결국 동적 바인딩을 더 잘 활용하기 위해 새롭게 도입된 개념이 아닌가 라는 생각이 든다.

문법

Class

  • 클래스는 특정 객체의 데이터(상태)와 메서드(행동)를 정의하는 소프트웨어 구조이다.
  • 클래스 자체는 객체가 아니며 객체가 어떻게 보이고, 어떤 행동을 할지 정의한 설계도이다.
class Point extends Object {
        
 private double  x;    /* instance variable  */
             
 private double  y;    /* instance variable  */
             

        Point() {    /* constructor to initialize to zero  */
        
            x = 0.0;
            y = 0.0;
        }
                    /* constructor to initialize to specific value  */
           
        Point(double x, double y) {
             
            this.x = x;
             
            this.y = y;
           
        }
          
        public void setX(double x) {    /* accessor method  */
           this.x = x;
        
        }
        public void setY(double y) {    /* accessor method  */
        
            this.y = y;
            
        }
          
        public double getX() {    /*  accessor method  */
          
            return x;
      
        }
          
        public double getY() {    /*  accessor method  */
            
            return y;
            
        }
           
    }

객체의 인스턴스화

Point  myPoint;           // declares a variable to refer to a Point object
myPoint = new Point();   // allocates an instance of  a Point object
  • Point 객체에 접근할 수 있는 주소값을 담을 변수 생성
  • 생성자를 통해 객체 생성
  • 인스턴스 :

메소드와 메세징

  • 객체가 다른 객체가 특정 행동을 수행하기 원할 때 첫번 째 객체는 두번 째 객체에게 메세지를 보내고, 두번 째 객체는 호출할 적절한 메서드를 선택한다.
  • 메세징은 다른 객체의 함수 호출을 통해 이루어진다.
myPoint.setX(10.0);      //  sets the x variable via the accessor method
myPoint.setY(25.7);

Subclasses

  • 서브 클래스는 기존 객체의 관점에서 새로운 확정 객체를 정의할 수 있는 매커니즘이다.
  • 기존에 정의된 Point를 상속받아 새로운 ThreePoint 클래서를 정의
class ThreePoint extends Point {
           
        protected double z;    /* the z coordinate of the point  */
            
        ThreePoint() {      /* default constructor  */
              
            x = 0.0;        /* initialize the coordinates  */
             
            y = 0.0;
             
            z = 0.0;
              
        }
             
        ThreePoint(double x, double y, double z) {/* specific constructor */
            
            this.x = x;        / *initialize the coordinates  */
              
            this.y = y;
              
            this.z = z;
             
        }
              
    }

Interface

  • 자바는 다중 상속은 개발자와 컴파일러 개발자에게 너무 많은 문제를 야기할 수 있기 때문에 단일 상속 모델을 채택했다.
  • 인터페이스는 이런 자바의 단일 상속 모델을 극복하기 위해 등장했다.
  • 인터페이스는 함수의 정의를 하지 않은 채 인자와 method만 정의한다.
  • 클래스는 인터페이스를 implements를 통해 다양한 인터페이스를 정의할 수 있다.

Class Variables and Class Methods

  • 일반적으로 클래스에서 선언한 변수와 함수는 인스턴스 변수와 함수로 각각의 인스턴스마다 다른 값을 지닌다.
  • 클래스 변수와 함수는 클래스에서 인스턴스한 모든 개체에서 공유된다.
class Rectangle extends Object {
        
        static  final int version = 2;
            
        static  final int revision = 0;
             
    }

Abstract Method

  • 추상 메서드는 실제로 구현하지 않은 메서드이다.
  • 추상 슈퍼 클래스는 추상 메서드를 선언한 클래스이며 subclass가 이를 상속 받아 구현한다.
  • 추상 클래스는 일반적인 상태와 행동을 정의한다.

Dynamic Binding

  • Dynamic Binding은 late Binding과 같은 의미로 쓰인다.
  • Java Reference에는 동적 바인딩에 대한 예시가 따로 없어서 블로그 글에서 가져왔다.
class Human{
   //Overridden Method
   public void walk()
   {
       System.out.println("Human walks");
   }
}
class Demo extends Human{
   //Overriding Method
   public void walk(){
       System.out.println("Boy walks");
   }
}

class Test {
 public static void main( String args[]) {
       // Reference is of Human type and object is Boy type
       Human obj = new Demo();
       // Reference is of HUman type and object is of Human type.
       Human obj2 = new Human();
       obj.walk();
       obj2.walk();
   }
}

Boy walks
Human walks

  • JAVA에서는 오버라이딩을 상속 받은 클래스의 기능(함수)를 바꿀 수 있다.
  • 상속 : Human을 상속한 Demo 클래스에서는 오버라이딩을 통해 walk 함수를 재정의했다.
  • 메세징 : 테스트 클래스의 메인 함수에서 Human 참조변수의 함수 호출을 통해 각 참조 변수가 연결 되어 있는 객체들로 메세지를 보냄
  • 다형성 : Human 참조변수.walk()라는 같은 메세지를 전달 했지만 메세지를 전달 받는 객체 (Human, Demo)에 따라 다르게 행동
  • 동적 바인딩 : 프로그램이 실행될 때 obj 연결된 Demo 객체,obj2에 연결된 Human 객체와 Human 참조변수.walk()라는 메세지가 연결,

정리

  • JAVA를 사용하는 이유는 JAVA가 가지고 있는 객체지향언어의 특징, JVM을 통해 플랫폼에 독립적인 언어라는 점, 가비지 컬렉션을 통한 동적 메모리 관리의 효율성 3가지 때문이다.
  • 객체 지향 프로그래밍이란 상태와 행동을 지닌 객체들이 자신들의 상태를 외부에 노출하지 않은 채 메세지를 통해 프로그램 실행하는 것을 의미하며 동적 바인딩을 통해 유연성을 지닌다.
  • JAVA는 캡슐화, 동적바인딩, 다형성, 상속을 통해 객체지향 프로그래밍을 지원한다.
  • 다형성과 상속은 동적바인딩을 구현하기 위한 수단이다.
  • 다양한 환경에서 배포될 수 있도록 자바는 컴파일러를 통해 바이트 코드를 생성하고 각 환경에 설치된 JVM이 바이트코들르 기계어로 해석해 실행한다.
  • JVM은 가비지 컬렉션을 통해 동적 메모리의 할당과 해제를 자동으로 해준다.

Reference

profile
지금부터 공부하고 개발한것들을 꾸준하게 기록하자.

0개의 댓글