JAVA/개념

[JAVA] 05. OOP 1(객체 지향 언어)

밍글링글링 2017. 8. 1.
728x90

2.1 클래스와 객체의 정의와 용도

- 클래스의 정의 - 클래스란 객체를 정의해 놓은 것이다.

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

 

- 객체의 정의 - 실제로 존재하는 것. 사물 또는 개념

- 객체의 용도 - 객체의 속성과 기능에 따라 다름.

 클래스  객체
 제품 설계도  제품
 TV설계도  TV
 붕어빵기계  붕어빵

 

2.2 객체와 인스턴스

▶ 객체 ≒ 인스턴스

- 객체(object)는 인스턴스(instance)를 포함하는 일반적인 의미

 

책상은 인스턴스다.    책상은 책상 클래스의 객체다.

책상은 객체다.          책상은 책상 클래스의 인스턴스다.

 

▶ 인스턴스화(instantiate, 인스턴스化)

- 클래스로부터 인스턴스를 생성하는 것

클래스 instantiate 인스턴스(객체)

 

2.3 객체의 구성요소 - 속성과 기능

▶ 객체는 속성과 기능으로 이루어져 있다.

- 객체는 속성과 기능의 집합이며, 속성과 기능을 객체의 멤버(member, 구성요소)라고 한다.

▶ 속성은 변수로, 기능은 메서드로 정의한다.

- 클래스를 정의할 때 객체의 속성은 변수로, 기능은 메서드로 정의한다.

 

 속성  크기, 길이, 높이, 색상, 볼륨, 채널 등
 기능  켜기, 끄기, 볼륨 높이기, 볼륨 낮추기, 채널 높이기 등
class Tv{
    String color; //색깔
    boolean power; //전원상태(on/off)
    int channel; //채널

    void power() { power = !power } //전원 on/off
    void channelUp{ channel++; } //채널 높이기
    void channelDown { channel--; } //채널 낮추기
}

 

2.4 인스턴스의 생성과 사용(1/4)

▶ 인스턴스의 생성방법

클래스명 참조변수명; //객체를 다루기 위한 참조변수 선언

참조변수명 = new 클래스명();

// 객체 생성 후, 생성된 객체의 주소를 참조변수에 저장

Tv t;
t = new Tv();

Tv t = new Tv();

 

2.4 인스턴스의 생성과 사용(2/4)

Tv t;
t = new Tv();
t.channel = 7;
t.channelDown();
System.out.println(t.channel);
 

 

2.4 인스턴스의 생성과 사용(3/4)

Tv t1 = new Tv();
Tv t2 = new Tv();
t2 = t1;
t1.channel = 7;
System.out.println(t1.channel);
System.out.println(t2.channel);
 

 

2.4 인스턴스의 생성과 사용(4/4)

(a) 하나의 인스턴스를 여러 개의 참조변수가 가리키는 경우(가능)

(b) 여러 개의 인스턴스를 하나의 참조변수가 가리키는 경우(불가능)

 

2.5 클래스의 또 다른 정의

1. 클래스 - 데이터와 함수의 결합

▶ 변수 - 하나의 데이터를 저장할 수 있는 공간

▶ 배열 - 같은 타입의 여러 데이터를 저장할 수 있는 공간

▶ 구조체 - 타입에 관계없이 서로 관련된 데이터들을 저장할 수 있는 공간

▶ 클래스 - 데이터와 함수의 결합(구조체 + 함수)

 

2. 클래스 - 사용자 정의 타입(User-defined type)

- 프로그래머가 직접 새로운 타입을 정의할 수 있다.

- 서로 관련된 값을 묶어서 하나의 타입으로 정의한다.

 

3.1 선언위치에 따른 변수의 종류

"변수의 선언위치가 변수의 종류와 범위(scope)을 결정한다."

class Time{
    int hour;
    int minute;
    int second;
}
 
 변수의 종류  선언위치  생성시기
 클래스변수  클래스 영역  클래스가 메모리에 올라갈 때
 인스턴스 변수  클래스 영역  인스턴스 생성시
 지역변수  메서드 영역 변수 선언문 수행시

 

▶ 인스턴스변수(instance variable)

- 각 인스턴스의 개별적인 저장공간, 인스턴스마다 다른 값 저장가능

- 인스턴스 생성 후, '참조변수.인스턴스변수명'으로 접근

▶ 클래스변수(class variable)

- 같은 클래스의 모든 인스턴스들이 공유하는 변수

- 클래스가 로딩될 때 생성되고 프로그램이 종료될 때 소멸

▶ 지역변수(local variable)

- 메서드 내에 선언되며, 메서드의 종료와 함께 소멸

- 조건문, 반복문의 블럭{} 내에 선언된 지역변수는 블럭을 벗어나면 소멸

 

3.2 클래스와 인스턴스변수

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

class Card{
    String kind; //무늬
    int number; //숫자

    static int width - 100; //폭
    static int height = 250; //높이
}
 

3.3 메서드(Method)

▶ 메서드란?

- 작업을 수행하기 위한 명령문의 집합

- 어떤 값을 입력받아서 처리하고 그 결과를 돌려준다.

(입력받는 값이 없을 수도 있고 결과를 돌려주지 않을 수도 있다.)

 

▶ 메서드의 장점과 작성지침

- 반복적인 코드를 줄이고 코드의 관리가 용이하다.

- 반복적으로 수행되는 여러 문장을 메서드로 작성한다.

- 하나의 메서드는 한 가지 기능만 수행하도록 작성하는 것이 좋다.

- 관련된 여러 문장을 메서드로 작성한다.

 

▶ 메서드를 정의하는 방법 - 클래스 영역에만 정의할 수 있음.

 

3.4 return문

▶ 메서드가 정상적으로 종료되는 경우

- 메서드의 블럭{]의 끝에 도달했을 때

- 메서드의 블럭{}을 수행 도중 return문을 만났을 때

 

▶ return문

- 현재 실행 중인 메서드를 종료하고 호출한 메서드로 되돌아간다.

1. 반환값이 없는 경우 - return문만 써주면 된다.

return;
 

2. 반환값이 있는 경우 - return문 뒤에 반환값을 지정해 주어야 한다.

return 반환값;
 

 

3.4 return문 - 주의사항

▶ 반환값이 있는 메서드는 모든 경우에 reuturn문이 있어야 한다.

(X)
int max(int a, int b){
    if(a>b)
        return a;
}
 
 
(O)
int max(int a, int b){
    if(a>b)
        return a;
    else
        return b;
}​

 

▶ return문의 개수는 최소화하는 것이 좋다.

int max(int a, int b){
    if(a>b)
        return a;
    else
        return b;
}

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

int max(int a, int b){
    int result = 0;
    if(a > b)
        result = a;
    else
        result =b;
    return result;
}
 

 

3.5 메서드의 호출

▶ 메서드의 호출방법

참조변수.메서드 이름();    //메서드에 선언된 매개변수가 없는 경우

참조변수.메서드 이름(값1, 값2, ...); //메서드에 선언된 매개변수가 있는 경우

class MyMath{
    long add(long a, long b){
        long result = a+b;
        return result;
        return a + b;
    }
}
 
3.6 JVM의 메모리 구조
 

참조: https://velog.io/@shin_stealer/%EC%9E%90%EB%B0%94%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0

 

 

3.6 JVM의 메모리 구조 - 호출스텍
 
▶ 호출스텍의 특징
- 메서드가 호출되면 수행에 필요한 메모리를 스텍에 할당받는다.
- 메서드가 수행을 마치면 사용했던 메모리를 반환한다.
- 호출스텍의 제일 위에 있는 메서드가 현재 실행중인 메서드다.
- 아래에 있는 메서드가 바로 위의 메서드를 호출한 메서드다.
class CallStatckTest{
    public static void main(String[] args){
        firstMethod();
    }

    static void firstMethod(){
        secondMethod();
    }

    static void secondMethod(){
        System.out.println("secondMethod()");
    }
}
 
 
3.7 기본형 매개변수와 참조형 매개변수
- 기본형 매개변수 - 변수의 값을 읽기만 할 수 있다.(ready only)
- 참조형 매개변수 - 변수의 값을 읽고 변경 할 수 있다.(read & write)
class Data { int x; }
class ParameterTest{
    public static void main(String[] args){

        Data d = new Data();
        d.x=10;
        System.out.println("main(): x= "+d.x);

        change(d.x);
        System.out.println("After change(d.x);")
        System.out.println("main() : x = " + d.x);
    }
        static void change(int x){
            x = 1000;
            System.out.println("change() : x = " + x);
    }
}
 
class Data { int x; }
class ParameterTest{
    public static void main(String[] args){

        Data d = new Data();
        d.x=10;
        System.out.println("main(): x= "+d.x);

        change(d);
        System.out.println("After change(d);")
        System.out.println("main() : x = " + d.x);
    }
        static void change(Data d){
            d.x = 1000;
            System.out.println("change() : d.x = " + d.x);
    }
}
 
 
3.9 클래스메서드(stack)메서드와 인스턴스메서드
▶ 인스턴스 메서드
- 인스턴스 생성 후, '참조변수.메서드이름()'으로 호출
- 인스턴스 변수나 인스턴스메서드와 관련된 작업을 하는 메서드
- 메서드 내에서 인스턴스변수 사용가능
 
▶ 클래스 메서드(stack메서드)
- 객체 생성 없이 '클래스이름.메서드이름()'으로 호출
- 인스턴스변수나 인스턴스메서드와 관련없는 작업을 하는 메서드
- 메서드 내에서 인스턴스변수 사용불가
- 메서드 내에서 인스턴스변수를 사용하지 않는다면 static을 붙이는 것을 고려한다.
class MyMath2{
    long a,b;

    long add(){ // 인스턴스 메서드
        return a+b;
    }

    static long add(long a, long b){ //클래스 메서드(static 메서드)
        return a+b;
    }
}    

class MyMathTest2{
    public static void main(String[] args){
        System.out.println(MyMath2.add(200L, 100L); //클래스메서드 호출
        MyMath2 mm = new MyMath2(); //인스턴스 생성
        mm.a = 200L;
        mm.b = 100L;
        System.out.println(mm.add()); //인스턴스메서드 호출
    }
}
 
 
3.10 멤버간의 참조와 호출(1/2) - 메서드의 호출
"같은 클래스의 멤버간에는 객체생성이나 참조변수 없이 참조할 수 있다. 그러나 static멤버들은 인스턴스멤버들을 참조할 수 없다."
 
class TestClass{
    void instanceMethod() {}  //인스턴스메서드
    static void staticmethod() {} //static메서드

    void instanceMethod2(){    //인스턴스메서드
        instanceMethod();; //다른 인스턴스메서드를 호출한다.
        staticMethod(); //static메서드를 호출한다.
    }

    static void staticMethod2(){ //static 메서드
        instanceMethod(); //에러!!! 인스턴스 메서드를 호출할 수 없다.
        staticMethod(); //static메서드는 호출할 수 있다.
    }
} //end of class
 
 
3.10 멤버간의 참조와 호출(2/2) - 변수의 접근
"같은 클래스의 멤버간에는 객체생성이나 참조변수 없이 참조할 수 있다. 그러나 static멤버들은 인스턴스멤버들을 참조할 수 없다."
class TestClass2{
    int iv; //인스턴스변수
    static int cv; //클래스변수

    void instanceMethod(){    //인스턴스메서드
        System.out.println(iv); //인스턴스변수를 사용할 수 있다.
        System.out.println(cv); //클래스변수를 사용할 수 있다.
    }

    static void staticMethod(){ //static 메서드
        System.out.println(iv); //에러!!! 인스턴스 변수를 사용할 수 없다.
        System.out..println(cv); //클래스변수를 사용할 수 잇다.
    }
} //end of class
 
 
 
4.1 메서드 오버로딩(Method overloading)이란?
"하나의 클래스에 같은 이름의 메서드를 여러 개 정의하는 것을 메서드 오버로딩, 간단히 오버로딩이라고 한다."
 
* overload - vt.과적하다, 부담을 많이 지우다.
 
4.2 오버로딩의 조건
- 메서드의 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.
(리턴타입은 오버로딩을 구현하는데 아무런 영향을 주지 못한다.)
 
 
4.3 오버로딩의 예(1/3)
▶ System.out.println메서드
- 다양하게 오버로딩된 메서드를 제공함으로써 모든 변수를 출력할 수 있도록 설계
 
void println()
void println(boolean x)
void println(char x)
void println(char[] x)
void println(double x)
void println(float x)
void println(int x)
void println(long x)
void println(Object x)
void println(String x)
 
4.3 오버로딩의 예(2/3)
▶ 매개변수의 이름이 다른 것은 오버로딩이 아니다.
 
[보기1]
int add(int a, int b) { return a+b;}
int add(int x, int y) { return x+y;}
 
 
▶ 리턴타입은 오버로딩의 성립조건이 아니다.
 
[보기2]
int add(int a, int b){ return a+b; }
long add(int a, int b){ return (long)(a+b); }
 
 
4.3 오버로딩의 예(3/3)
▶ 매개변수의 타입이 다르므로 오버로딩이 성립한다.
 
[보기3]
long add(int a, long b){ return a+b; }
long add(long a, int b){ return a+b; }
 
 
▶ 오버로딩의 올바른 예 - 매개변수는 다르지만 같은 의미의 기능수행
 
[보기4]
int add(int a, int b){ return a+b; }
long add(long a, long b){ return a+b; }
int add(int[] a){
    int result = 0;
    
    for(int i=0; i < a.length; i++){
        result += a[i];    
    }
    return result;
}​

 

5.1 생성자(constructor)란?

▶ 생성자란?
- 인스턴스가 생성될 때마다 호출되는 "인스턴스 초기화 메서드"
- 인스턴스 변수의 초기화 또는 인스턴스 생성시 수행할 작업에 사용
- 몇가지 조건을 제외하고는 메서드와 같다.
- 모든 클래스에는 반드시 하나 이상의 생성자가 잇어야 한다.
 
* 인스턴스 초기화 - 인스턴스 변수에 적절한 값을 저장하는 것.
Card c = new Card();

1. 연산자가 new에 의해서 메모리(heap)에 Card클래스의 인스턴스가 생성된다.
2. 생성자 Card()가 호출되어 수행한다.
3. 연산자 new의 결과로, 생성된 Card인스턴스의 주소가 반환되어 참조변수 c에 저장한다.
 
 
5.2 생성자의 조건
▶ 생성자의 조건
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴타입이 없다.
클래스이름(타입 변수명, 타입 변수명, ...){
    //인스턴스 생성시 수행될 코드
    //주로 인스턴스 변수의 초기화 코드를 적는다.
}
class Card{
    ...
    Card(){ //매개변수가 없는 생성자
        //인스턴스 초기화 작업
    }
    Card(String kind , int number){ //매개변수가 잇는 생성자
        //인스턴스 초기화 작업
    }
}
 
 
 
5.3 기본 생성자(default constructor)
▶ 기본 생성자란?
- 매개변수와 내용 없는 생성자
- 클래스에 생성자가 하나도 없으면 컴파일러가 기본 생성자를 추가한다.
(생성자가 하나라도 있으면 컴파일러는 기본 생성자를 추가하지 않는다.)
 
클래스이름() { }
CardA(0 { } // 컴파일러에 의해 추가된 Card클래스의 기본 생성자, 내용이 없다.

" 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다."
class Data1{
    int value;
}

class Data1{
    int value;
    Data1() {} //기본 생성자
}

class Data2{
    int value;
    Data2(int x){ 
        value = x;
    }
}

class ConstrucTest{
    public static void main(String[] args){
        Data1 d1 = new Data1();
        Data2 d2 = new Data2(); //compile error발생
    }
}
 
 
5.4 매개변수가 있는 생성자
class Car {
    String color:
    String geartype;
    int door;

    Car() {]
    Car(String c, String g, int d){ //생성자
        color = c;
        gearType = g;
        door = d;
    }
}
Car c = new Car();
c.color = "white";
c.gearType = "auto";
c.door = 4;

Car c = new Car("white", "auto", 4);
 
 
 
 
 
5.5 생성자에서 다른 생성자 호출하기 = this()
▶ this() - 생성자, 같은 클래스의 다른 생성자를 호출할 대 사용
다른 생성자 호출은 생성자의 첫 문장에서만 가능
 
class Car{
    String color;
    String gearType;
    int door;

    Car(){
        color = "white";
        gearType = "auto";
        door = 4;
    }
*코드의 재사용성을 높인 코드    ▼

    Car(){
        //Card("white", "auto", 4);
        this("white", "auto", 4);
    }

    Car(String c, String g, int d){
        color = c;
        gearType = g;
        door = d;
    }

    Car(){
        door = 5;
        this("white", "auto", 4);
    }
}
 
 
 
5.6 참조변수 this
▶ this - 인스턴스 자신을 가르키는 참조변수, 인스턴스의 주소가 저장되어있음
모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재
 
class Car{
    String color;
    String gearType;
    int door;

    Card(){
        // Card("white", "auto", 4);
        this("white", "auto", 4);
    }
    
    Card(String c, String g, int d){
        color = c;
        gearType = g;
        door = d;
    }

    *인스턴스변수와 지역변수를 구별하기 위해 참조변수 this사용▼

    Car(String color, String gearType, int door){
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }
}
 
 
5.7 생성자를 이용한 인스턴스의 복사
- 인스턴스간의 차이는 인스턴스변수의 값 뿐 나머지는 동일하다.
- 생성자에서 참조변수를 매개변수로 받아서 인스턴스변수들의 값을 복사한다.
- 똑같은 속성값을 갖는 독립적인 인스턴스가 하나 더 만들어진다.
 
class Car{
    String color; //색상
    String gearType; //변속기 종류 - auto(자동), manual(수동)
    int door; //문의 개수

    Car(){
        this("white", "auto", 4);
    }

    Car(String color, String gearType, int door){
        this.color = color;
        this.gearType = gearType;
        this.door =door;
    }

    Car(Car c){
        color = c.color;
        gearType = c.gearType;
        door = c.door;
    }
                      ▼
    Car(Car c){
        this(c.color, c.gearType, c.door);
    }
    
    class CarTest3{
        public static void main(String[] args){
            Car c1 = new Car();
            Car c2 = new Car(c1); //Car(Car c)를 호출
        }
    }
 
 
6.1 변수의 초기화
- 변수를 선언하고 처음으로 값을 저장하는 것
- 멤버변수(인스턴스변수 ,클래스변수)와 배열은 각 타입의 기본값으로 자동 초기화되므로 초기화를 생략할 수 있다.
- 지역변수는 사용전에 꼭!!! 초기화를 해주어야한다.
 
class InitTest{
    int x; //인스턴스변수
    int y = x; //인스턴스변수

    void method1(){
        int i; //지역변수
        int 3 =i; //컴파일 에러!!! 지역변수를 초기화하지 않고 사용했음.
    }
}
 
6.1 변수의 초기화 - 예시
 
선언예 설명
int i=10;
int j=10;
int형 변수 i를 선언하고 10으로 초기화한다.
int형 변수 j를 선언하고 10으로 초기화한다.
int i=10, j=10; 같은 타입의 변수는 콤마(,)를 사용해서 함께 선언하거나 초기화할 수 있다.
int i=10, long j=0; 타입이 다른 변수는 함께 선언하거나 초기화할 수 없다.
int i=10;
int j=1;
변수 i에 저장된 값으로 변수 j를 초기화한다.
변수 j는 i의 값인 10으로 초기화 된다.
int j=i;
int i=10;
변수 i가 선언되기 전에 i를 사용할 수 없다.

  

class Test{
    int j= i;
    int i= 10; // 에러
}
            ▼
class Test{
    int i=10;
    int j=i; //Ok
}​
 
 
 
6.2 멤버변수의 초기화
▶ 멤버변수의 초기화 방법
1. 명시적 초기화(explicit initialization)
 
class Car{
    int door = 4;    //기본형(primitive type) 변수의 초기화
    Engine e = new Engine(); //참조형(reference type) 변수의 초기화

    /'/...
}
 
 
2. 생성자(constructor)
 
Car(String color, String gearType, int door){
    this.color = color;
    this.gearType = gearType;
    this.door = door;
}
 
 
3. 초기화 블럭(initialization block)
- 인스턴스 초기화 블럭: { }
- 클래스 초기화 블럭: static { }
 
 
6.3 초기화 블럭(initialization block)
- 인스턴스간의 차이는 인스턴스변수의 값 뿐 나머지는 동일하다.
- 생성자에서 참조변수를 매개변수로 받아서 인스턴스변수들의 값을 복사한다.
- 똑같은 속성값을 갖는 독립적인 인스턴스가 하나 더 만들어진다.
 
class Car{
    String color; //색상
    String gearType; //변속기 종류 - auto(저동), manual(수동)
    int door; // 문의 개수

    Car(){
        this("white", "auto", 4);
    }    
    Car(String color, String gearType, int door){
        this.color = color;
        this.gearType = gearType;
        this.door = door;
    }

    Car(Car c){ //인스턴스의 복사를 위한 생성자
        color = c.color;
        gearType = c.gearType;
        dopor = c.door;
    }
                               ▼
    Car(Car c){
        this(c.color, c.gearType, c.door);
    }
}

class CarTest3{
    public static void main(String[] args){
        Car c1 = new Car();
        Car c2 = new Car(c1);     //Car(Car c)를 호출
    }
}
 
 
6.4. 멤버 변수의 초기화 시기와 순서
▶ 클래스변수 초기화 시점: 클래스가 처음 로딩될 때 단 한번
▶ 인스턴스변수 초기화 시점: 인스턴스가 생성될 때 마다
 
class InitTest{
    static int cv = 1; //명시적 초기화
     int iv =1; //명시적 초기화

    static { cv=2; } //클래스 초기화 블럭
    { iv = 2; } //인스턴스 초기화 블럭

    InitTest(){ //생성자
        iv =3;
    }
}

InitTest it = new InitTest();
 
class Product{
    static int count=0; //생성된 인스턴스의 수를 저장하기 위한 변수
    int serialNo; //인스턴스 고유의 번호
    
    { //인스턴스 초기화 블럭: 모든 생성자에서 공통적으로 수행될 코드
        ++count;
        serialNo = count;
    }

    public Product(){}
}

class ProductTest{
    public static void main(String[] args){
        Product p1 = new Product();
        Product p2 = new Product();
        Product p3 = new product();

        System.out.println("p1의 제품번호 (serial no)는 "+p1.serialNo);
        System.out.println("p2의 제품번호 (serial no)는 "+p2.serialNo);
        System.out.println("p3의 제품번호 (serial no)는 "+p3.serialNo);
        System.out.println("생산된 제품의 수는 모두 " +Product.count+"개 입니다.");
    }    
}
 
 
"객체는 클래스없이 존재할 수 없다."
 
 
 
 

 

728x90

'JAVA > 개념' 카테고리의 다른 글

[JAVA] 06. OOP2(객체 지향 언어)  (0) 2017.08.01
[JAVA] 04. Array (배열)  (0) 2017.07.31
[JAVA] 03. 조건문, 반복문 (Control Statement)  (0) 2017.07.30
[JAVA] 02. 연산자(Operator)  (0) 2017.07.28
[JAVA] 01. 변수(Variable)  (1) 2017.07.28

댓글