OOP - Class, Method

5w31892p·2022년 12월 27일
0

Java

목록 보기
13/17

계산기 프로그램을 자바 코드로 구현했을 때,
계산할 것이 많아질수록 클래스를 추가하는 것이 아닌
아래와 같이 ca1, ca2를 생성하여 각 역할을 수행하게 한다.
ca1, cal2와 같은 것을 객체라고 한다.

Calculator cal1 = new Calculator();  // 계산기1 객체를 생성한다.
Calculator cal2 = new Calculator();  // 계산기2 객체를 생성한다.

:: 클래스

:: 객체

  • 선언만 되어 있는 껍데기 뿐인 클래스라도 아주 중요한 객체(Object)만드는 기능을 가지고 있다.
  • new는 객체를 생성할 때 사용하는 키워드다.
  • 이렇게 new를 통해 만들어진 객체를 instance 라고 한다.
  • 아래의 예로 보면 cat이 바로 Animal의 인스턴스이다.
  • dog, horse ... 등 많은 객체를 Animal 클래스로 만들 수 있다.
class Animal {
}
public class Sample {
    public static void main(String[] args) {
        Animal cat = new Animal();
        Animal dog = new Animal();
        Animal horse = new Animal();
    }
}

:: 객체 변수

  • 아래와 같이 클래스에 선언된 변수는 객체 변수라고 한다.
  • 객체 변수 == 인스턴스 변수 == 멤버 변수 == 속성
  • 객체 변수는 .(도트연산자)로 이용하여 접근한다.
class Animal {
	String name;
}
public class Sample {
    public static void main(String[] args) {
        Animal cat = new Animal();
        System.out.println(cat.name);
    }
} 

// null

:: 메서드

  • 함수이다.
  • 객체 변수에 값을 대입한다.
  • 아래에서 보면 setName이 메서드이다.
    • 입력 = String name
    • 출력 = void (return X)
  • 호출은 객체에서 한다.
  • this는 클래스에 의해 생성된 객체를 지칭
  • dog 객체가 있다면 this는 dog을 지칭하고, horse가 있다면 this는 horse를 지칭한다.
class Animal {
    String name;

    public void setName(String name) {
        this.name = name;
    }
}
public class Sample {
    public static void main(String[] args) {
        Animal cat = new Animal();
        cat.setName("야옹이");
        System.out.println(cat.name);
    }
}

// 야옹이

:: 객체 변수는 공유 놉!

  • 객체의 변수 값은 독립적으로 유지된다.
  • 객체지향적이라는 말도 결국 객체 변수 값이 독립적이기 때문에 가능하다.
  • 아래의 예를 보면 각각 대입한 이름이 나오고, 서로 영향을 주지 않는다.
Animal cat = new Animal();
cat.setName("야옹이");

Animal dog = new Animal();
dog.setName("멍멍이");

클래스에 의해! 생성된 것은 객체

클래스에 선언! 된 것은 객체 변수

객체에 값을 대입! 메서드


:: 메서드 (Method)

  • java는 클래스를 떠나 존재할 수 있는 것이 없어 함수도 따로 존재하지 않고 클래스 내에 존재한다.
  • 이렇게 클래스 내에 존재하는 함수를 메서드라고 한다.

    믹서기에 과일을 넣고 간다면
    -> 과일은 입력
    -> 과일 주스는 출력(return)
    -> 믹서기는 메서드

:: 메서드 사용 이유

  • 반복해서 사용하는 코드가 있을 것이고, 반복해서 사용한다는 것은 가치가 있다는 것이다.
  • 이럴 때 한뭉치로 묶어서 "입력값 주었을 때 리턴 값을 돌려준다"라는 식의 메서드를 작성하는 것이 현명한 것이다.
public class Sample {
    int sum(int a, int b) {
        return a + b;
    }
    public static void main(String[] args) {
        int a = 3;
        int b = 4;
        Sample sample = new Sample();
        int c = sample.sum(a,b);
        System.out.println(c);
    }
}

// 7

:: 매개변수와 인수

  • 매개변수 : 메서드에 입력으로 전달된 값을 받는 변수
  • 인수 : 메서드를 호출할 때 전달하는 입력 값
public class Sample {
    int sum(int a, int b) { // a와 b는 매개변수
        return a + b;
    }
    public static void main(String[] args) {
        Sample sample = new Sample();
        int c = sample.sum(3,4); // 3과 4는 인수
        System.out.println(c);
    }
}

매개변수 메서드에 전달된 값을 저장하는 변수
인수 메서드에 전달하는 값
소주병 == 매개변수 | 소주 == 인수

:: 메서드의 입력값과 리턴값

입력값 -> 메서드(블랙박스) -> 리턴값

메서드 구조

리턴자료형 메서드명 (입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
	....
    return 리턴값
}
// 리턴자료형이 void라면 return문 노필요

입력과 출력이 모두 있는 메서드 (일반적)

  • 입력값 : int a, int b
  • 리턴값 : int
  • 리턴값 받을 변수 = 객체.메서드명(입력인수1, 2 ...)
...
int sum(int a, int b) {
    return a+b;
}
...
Sample sample = new Sample();
int result = sample.sum(3, 4);

입력은 없고 출력은 있는 메서드

  • 입력값 : X
  • 리턴값 : String
  • 리턴값 받을 변수 = 객체.메서드명()
...
String say() {
    return "Hi";
...

Sample sample = new Sample();
String a = sample.say();
System.out.println(a);  // "Hi" 출력
}

입력은 있고 출력은 없는 메서드

  • 입력값 : int a, int b
  • 리턴값 : void
  • 객체.메서드명(입력인수1, 2, ...)
...
void sum(int a, int b) {
	System.out.println(a+"과 "+b+"의 합은 "+(a+b)+"입니다.");
...
Sample sample = new Sample();
sample.sum(3, 4);

// 3과 4의 합은 7입니다.

입력과 출력이 모두 없는 메서드

  • 입력값 : X
  • 리턴값 : void
  • 객체.메서드명()
...
void say() {
    System.out.println("Hi");
}
...
Sample sample = new Sample();
sample.say();

// Hi

정리해보자면
입력값이 있을 땐 입력 인수를 적고,
리턴값이 있을 땐 리턴값을 받을 변수를 적는다.

:: return의 또 다른 쓰임새

  • 메서드를 빠져나가고 싶을 때 return 단독 사용하여 즉시 빠져 나갈 수 있다.
  • 아래처럼 사용하는데 아래와 같은 경우는 fool이라는 값이 오면 빠져 나간다.
  • 단, void에서만 빠져나갈 수 있다.
void sayNick(String nick) {
    if ("fool".equals(nick)) {
            return;
    }
    System.out.println("나의 별명은 "+nick+" 입니다.");
}

:: 메서드 내에서 선언된 변수의 효력 범위

  • a 메서드의 매개변수명을 b 메서드에 똑같이 할 때 위에 있는 a 메서드가 void로 됐다면 b메서드의 값만 출력된다.
  • 하지만, return을 받는 자료형이거나 객체변수를 만들고 void 메서드 안에 클래스명을 적는 경우에는 먼저 선언된 값으로 대입되서 출력된다.

this 활용

void varTest(Sample sample) {
    sample.a++;
}
==
void varTest() {
    this.a++;
}

:: Call by value

  • 메서드에 값을 전달하는 것과 객체를 전달하는 것은 큰 차이가 있다.
  • 메서드에 객체를 전달하게 된다면 메서드의 객체의 객체변수 값을 변경할 수 있다.
class Updater {
    void update(int count) {
        count++;
    }
}
class Counter {
    int count = 0;  // 객체변수
}
public class Sample {
    public static void main(String[] args) {
        Counter myCounter = new Counter();
        System.out.println("before update:"+myCounter.count);
        Updater myUpdater = new Updater();
        myUpdater.update(myCounter.count);
        System.out.println("after update:"+myCounter.count);
    }
}

// before update:0
// after update:0
// 입력값 변경
...
void update(Counter counter) {
    counter.count++;
}
...
myUpdater.update(myCounter); // 객체 전달 받음
    System.out.println("after update:"+myCounter.count);
    
// after update:1

메서드 입력으로 객체 전달 받는 경우, 메서드가 입력받은 객체 그대로 사용하기 때문에 메서드가 객체의 속성값을 변경하면 메서드 수행 후에도 객체의 변경된 속성 값이 유지된다.

0개의 댓글