ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 자바 객체지향
    자바 2021. 3. 12. 14:12

    객체지향이론의 기본 개념

    실제 세계는 사물(객체)로 이루어져 있으며, 발생하는 모든 사건들은 사물간의 상호작용이라는 것이다.

     

    실제 사물의 속성과 기능을 분석한 다음, 데이터(변수)와 함수로 정의함으로써 실제 세계를 컴퓨터 속에 옮겨 놓은 것과 같은 가상세계를 구현하고 이 가상세계에서 모의실험을 함으로써 많은 시간과 비용을 절약할 수 있다.

     

    객체지향언어의 특징

    코드의 재사용성이 높다.

    새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.

    코드의 관리가 용이하다.

    코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경할 수 있다.

    신뢰성이 높은 프로그래밍을 가능하게 한다.

    제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지할 수 있다.

     

    클래스

    정의

    클래스란 객체를 정의해 놓은 것, 객체의 설계도 또는 틀

    용도

    클래스는 객체를 생성하는데 사용된다.

     

    객체

    정의

    실제로 존재하는 것, 사물 또는 개념, 클래스에 정의된 내용대로 메모리에 생성된 것을 뜻한다.

    용도

    객체가 가지고 있는 기능과 속성에 따라 다름

     

    클래스와 객체의 관계는 제품 설계도와 제품과의 관계와 같다.

    클래스는 객체를 생성하는데 사용될 뿐, 객체 그 자체는 아니다. 우리가 원하는 기능의 객체를 사용하기 위해서는 먼저 클래스로부터 객체를 생성하는 과정이 선행되어야 한다. 우리는 tv가 필요한거지 tv설계도가 필요한것이 아니다.

    클래스를 통해 객체를 생성하는 이유는 하나의 설계도만 잘 만들어 놓으면 제품을 만드는 일이 쉬어지기 때문이다.

     

    인스턴스

    객체와 같은 의미이지만 어떤 클래스로부터 만들어진 것인지를 강조하는 보다 구체적인 의미이다.

    ex) 책상은 객체다, 책상은 책상 클래스의 인스턴스이다.

    클래스 ---> 인스턴스(객체)

        (인스턴스화)

     

    객체의 구성요소(속성,기능 -> 멤버)

    속성

    멤버변수, 특성 , 필드, 상태

    기능

    메서드, 함수, 행위

    클래스에는 객체의 모든 속성과 기능이 정의 되어있다.

     

    인스턴스와 참조변수의 관계는 마치 우리가 일상생활에서 사용하는 TV와 리모콘의 관계와 같다.

    리모콘을 사용해서 TV를 다루기 때문, 그리고 TV,에어컨 등 해당 제품에 맞는 리몬콘을 사용해야하듯이 TV인스턴스를 사용하려면 TV클래스의 참조변수가 필요하다.

     

    객체배열

    참조변수들을 하나로 묶은 참조변수 배열

    ex) Tv tv1, tv2, tv3; -> Tv[] tvArr = new Tv[3];

    객체 배열을 생성하는 것은, 그저 객체를 다루기 위한 참조변수들이 만들어진 것일 뿐, 아직 객체가 저장되지 않았다.

    객체를 생성해서 객체 배열의 각 요소에 저장하는 것을 잊으면 안 된다.

    tvArr[0] = new Tv();

    tvArr[1] = new Tv();

    tvArr[2] = new Tv();

     

    클래스

    서로 관련된 변수들을 정의하고 이들에 대한 작업을 수행하는 함수들을 함께 정의한 것이 바로 클래스다.

    객체지향언어에서는 제어자와 메서드를 이용해 값들에 대한 조건을 코드에 쉽게 반영이 가능하다.

    public class Time {
    
        private int hour;
        private int minute;
        private float second;
        
        public void setHour(int h) {
        	if(h<0 || h>23) return;
            hour = h;
        }
        
        public void setMinute(int m) {
        	if(m<0 || m>59) return;
            minute = m;
        }
        
        public void setSecond(float s) {
        	if(s<0.0f || s>59.99f) return;
            second = s;
        }
    }

    제어자를 이용해서 변수의 값을 직접 변경하지 못하도록 하였다 대신 메서드를 통해서 값을 변경하도록 작성하였다.

    값을 변경할 때 지정된 값의 유효성을 조건문으로 점검한 다음에 유효한 값일 경우에만 변경한다.

     

    변수

    멤버변수 

    클래스 영역에 선언된다. 인스턴스변수는 인스턴스가 생성될 때마다 생성되므로 인스턴스마다 각기 다른 값을 유지하지만, 클래스 변수는 모든 인스턴스가 하나의 저장공간을 공유하므로, 항상 공통된 값을 가진다.

    클래스변수

    앞에 static이 붙어있으며 클래스가 메모리에 올라갈 때 생성이 된다. 모든 인스턴스가 공통된 저장공간(변수)을 공유하게 된다. 한 클래스의 모든 인스턴스들이 공통적인 값을 유지해야하는 속성의 경우, 클래스변수로 선언해야 하며 인스턴스를 생성하지 않고도 사용이 가능하다.

    인스턴스변수

    인스턴스가 생성되었을 때 생성 된다. 인스턴스는 독립적인 저장공간을 가지므로 서로 다른 값을 가질 수 있다.

     

    지역변수

    클래스 영역 이외에 영역(메서드, 생성자, 초기화 블럭 내부)에 선언되고 변수 선언문이 수행되었을때 생성이 된다.

     

    메서드 사용의 이점

    높은 재사용성

    한번 만들어 놓은 메서드는 몇번이고 호출할 수 있으며, 다른 프로그램에서도 사용이 가능하다.

    중복된 코드의 제거

    반복되는 문장들을 묶어서 하나의 메서드로 작성해 놓으면, 반복되는 문장들 대신 메서드를 호출하는 한 문장으로 대체할 수 있다.

    프로그램의 구조화

     

    main메서드는 프로그램의 전체 흐름이 한눈에 들어올 정도로 단순하게 구조화하는 것이 좋다.

    처음에 프로그램을 설계할 때 내용이 없는 메서드를 작업단위로 만들어 놓고, 하나씩 완성해가는 것도 프로그램을 구조화하는 좋은 방법이다.

     

    메서드를 호출할때 괄호()안에 지정해준 값들을 인자(argument) 또는 인수라고 한다.

     

    statice메서드는 같은 클래스 내의 인스턴스 메서드를 호출할 수 없다.

     

    메서드의 구현부{}를 작성할 때, 제일 먼저 해야 하는 일이 매개변수의 값이 적절한 것인지 확인하는 것이다.

    적절하지 않은 값이 매개변수를 통해 넘어온다면 매개변수의 값을 보정하던가, 보정하는 것이 불가능하다면 return문을 사용해서 작업을 중단하고 호출한 메서드로 되돌아가야한다.

    float divate(int x, int y) {
        //작업을 하기 전에 나누는 수(y)가 0인지 확인한다.
        if(y==0) {
        	return 0; //매개변수가 유효하지 않으므로 메서드를 종료한다.
        }
        
        return x/ (float)y;
    }

     

    참조형매개변수

    타입이 참조형이면 인스턴스의 주소가 복사되기에 값을 읽어 오는 것을 물론 값을 변경하는 것도 가능하다.

    public static void main(String[] args) {
      Data d = new Data();
      d.x = 10;
      System.out.println(d.x);
    
      change(d.x);
      System.out.println(d.x);
    
      static void change(int x) {
      x = 1000;
      System.out.println(x);
      }
    }

    여기서 d.x의 값이 변경된 것이 아니라, change메서드의 매개변수 x의 값이 변경된 것이다.

    즉 원본이 아닌 복사본이 변경된 것. 이처럼 기본형 매개변수는 변수에 저장된 값만 읽을 수만 있을 뿐 변경이 안된다.

     

    class Data {
    	int x;
    }
    
    	public static void main(String[] args) {
    		  Data d = new Data();
    		  d.x = 10;
    		  System.out.println(d.x);
    		  
    		  change(d);
    		  System.out.println(d.x);
    	}
    	
    	static void change(Data d) {
    		d.x = 1000;
    		System.out.println(d.x);
    	}

    change 메서드의 매개변수가 참조형이라서 값이 아니라 '값이 저장된 주소'를 change메서드에서 넘겨주었기 때문에 값을 읽어오는 것뿐만 아니라 변경하는 것도 가능하다.

     

    	public static void main(String[] args) {
    		int[] x = new int[]{10}; //크기가 1인 배열. x[0] = 10;
    		System.out.println(x[0]);
    		
    		change(x);
    		System.out.println(x[0]);
    	}
    	
    	static void change(int[] x) { //참조형 매개변수
    		x[0] = 1000;
    		System.out.println(x[0]);
    	}

    배열도 객체와 같이 참조변수를 통해 데이터가 저장된 공간에 접근하기에 같은 결과를 얻는다

    임시적으로 간단히 처리할 때는 별도의 클래스를 선언하는 것보다 이처럼 배열을 이용할 수도 있다.

     

    int add(int a, int b) {
    	return a+b;
    }
    
    void add(int a, int b, int[] result) {
    	result[0] = a+b;
    }

    참조형 매개변수를 활용하면 반환값이 없어도 메서드의 실행결과를 얻어 올 수 있다.

    메서드는 단하나의 값만을 반환할 수 있지만 이것을 응용하면 여러 개의 값을 반환하는 것과 같은 효과를 얻을 수 있다.

     

    참조형 반환타입

    반환타입이 참조형이라는것은 메서드가 객체의 주소를 반환한다는 것을 의미한다.

    class Data {
    	int x;
    }
    
    	public static void main(String[] args) {
    		Data d = new Data();
    		d.x = 10;
    		
    		Data d2 = copy(d);
    		System.out.println(d.x);
    		System.out.println(d2.x);
    	}
    	
    	static Data copy(Data d) {
    		Data tmp = new Data();
    		tmp.x = d.x;
    		
    		return tmp;
    	}

    copy메서드 내에서 생성한 객체를 main메서드에서 사용할 수 있으려면, 이렇게 새로운 객체의 주소를 반환해줘야 한다.

     

    재귀호출

    public class Scan {
    
    	public static void main(String[] args) {
    		int result = factorial(4);
    		
    		System.out.println(result);
    	}
    	
    	static int factorial(int n) {
    		int result=0;
    		
    		if(n==1) {
    			result = 1;
    		} else {
    			result = n * factorial(n-1); //다시 메서드 자신을 호출한다.
    		}
    		return result;
    	}
    }

     

    클래스 메서드와 인스턴스 메서드

    인스턴스 메서드

    인스턴스 변수와 관련된 작업을 하는, 즉 메서드의 작업을 수행하는데 인스턴스 변수를 필요로 하는 메서드이다.

    클래스 메서드

    인스턴스와 관계없는 메서드이다.

    클래스 영역에 선언된 변수를 멤버변수라 한다. 멤버변수 중에 static이 붙은 것을 클래스변수(static변수), static이 붙지 않은 것은 인스턴스변수라 한다.

    멤버변수는 모두 통칭하는것

     

    1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용하는 것에 static을 붙인다.

    2. 클래스 변수는 인스턴스를 생성하지 않아도 사용할 수 있다.

    3. 클래스 메서드는 인스턴스 변수를 사용할 수 없다.

    4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.(매개변수만으로 작업할 경우)

     

    클래스 멤버와 인스턴스 멤버간의 참조와 호출

    클래스멤버가 인스턴스 멤버를 참조 또는 호출하고자 하는 경우에는 인스턴스를 생성해야 한다.

     

    오버로딩

    한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메서드가 있더라도 매개변수의 개수 또는 타입이 다르면, 같은 이름을 사용해서 메서드를 정의하는 것

    사용하는데에 있어 장점으로는 같은 이름을 지정함으로써 동일한 기능을 한다는것을 파악하기 쉽다는것과 메서드의 이름을 짓는데에 고민을 덜 수 있다.

     

    오버라이딩

    상속관계에 있는 조상클래스로부터 상속받은 메서드의 내용을 변경하는 것을 오버라이딩이라고 한다.

    메서드의 선언부틑 조상의 것과 완전히 일치해야한다

    - 이름, 매개변수, 반환타입 동일해야함

    - 접근 제어자는 조상 클래스의 메서드보다 좁은 범위로 변경 할 수 없다.

    - 조상 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.

    - 인스턴스메서드를 static메서드로 또는 그 반대로 변경할수없다.

    남궁성,『Java의 정석』,도우출판

    '자바' 카테고리의 다른 글

    자바 다형성(polymorphism)  (0) 2021.03.14
    접근 제어자  (0) 2021.03.14
    자바의 변수(variable)에 대해서  (0) 2021.03.10
    JVM(Java Virtual Machine)  (0) 2021.03.10
    어노테이션  (0) 2019.09.17
Designed by Tistory.