[7주차] 자바 프로그래밍

Useful·2023년 5월 7일
0

Java

목록 보기
6/10
post-thumbnail

4. 클래스와 객체


먼저, Java뿐 아니라 객체 지향 언어를 배울 때 마다, 생기는 어려움이 객체(object)에 대한 이해 이다.

일상생활에서 볼 수 있는 객체(object)는 다음과 같다.

  • TV, 의자, 책, 집, 카메라, 컴퓨터, 노트북 등

    • 위에 있는 객체들은 자신만의 고유한 특성(state)행동(behavior)을 가진다.
    • 이 객체들은 다른 객체들에게 행동을 요청하거나 정보를 주고받는 등 상호 작용을 한다.





4-1. 객체지향 언어의 특성 3가지


  • 1. 캡슐화 (Encapsulation)

    • 객체를 캡슐로 싸서 내부를 보호하고 볼수 없게 하는 것, 객체의 가장 기본적인 특징.

    • 캡슐 약을 생각하면 이해하기 쉽다. 캡슐에 든 약은 어떤 색, 어떤 성분인지 보이지 않는다.

    • 객체는 캡슐화가 기본 원칙이지만, 외부와의 접속을 위해 몇부분만 공개 노출한다.

      • TV를 예로 들자면, TV의 내부 회로 기판에 대해서는 볼 수 없게 케이스로 쌓여 있다.
      • 그러나 TV의 전원버튼, 채널 버튼, 음량 버튼 등의 기능은 리모컨을 통해 접근이 가능하다.
      • 아래는 그에 대한 예제를 적어 보았다.
      public class TV {
          private int volume;		// 음량을 저장하는 변수
          private int channel;	// 채널을 저장하는 변수
          private boolean onOff;  // TV의 전원의 on/off 여부 저장 변수
      
          // TV의 전원을 켜고/끄는 메서드 setOnOff
          public void setOnOff (boolean onOff) {
              this.onOff = onOff;
      
              if(this.onOff) {
                  System.out.println("TV의 전원이 켜졌습니다.");
              } 
              else {
                  System.out.println("TV의 전원이 꺼졌습니다.");
              }
          }
      
          // TV의 채널을 설정하는 메서드 setChannel
          public void setChannel (int channel) {
              // TV의 전원이 ON 이면 채널 변경, OFF이면 전원이 꺼져있다고 메세지 출력
              if (onOff) {	
                  this.channel = channel;
                  System.out.println(this.channel + "번으로 이동합니다.");	
              } else {
                  System.out.println("전원이 꺼져있습니다.");
              }
          }
      
          // TV의 음량을 설정하는 메서드 setVolume
          public void setVolume (int volume) {
              // TV의 전원이 ON 이면 음량 변경, OFF이면 전원이 꺼져있다고 메세지 출력
              if (onOff) {
                  this.volume = volume;
                  System.out.println(this.volume + "음량으로 설정되었습니다.");	
              } else {
                  System.out.println("전원이 꺼져있습니다.");
              }
          }
      }
      
      public class CapsulationEx {
      
          public static void main(String[] args) {
              TV 리모컨 = new TV();
              리모컨.setOnOff(true);	// 먼저 전원을 켠다.
              리모컨.setChannel(10);	// 그리고 채널을 10번으로 바꾼다.
          }
      }



위에 private과 같은 접근지정자는 후에 서술할 예정입니다.

자바에서 객체는 클래스(class) 라는 캡슐을 사용하며,
그 안에는 필드(멤버 변수)메소드(멤버 함수) 로 구성된다.

/* 클래스의 구성은 다음과 같다.. */

public class Animal {	// <-- 필드와 메소드를 가지고 있는 클래스 Animal

	String name;		// ┐
	String gender;		// │ 이 부분이 필드(멤버 변수)
	int age;			// ┘
		
	void eat() {...}	// ┐
	void speak() {...}	// │ 이 부분이 메소드(멤버 함수)
	void sleep() {...}	// ┘
}



  • 2. 상속 (Inheritance)

    실세계에서 상속은 다음의 그림과 유사하다고 볼 수 있다.

  • But, 자바에서의 상속은 자식 클래스가 부모 클래스의 속성을 물려받고 기능을 추가하여
    확장(extends)을 한다는 개념이다.
  • 부모 클래스를 슈퍼 클래스 (super class), 자식 클래스를 서브 클래스(sub class) 라고 부른다.
  • 상속은 부모 클래스의 필드와 메소드를 물려 받아 코드를 재사용을 할 수 있다..!
  • 그 예시는 아래 코드에 나와 있다.
public class Animal {

	String name;		// ┐
	String gender;		// │ 이 부분이 필드(멤버 변수)
	int age;			// ┘
		
	void eat() {...}	// ┐
	void speak() {...}	// │ 이 부분이 메소드(멤버 함수)
	void sleep() {...}	// ┘
}

// Animal 클래스를 상속받은 Human 클래스
public class Human extends Animal {
	String hobby;
	String job;
    
	void work() {...}
	void cry() {...}
	void laugh() {...}
}

// Animal 클래스를 상속받은 Human 클래스의 구성요소는 다음과 같다 볼 수 있다.

	class Human {
      String name;			// ┐
      String gender;		// │ 상속받은 Animal 클래스의 필드
      int age;				// ┘
      void eat() {...}		// ┐
      void speak() {...}	// │ 상속받은 Animal 클래스의 메소드
      void sleep() {...}	// ┘
      -----------------------------------------------------------
      String hobby;			// ┐
      String job;			// │ 기존 Human 클래스가 가지고 있는 필드
	  String phNum;			// ┘
      
      void work() {...}		// ┐
      void cry() {...}		// │ 기존 Human 클래스가 가지고 있는 메소드
      void laugh() {...}    // ┘  	
    }



  • 3. 다형성 (Polymorphism)
    • 다형성은 같은 이름의 메소드가 클래스 혹은 객체에 따라 다르게 동작하도록 구현되는 것
    • 오버로딩(overloading)오버라이딩(overriding)이 이에 해당한다.
    • 그냥 개념만 알아두고, 다음에 오버로딩과 오버라이딩에 대해서 다음에 자세히 다루겠다.





4.2 클래스에 대해 자세히 알아보자..


그래서 클래스, 객체가 뭔가요

클래스는 객체를 만들어 내기 위한 설계도 혹은 틀
객체는 틀의 모양 즉, 클래스의 모양 그대로 생성된 실체가 객체.
그리고 객체를 클래스의 인스턴스(instance) 라고도 부른다.

클래스와 객체의 아주 좋은 예시로는 클래스(붕어빵틀)객체(붕어빵) 이 있습니다..!!

위 사진으로 알 수 있는 것은,

  • 붕어빵 틀은 클래스구나
  • 이 틀의 형태로 구워져서 나온 붕어빵이 바로 객체구나
  • 모양대로 만들어지지만 서로 조금씩 다르구나 (치즈, 크림, 단팥 등)
  • 뭐지 저 햄스터는 ?

또 다른 예시를 봅시다.

위의 예시로 알 수 있는 것은,

  • 객체들은 클래스의 모양대로 모두 동일한 속성을 가지고 있구나..!
  • 하지만 자신만의 고유한 값을 가지고 있구나
  • 속성은 전부 같지만, 속성의 값은 다르구나

라는 사실을 알 수 있습니다.




4.3 클래스를 선언하는 법


자바에서 클래스를 사용하는 것은 접근지정자 키워드와 함께 class 키워드를 사용해서 만든다.

/* 클래스의 구성도 */
접근지정자 class 클래스이름 {
	접근지정자 타입 멤버변수명;
    접근지정자 타입 멤버변수명2;
    
    접근지정자 반환타입 메소드이름 (매개변수...) {
        ...
    }
    접근지정자 반환타입 메소드이름2 (매개변수...) {
    	...
    }
}

/* 클래스의 예제 */

// 접근지정자 키워드 클래스명
//    👇     👇    👇
    public class Animal {
      // 필드(멤버변수) 부분
      private String name;
      private int age;

      // 메서드(멤버함수) 부분
      public int getAnimalAge() {
          return this.age;
      }

      public String getAnimalName() {
          return this.name;
      }
  }

다시 서술하지만 접근지정자(private, public 등)에 대해서는 후에 서술하니 넘어가도 된다.


4.3.1 클래스 인스턴스의 생성

위의 예제로, Animal 클래스와 그에 대한 인스턴스를 생성해보자

public static void main(String[] agrs) {
	/* 클래스 인스턴스의 생성 방법 */
    클래스명 레퍼런스변수명 = new 클래스명();
    
    /* Animal 클래스로 인스턴스 생성하기 */
    
	// 1. 아래는 클래스(붕어빵틀)의 객체(붕어빵)을 만들기 위해 레퍼런스 변수(animal)을 먼저 만들어준 모습이다.
	Animal animal;
    
    // 2. 그리고 new 연산자를 통해 인스턴스(객체)를 생성하고 animal 레퍼런스 변수에 만들어진 인스턴스(객체)를 집어넣는다.
    animal = new Animal();
    
    // 3. 클래스의 레퍼런스 변수선언과 인스턴스의 생성을 동시에 수행할 수 있고, 그 결과는 다음과 같다.
    Animal animal = new Animal();
}





4.4 메소드 (Method)


4.4.1 메소드란?

사전적 정의 : 어떤 특정 작업을 수행하기 위한 명령문의 집합

필자 본인이 쉽게 생각했을 때는 메소드는 함수인데, 클래스안에 들어가있는 함수를 메소드라 부르는거다.



4.4.2 메소드의 사용목적과 정의

메소드의 사용목적

  • 중복되는 코드의 반복적인 프로그래밍을 방지하기 위함
  • 모듈화로 인해 코드의 가독성이 좋아짐
  • 프로그램에 문제가 발생했을 때, 손쉬운 유지보수가 가능

메소드 정의

/* 메소드를 정의하는 법은 함수와 크게 다르지 않다. */
접근지정자 반환타입 메소드명(매개변수1, 매개변수2 ...) {
	...구현 하는 곳...
}

/* 다음 예제는 울음소리(sound)를 인자값으로 받아와 Animal클래스의 speak()메서드를 구현하는 예제이다. */
public void speak(String sound) {
	System.out.println("Animal is speaking..." + sound);
}



4.4.3 메소드 호출

위와 같이 메소드를 정의했다면 참조연산자( . ) 를 사용하여 호출할 수 있습니다.

다음 예제는 Animal 클래스의 speak() 메소드를 호출(사용)하는 예제입니다.


class Animal {
	int age;
	String name;
	
    // 울음소리(sound)를 인자값으로 받아서 출력하는 메소드 speak()
	public void speak(String sound) {
		System.out.println("Animal is speaking..." + sound);
	}
}

public class Main {
	public static void main(String args[]) {
		Animal animal = new Animal();	// Animal 클래스의 객체 생성
		animal.speak("멍멍!");		    // 객체 뒤에 . 을 사용하여 speak 메소드 호출
	}
}

// 실행결과 : Animal is speaking...멍멍!






4.5 생성자 (Constructor)


우리는 생성자에 대해 모르고 있었지만... 사실 이전에 몇번 생성자를 호출한 적이 있다.😶


해당 코드를 한번 살펴보자..

	Animal animal = new Animal();	// Animal 클래스의 객체 생성

위의 코드는 "그냥 평범하게 클래스의 객체를 생성하는 코드 아니야?" 라고 생각할 수 있다.


후후,, 하지만 다음 코드를 살펴보자

	new Animal(); <-- 해당 코드의 이 부분은 생성자를 호출하는 코드이다.



4.5.1 생성자..?

생성자는 인스턴스(객체)를 생성할 때 반드시 실행되고, 제일 먼저 호출되는 메소드이다.

생성자의 사용목적은 바로, 인스턴스 변수를 원하는 값으로 초기화 하기 위함이다.

  • 인스턴스 변수 는 아래 사진으로 이해하면 된다.



4.5.2 생성자 선언

생성자를 선언하려면, 다음과 같은 규칙을 따라야 한다.

  • 생성자는 해당 클래스 이름과 동일하여야 한다.
  • 생성자는 반환값이 없다. 그러나 반환값을 void로 선언하진 않는다.
  • 생성자는 초기화를 위한 데이터를 인수로 전달받을 수 있다.
  • 하나의 클래스는 여러개의 생성자를 가질 수 있다 (오버로딩)

여기서 잠시 !

  • 우리가 객체를 생성할 때, 클래스의 생성자도 호출된다고 했다.
  • 근데 우리는 생성자를 만든적이 없는데 어떻게 호출된거지..?😱

그 이유는, 우리가 생성자를 만들지 않으면 컴파일러가 기본 생성자(default Contructor)을 만들어준다..!!

class Animal {
	int age;
	String name;
    
    // public Animal() {}	<-- 2. 하지만 우리 눈에 보이진 않지만 JVM이 기본 생성자를 만들어놓는다.

	public void speak(String sound) {
		System.out.println("Animal is speaking..." + sound);
	}
}

public class Main {
	public static void main(String args[]) {
		Animal animal = new Animal();	// 1. 객체 생성과 동시에 생성자 호출.. 그러나 우린 생성자를 정의한적이 없다.
	}
}

고마워요 Java Compiler맨!


생성자 선언 방법

public 생성자명[클래스명과 동일해야함] (매개변수..) {...}
/* 매개변수가 없는 생성자 */
public Animal () {...}

/* 매개변수가 있는 생성자 */
public Animal (인수1, 인수2, ...) {...} 



이제 Animal 클래스에 생성자를 직접 추가해보자.

다음 예제는 생성자가 나이(age)와 이름(name)을 받아서 객체를 초기화 하고, 초기화된 값을 출력한다.

class Animal {
	int age;
	String name;
    
    // 생성자, 이름과 나이를 인수로 받고, 클래스의 멤버변수를 초기화 해준다.
    public Animal(int pAge, String pName) {
    	age = pAge;
        name = pName;
    }
    
    // 멤버변수를 출력하는 메소드 print()
    public void print() {
    	System.out.println("멤버변수 age의 값 : " + age);
        System.out.println("멤버변수 name의 값 : " + name);
    }
}

public class Main {
	public static void main(String args[]) {
    	// 객체 생성과 동시에 생성자에 나이(80)와 이름("장수거북이")를 인자값으로 넘기고 호출한다. 
		Animal animal = new Animal(80, "장수거북이");
        
        // 제대로 초기화 되었는지 확인한다.
        animal.print();
	}
}
// 실행 결과 : 멤버변수 age의 값 : 80
//            멤버변수 name의 값 : 장수거북이



4.5.3 위에 코드로 코드 진행 순서를 알아봅시다.

다음에 정리할 것은

  • 생성자와 오버라이딩
  • 오버로딩
  • 접근지정자

에 대해 정리하겠습니다.



감사합니다!






다음 자료를 참고하였습니다! 감사합니다😘
https://www.tcpschool.com/java/
https://blog.naver.com/heartflow89/220955879645

profile
1 commit = 1 life

0개의 댓글