Home Java(객체지향)란?
Post
Cancel

Java(객체지향)란?


Java란?

자바는 C언어에 객체 지향적 기능을 추가하여 만든 C++과 달리, 처음부터 객체 지향 언어로 개발된 프로그래밍 언어이다. 자바는 자바 가상 머신(JVM, Java Virtual Machine)을 사용하여 운영체제와 독립적으로 동작할 수 있다. 따라서 자바는 어느 운영체제에서나 같은 형태로 실행 될 수 있다.


객체지향이란?

객체 지향 프로그래밍은 컴퓨터 프로그래밍 패러다임 중 하나로, 프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고 그 객체들 간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법이다.

컴퓨터로 예를 들어보자.
컴퓨터는 CPU, SSD, RAM 등등으로 이루어져 있다. 필자는 CPU와 RAM만으로 예를 들어보겠다.
아래와 같이 Computer와 Ram, Cpu를 모델링하였다. 각각의 class들을 객체라고 한다.

  • Computer.class
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    public class Computer {
      private String name; //컴퓨터명
      private Cpu cpu; //cpu
      private Ram ram;//ram
    	
      public Computer(String name, Cpu cpu, Ram ram) {
          super();
          this.name = name;
          this.cpu = cpu;
          this.ram = ram;
      }
      public void setCpu(Cpu cpu) {
          this.cpu = cpu;
      }
      public void setRam(Ram ram) {
          this.ram = ram;
      }
      public int speed() {
          return cpu.getSpeed()*ram.getStorage();
      }
      @Override
      public String toString() {
          return "Computer [name=" + name + ", cpu=" + cpu + ", ram=" + ram + "]";
      }
    }
    
  • Cpu.class
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    public class Cpu {
      private String model;//모델명
      private String version;//버전
      private int speed;//속도
    
      public Cpu(String model, String version, int speed) {
          super();
          this.model = model;
          this.version = version;
          this.speed = speed;
      }
    	
      public int getSpeed() {
          return speed;
      }
    	
      @Override
      public String toString() {
          return "Cpu [model=" + model + ", version=" + version + ", speed=" + speed + "]";
      }
    }
    
  • Ram.class
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    
    public class Ram {
      private String model;//모델명
      private String version;//버전
      private int storage;//용량
    	
      public Ram(String model, String version, int storage) {
          super();
          this.model = model;
          this.version = version;
          this.storage = storage;
      }
    	
      public int getStorage() {
          return storage;
      }
    
      @Override
      public String toString() {
          return "Ram [model=" + model + ", version=" + version + ", storage=" + storage + "]";
      }
    }
    

    Computer.class에 speed라는 메소드를 만들어놨다.

    1
    2
    3
    
    public int speed() {
      return cpu.getSpeed()*ram.getStorage();
    }
    

    간단하게 Cpu의 speed와 Ram의 storage를 곱하여 speed를 구하는 메소드이다. 아래와 같이 테스트 코드를 작성하였다.
    하나의 Cpu와 ram8 ram16객체를 생성하여 Computer객체에 각 부품들을 넣어 실행해주었다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    public class ComputerTest {
    	
      @Test
      void test() {
          Cpu cpu = new Cpu("A", "01", 100);
          Ram ram8 = new Ram("A", "01", 8);
          Ram ram16 = new Ram("A", "01", 16);
    		
          Computer computer = new Computer("A", cpu, ram8);
          System.out.println("RAM 8 Computer : "+computer.speed());
          computer.setRam(ram16);
          System.out.println("RAM 16 Computer : "+computer.speed());
      }
    }
    

    아래와 같이 출력이 되었다.
    Computer의 ram만 갈아 끼워주는 것 만으로 Computer의 속도가 다르게 출력된 것을 확인 할 수 있다.
    이런식으로 각 대상을 모델링하여 객체를 만들어주고 각 객체들을 유기적으로 상호작용하여 프로그래밍하는 것을 객체지향프로그래밍이라고 할 수 있다.

    1
    2
    
    RAM 8 Computer : 800
    RAM 16 Computer : 1600
    

객체지향의 특징

  • 캡슐화

    위 Computer예시코드를 보면 변수들은 private 접근제어자를 사용하고 변수를 set하거나 get할때 getter/setter함수를 만들어서 사용하고 있다.
    왜 그럴까?
    이유는 객체지향의 특징 캡슐화 떄문이다.
    캡슐화란 데이터와 코드의 형태를 외부로부터 알 수 없게 하고, 데이터의 구조와 역할, 기능을 하나의 캡슐 형태로 만드는 방법이다. (정보 은닉)

    캡슐화 방법

    1. 변수앞에 private 접근제어자를 사용한다.

      private
      본인 클래스 내부에서만 접근할 수 있는 접근제어자

    2. 멤버 변수에 값을 넣고 꺼내쓸 수 있는 메소드를 만든다.(Ex. Getter/Setter )

    위와 같은 캡슐화 방법을 따라서 Computer.class 객체를 생성한 것이다.

  • 추상화

    만약의 Desktop과 Notebook이 있다 두 제품은 똑같은 Cpu, Ram을 가지고 있지만 사용하는 법이 전혀 다를것이고 생김새도 다를 것이다.
    하지만 똑같은 Cpu, Ram을 사용하기에 성능에 있어서는 같은 성능을 발휘할 것이다.
    이런 공통적인 특정을 묶어서 표현하는 것을 추상화라고 한다.
    Ex)
    위 Computer를 추상클래스로 변경하였다.
    그리고 display라는 추상메소드를 만들었다.

    • Computer.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      
        public abstract class Computer {
            private String name; //컴퓨터명
            private Cpu cpu; //cpu
            private Ram ram;//ram
      			
            public Computer(String name, Cpu cpu, Ram ram) {
                super();
                this.name = name;
                this.cpu = cpu;
                this.ram = ram;
            }
            public void setCpu(Cpu cpu) {
                this.cpu = cpu;
            }
            public void setRam(Ram ram) {
                this.ram = ram;
            }
            public int speed() {
                return cpu.getSpeed()*ram.getStorage();
            }
      			
            public abstract void display();
      			
            @Override
            public String toString() {
                return "Computer [name=" + name + ", cpu=" + cpu + ", ram=" + ram + "]";
            }
        }
      
  • 상속화

    위에 Desktop과 NoteBook의 같은 기능과 성질을 Computer.class로 추상화하여 추상클래스를 구성하였다.
    상속화란 추상화된 추상클래스를 하위클래스에서 상속하여 사용하는 것을 의미한다.

    Ex)
    Desktop과 Notebook의 객체를 만들었다. Desktop과 Notebook은 Computer의 name, cpu, ram을 동일하게 사용하기 때문에 extends를 사용하여 Computer.class상속하였다.
    그리고 Desktop과 Notebook은 display의 기능이 다르기 떄문에 @Override하여 메소드를 각각 기능을 새로 구현하였다.

    • Desktop.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
        public class Desktop extends Computer{
            public Desktop(String name, Cpu cpu, Ram ram) {
                super(name, cpu, ram);
            }
      
            @Override
            public void display() {
                System.out.println("I'm Desktop, 성능 : "+speed());
            }
        }
      
    • Notebook.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
        public class Notebook extends Computer{
            public Notebook(String name, Cpu cpu, Ram ram) {
                super(name, cpu, ram);
            }
      
            @Override
            public void display() {
                System.out.println("I'm NoteBook, 성능 : "+speed());
            }
        }
      
    • Test.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      
        public class ComputerTest {
            @Test
            void test() {
                Cpu cpu = new Cpu("A", "01", 100);
                Ram ram8 = new Ram("A", "01", 8);
                Ram ram16 = new Ram("A", "01", 16);
      				
                Desktop computer = new Desktop("A", cpu, ram8);
                Notebook notebook = new Notebook("B", cpu, ram16);
      				
                computer.display();
                notebook.display();
      
                /* 출력결과
                I'm Desktop, 성능 : 800
                I'm NoteBook, 성능 : 1600 
                */
            }
        }
      

    테스트 했을 시 위와 같이 speed기능은 Computer.class의 메소드를 공통으로 그대로 사용하는 것에 반에 display()는 각 구성한 대로 출력되는 것을 확인할 수 있다.
    상속란 이런식으로 공통된 기능들은 하나로 묶어 class를 구성하고 공통기능을 사용하는 객체에 extends하여 사용하는 것이다.

  • 다형성

    예를들어 Desktop과 Notebook은 같은 Computer이지만 Desktop은 키보드, 마우스, 스피커를 따로 설치를 해야하는 방면, Notebook 하드웨어에 장착이 되어있기 때문에 따로 설치를 해줄 이유가 없다.
    이렇게 같은 기능이지만 객체의 상황에 따라 다른 또는 여러가지 형태를 띄우는 것을 다형성이라고 한다.

    Ex)
    아래와 같이 keyboard, mouse, speeker라는 메소드를 interface로 만들고
    Desktop.class, Notebook.class에 상속시켜줬다.
    상속하면 interface의 각 메소드들을 각 객체에 맞게 새로 커스텀하여 사용할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
      public interface ComputerFunction {
    		
          public void keyboard();
    		
          public void mouse();
    		
          public void speeker();
    
      }
    
    • Desktop.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      
        public class Desktop extends Computer implements ComputerFunction{
            public Desktop(String name, Cpu cpu, Ram ram) {
                super(name, cpu, ram);
            }
      
            @Override
            public void display() {
                System.out.println("I'm Desktop, 성능 : "+speed());
            }
      
            @Override
            public void keyboard() {
                System.out.println("keyboard not connected");
            }
      
            @Override
            public void mouse() {
                System.out.println("mouse not connected");
            }
      
            @Override
            public void speeker() {
                System.out.println("speeker not connected");
            }
        }
      
    • Notebook.class
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      
        public class Notebook extends Computer implements ComputerFunction{
            public Notebook(String name, Cpu cpu, Ram ram) {
                super(name, cpu, ram);
            }
      
            @Override
            public void display() {
                System.out.println("I'm NoteBook, 성능 : "+speed());
            }
            @Override
            public void keyboard() {
                System.out.println("keyboard connected");
            }
      
            @Override
            public void mouse() {
                System.out.println("mouse connected");
            }
      
            @Override
            public void speeker() {
                System.out.println("speeker connected");
            }
        }
      
This post is licensed under CC BY 4.0 by the author.
Contents