본문 바로가기

Java/StudyNote

JAVA_07-1 #객체지향 프로그래밍 #클래스 #메소드 #상속

객체지향 프로그래밍이란?

 

프로그램 설계 방법론의 일종으로, 프로그램을 단순히 데이터와 처리 방법으로 나누는 것이 아니라, 프로그램을 수많은 '객체(object)'라는 기본 단위로 나누고 이들의 상호작용으로 서술하는 방식이다. 객체란 하나의 역할을 수행하는 '메소드와 변수(데이터)'의 묶음으로 봐야 한다.

 

https://namu.wiki/w/%EA%B0%9D%EC%B2%B4%20%EC%A7%80%ED%96%A5%20%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D

 


클래스

 

1. 객체 생성

- new : 객체를 생성할 때 사용하는 키워드

class Animal{
}

public class Sample_3039 {
    public static void main(String[] args) {
            // Animal 클래스의 인스턴스인 cat을 만듬 or Animal의 객체를 만듬
            Animal cat = new Animal();
        }
    }
}

 

- Animal의 인스턴스를 대량 생산(객체 지향 프로그래밍의 장점)

// 객체 대량 생산
Animal pig = new Animal();
Animal dog = new Animal();
Animal horse = new Animal();

 

 

2. 객체 변수 (Instance variable)

- 클래스에 선언된 변수를 객체 변수라고 한다. 다른 말로 인스턴스 변수, 멤버 변수, 속성 이라고도 함

- 객체 변수에 접근은 도트연산자(.)를 사용한다.

class Animal{
    // name 이라는 문자열 객체 변수 생성
    String name;
}

public class Sample_3039 {
    public static void main(String[] args) {
            // Animal 클래스의 인스턴스인 cat을 만듬 or Animal의 객체를 만듬
            Animal cat = new Animal();
            // cat.name으로 객체 변수에 접근
            System.out.println(cat.name);
        }
    }
}

 

 

3. 메소드

- 클래스 내에 구현된 함수를 의미, 자바에선 메소드라고 많이 부름

class Animal{
    // name 이라는 문자열 객체 변수 생성
    String name;
    /* name 에 값을 대입하기 위한 setName 메소드 추가
        입력: String name
        출력: void(리턴값 없음)
    */
    public void setName(String name) {
        this.name = name;
    }
}

public class Sample_3039 {
    public static void main(String[] args) {
            Animal cat = new Animal();
            // Animal 클래스에 추가한 setName 메소드를 호출해서 "boby" 를 입력 
            cat.setName("boby");
            System.out.println(cat.name);
        }
    }
}

 

 

4. 객체 변수는 공유되지 않는다.

- 클래스에서 가장 중요한 부분은 객체 변수의 값이 독립적으로 유지된다는 점이다.

- 객체 변수의 값은 공유되지 않지만 static을 이용하게 되면 객체 변수를 공유하도록 만들 수 있다.

class Animal{
    // name 이라는 문자열 객체 변수 생성
    String name;
    /* name 에 값을 대입하기 위한 setName 메소드 추가
        입력: String name
        출력: void(리턴값 없음)
    */
    public void setName(String name) {
        this.name = name;
    }
}

public class Sample_3039 {
    public static void main(String[] args) {
            Animal cat = new Animal();
            // Animal 클래스에 추가한 setName 메소드를 호출해서 "boby" 를 입력
            cat.setName("boby");
            System.out.println(cat.name);

            Animal dog = new Animal();
            dog.setName("happy");
            System.out.println(dog.name);
        }
    }
}

cat이라는 객체와 dog이라는 객체는 객체 변수 값이 독립적으로 유지되기 때문에 각각 boby와 happy가 출력된다.

 


메소드

파이썬에는 함수와 메소드를 구분해서 부르지만 자바는 클래스내에 함수가 존재할 수 밖에 없어서 이를 메소드라고 부름

 

1. 메소드를 사용하는 이유

- 반복되는 코드를 줄이기 위함

public class study_0311 {
    // sum 이라는 메소드는 int a, 와 int b라는 인자를 받고, a+b를 리턴
    int sum(int a, int b){
        return a+b;
    }

    public static void main(String[] args){
        int a = 3;
        int b = 4;

        study_0311 sample = new study_0311();
        int c = sample.sum(a, b);

        System.out.println(c); // 7 출력
    }
}

 

 

2. 매개변수와 인수

- 매개변수(parameter) 는 메소드에 입력으로 전달된 값을 받는 변수

- 인수(arguents) 는 메소드를 호출할 때 전달하는 입력 값

public class study_0311 {
    // sum 이라는 메소드는 int a, 와 int b라는 인자를 받고, a+b를 리턴
    int sum(int a, int b){  // a, b 는 매개변수
        return a+b;
    }

    public static void main(String[] args){
        int a = 3;  
        int b = 4;  // 3, 4 는 인수

        study_0311 sample = new study_0311();
        int c = sample.sum(a, b);   

        System.out.println(c); // 7 출력
    }
}

 

 

3. 메소드의 입력값과 리턴값

- 메소드의 구조

리턴자료형 메소드명(입력자료형1 매개변수1, 입력자료형2 매개변수2, ...) {
    ...    
    return 리턴값;  // 리턴자료형이 void 인 경우에는 return 문이 필요없다.
}

 

- 일반적인 메소드 : 입력 값이 있고 리턴값이 있는 메소드

int sum(int a, int b) {
    return a+b;
}

 

- 입력값이 없는 메소드 : 메소드를 호출할 때 리턴값만 반환

String say() {
    return "Hi";
}

 

- 리턴값이 없는 메소드 : 리턴값이 없는 메소드는 리턴타입 부분에 void 라고 표기한다.

void sum(int a, int b) {
    System.out.println(a+"과 "+b+"의 합은 "+(a+b)+"입니다."); // 리턴값이 아니라 단순히 문자열을 출력
}

 

- 입력값도 리턴값도 없는 메소드

void say() {
    System.out.println("Hi");
}

 

- 특별한 경우 메소드를 빠져나가기를 원할 때 return을 단독으로 사용하여 메소드를 즉시 빠져나갈 수 있다.

public class study_0311 {
    void sayNick(String nick){
        if("fool".equals(nick)){
            return; // 인자로 fool 이 들어오면 메소드는 아무 것도 없는 값을 return 하고 종료된다.
        }
        System.out.println("나의 별명은 " + nick + "입니다.");
    }
    public static void main(String[] args){
        study_0311 sample = new study_0311();
        sample.sayNick("angel"); // angel 출력
        sample.sayNick("fool"); // 메소드 종료
    }
}

 

- 메소드 내에서 선언된 변수의 효력 범위 : 메소드에서 사용되는 변수는 메소드 안에서만 쓰여진다. 메소드 내에서만 쓰이는 변수를 로컬 변수(local variable)라 한다.

 

 


Call by value

- 메소드로 객체를 전달할 경우 메소드에서 객체의 객체변수(속성) 값을 변경할 수 있다.

 

sample #01

// Updater 클래스, 매개변수로 숫자를 받고 +1 증가한다.
class Updater{
    void update(int count){
        count++;
    }
}

// Counter 클래스, 객체 변수 숫자 0인 count 를 갖는다.
class Counter{
    int count = 0; //객체 변수
}

public class Sample_0504 {
    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);
    }
}

실행 결과

-> Updater 클래스의 update 메소드는 Counter 클래스의 count 객체 변수(int 0)를 전달받았기 때문에 결과는 0이 된다.

 

 

sample #02

// Updater 클래스, 매개변수로 Counter 객체를 counter 로 받아 +1 증가한다.
class Updater{
    void update(Counter counter){
        counter.count++;
    }
}

// Counter 클래스, 객체 변수 숫자 0인 count 를 갖는다.
class Counter{
    int count = 0; //객체 변수
}

public class Sample_0504 {
    public static void main(String[] args){
        Counter myCounter = new Counter();
        System.out.println("before update:"+myCounter.count);
        Updater myUpdater = new Updater();
        myUpdater.update(myCounter);  // 객체를 update 메소드에 전달한다.
        System.out.println("after update:"+myCounter.count);
    }
}

실행 결과

 

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

 

 


상속(Inheritance)

- 자식 클래스가 부모 클래스의 기능을 그대로 물려받을 수 있는 상속 기능이 있다.

 

1. 상속

- 클래스 상속을 위해서는 extends 키워드를 사용한다.

// 문자열 name 을 setName 메소드로 전달받는다. 클래스의 name 객체변수는 전달받은 name 이 된다.
class Animal0505{
    String name;
    void setName(String name){
        this.name = name;
    }
}

// 클래스는 Animal0505를 상속받는다. 
class Dog0505 extends Animal0505{

}

public class Sample_0505 {
    public static void main(String[] args){
        Dog0505 dog = new Dog0505();
        dog.setName("poppy");   // 객체 dog 은 클래스 자체엔 메소드가 없지만 Animal0505를 상속받았기 때문에 setName 메소드를 상속받는다.
        System.out.println(dog.name);
    }
}

 

 

2. 부모 클래스의 기능 확장

- 부모 클래스를 상속받은 자식 클래스는 부모 클래스의 기능에 추가적인 기능을 갖도록 작성된다.

- 안그러면 상속하는 의미가 없..

// 문자열 name 을 setName 메소드로 전달받는다. 클래스의 name 객체변수는 전달받은 name 이 된다.
class Animal0505{
    String name;
    void setName(String name){
        this.name = name;
    }
}

// 클래스는 Animal0505를 상속받는다.
class Dog0505 extends Animal0505{
    void sleep(){
        System.out.println(this.name+" zzz");
    }
}

public class Sample_0505 {
    public static void main(String[] args){
        Dog0505 dog = new Dog0505();
        dog.setName("poppy");   // 객체 dog 은 클래스 자체엔 메소드가 없지만 Animal0505를 상속받았기 때문에 setName 메소드를 상속받는다.
        System.out.println(dog.name);
        dog.sleep();
    }
}

 

 

3. IS-A 관계

Dog 클래스는 Animal 클래스를 상속했다. Dog은 Animal의 하위 개념이고, 이 경우 "개는 동물이다."라고 표현 가능 하다. 자바에선 "Dog is a Animal" 과 같이 말할 수 있는 관계를 IS-A 관계라고 한다.  이렇게 상속관계에 있을 때 자식 클래스의 객체는 부모 클래스의 자료형처럼 사용할 수 있다. 

 

Animal0505 dog02 = new Dog0505(); // Dog0505 라는 자식 클래스 객체를 부모 클래스의 자료형 처럼 사용

Dog0505 dog03 = new Animal0505(); // 컴파일 오류, 부모 클래스로 만든 객체는 자식 클래스의 자료형으로 사용 불가

 

 

4. Object 클래스

- 자바에서 만드는 모든 클래스는 Object 클래스를 자동으로 상속받는다.

class Animal_O extends Object{
    String name;
    void setName(String name){
        this.name = name;
    }
}

 

 

5. 메소드 오버라이딩 (Method overriding)

// 문자열 name 을 setName 메소드로 전달받는다. 클래스의 name 객체변수는 전달받은 name 이 된다.
class Animal0505{
    String name;
    void setName(String name){
        this.name = name;
    }
}

// 클래스는 Animal0505를 상속받는다.
class Dog0505 extends Animal0505{
    void sleep(){
        System.out.println(this.name+" zzz");
    }
}

// 클래스는 Dog0505를 상속받는다. 
class HouseDog extends Dog0505{
    // 부모 클래스의 sleep 메소드를 자식 클래스가 동일한 형태로 구현하면 자식 클래스가 더 높은 우선순위를 갖게 된다.
    // 이를 메소드 오버라이딩 이라고 부른다.
    void sleep() {
        System.out.println(this.name + " zzz in house");
    }
}

public class Sample_0505 {
    public static void main(String[] args) {
        HouseDog houseDog = new HouseDog();
        houseDog.setName("happy");
        houseDog.sleep();
    }
}

-> HouseDog < Dog0505 < Animal0505 구조로 Dog0505 에도 sleep() 메소드가 있고, HouseDog 에도 sleep() 메소드가 있지만 HouseDog 이 Dog0505 보다 자식 클래스이기 때문에 HouseDog 의 sleep() 메소드가 실행된다. 이를 메소드 오버라이딩 이라 부른다.

 

 

6. 다중 상속

- 다중 상속은 클래스가 동시에 하나 이상의 클래스를 상속 받는 것을 뜻하고, C++, 파이썬 등 많은 언어들이 다중 상속을 지원하지만 자바는 다중 상속을 지원하지 않는다.

 

 

 


참고
https://wikidocs.net/book/31

 

점프 투 자바

**초보 프로그래머를 위한 자바 입문서** 이 책은 문법위주의 지식보다는 이해중심의 지식을 전달하는 것을 주 목적으로 한다. 예를 들어 자바에서 잘 파악하기 힘든 개념 ...

wikidocs.net

 

반응형