본문 바로가기

Java

[Chapter07-2] 객체지향 프로그래밍1

01. 클래스의 구조


  • 클래스의 구조

Car car = new car( );

생성자: new 와 함께 초기화 -> 힙메모리에 객체를 생성 -> 메모리의 실제 주소값 반환

 

인스턴스 자신: this로 접근

인스턴스 부모: super로 접근

 

  • 필드란?

- 객체의 데이터, 상태를 저장하는 변수

- 주로 기본타입 또는 참조타입으로 정의

- 멤버변수라고도 함

 

 

02. 접근제한자


  • 접근제한자란?

- 객체의 필드와 메서드에 접근을 제한하기 위해 사용

- 정보 은닉을 위한 방법 (캡슐화)

- public > protected > default > private 네가지가 있다

 

https://po9357.github.io/java/2018-08-29-access_modifier/

  • 접근 제한자를 생략하면 default 제한자가 설정된다

 

03. 메서드


  • 매개변수

- 메서드를 선언할 때 괄호 안에 표현된 Input값을 나타내는 변수(type1 name1, type2 name2,...)

- 메서드 호출에서 들어가는 구체적인 값은 인자라고 함

 

  • 반환타입

- 메서드는 0개, 혹은 1개의 값을 Output으로 반환할 수 있음

- 반환 값이 없을 때: void

- 반환 값이 있을 때: int, boolean, Goods,....

- 반환 되는 값은 메서드 선언에서 정의된 반환 타입과 일치해야 함

 

  • 메서드 이름 -> Camel Case

- 자바의 식별자 규칙 대/소문자, 숫자, _, $ 조합을 지을 수 있고 숫자로 시작할 수 없다

- 관례에 따라 소문자로 작성, 두단어 조합시 두번재 시작문자는 대문자로 짓는다

- 메서드 명은 기능을 쉽게 알 수 있게 작성하는 게 좋다 (길어도 좋다)

 

04. 가변인수


가변인수란?

- 메소드의 매개 변수의 개수를 알 수 없을 때 사용

- 가장 간단한 해결방법은 매개변수를 배열로 선언

double sum(double[] values){}

- 이러한 경우, 메소드 호출시 배열을 넘겨주어 여러 개의 값을 전달 할 수 있다

double[] numbers = {1,2,3,4,5};
double result = sum(numbers);
double result = sum(new double[]{1,2,3,4,5});

 

- 방법2: 매개변수를 ...을 이용하여 선언

자동으로 배열이 생성되고 매개값으로 사용된다

double sum(double ... values){}
double result = sum(1,2,3,4,5);

 

05. Getter & Setter


  • Getter & Setter 사용이유

- 일반적으로 객체의 데이터는 객체 외부에서 직접적으로 접근하는 것을 막는다

- 객체의 외부에서 객체 내부의 데이터를 마음대로 읽고 쓸 경우 데이터의 무결성을 보장하기 힘들기 때문이다

- 메소드를 통한 접근을 하게 되면 객체의 데이터를 변경할 경우 무결성 체크를 할 수 있다

 

* 클래스를 정의할 때 필드는 private로 하여 객체 내부의 정보를 보호하고 필드에 대한 Setter와 Getter를 두어 객체의 값을 변경하고 참조하는 것이 좋다

 

  • Getter & Setter 특징

- 외부에서 읽기만 가능하게 하기 위해서 Getter만 해당 필드에 대해서만 작성하면 됨

- 외부에서 쓰기만 가능하게 하기 위해서 Setter만 해당 필드에 대해서만 작성하면 됨

- Getter와 Setter가 없으면 객체 내부 전용 변수가 된다

- 보통 Getter는 getXXX로 명명, 필드 타입이 boolean인 경우 isXXX로 명명하는 것이 관례

 

  • Getter & Setter 예시
public class Goods {
	// 필드
	private String name;
	private int price;
	
	// 외부 접근 방식 노출
	// getter/setter 
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getPrice() {
		return price;
	}
	
	public void setPrice(int price) {
		this.price = price;
	}
	
	public void showInfo() {
		System.out.println("상품명:" + name);
		System.out.println("가격: "+ price);
	}

 

 

06. 생성자


  • 생성자란?

- new 연산자와 같이 사용되어 클래스로부터 객체를 생성할 때 호출되고 객체의 초기화를 담당한다

- 생성자를 실행 시키지 않고 클래스로부터 객체를 만들 수 없다

- 생성자가 성공적으로 실행되면 JVM의 Heap영역에 객체가 생성되고 객체의 참조 값이 참조 변수에 저장된다

- 모든 클래스에는 반드시 하나 이상의 생성자가 있어야한다

 

없으면 기본생성자( )생성됨

 

  • 생성자의 정의

- 생성자의 이름은 클래스와 같아야 한다

- 생성자의 리턴 값은 없다 (하지만 void를 쓰지 않는다)

public class Goods {
    public Goods(){
    }
    
    public Goods(String name, int price){
    }
}

 

  • 기본 생성자

- 매개 변수가 없는 생성자

- 클래스에 생성자가 하나도 없으면 컴파일러가 기본 생성자를 추가한다

     //생성자를 선언하지 않으면 자바 컴파일러가 기본 생성자를 끼워 넣는다
     //생성자를 선언하면 컴파일러는 기본 생성자를 끼워넣지 않는다

 

- 생성자는 필요에 따라 여러 개 작성할 수 있다

 

07. this


  • 생성자에서 this란?

- this 키워드는 메서드 호출을 받는 객체를 의미

- 현재 사용중인 객체 그 자체를 의미

- this( )는 클래스의 한 생성자에서 다른 생성자를 호출할 때 사용할 수 있다

 

  • 생성자 this의 예시
public Goods(String name) {
		this.name = name;
	}
	
public Goods(String name, int price) {
		this(name); //다른 생성자 호출
		this.price = price;
	}

08. method overloading


- 각 메서드들은 매개변수 타입, 개수, 순서가 다른 형태로 구별된다

    * 메소드 시그니처: 메소드 인자의 타입, 개수, 순서

- 하나의 클래스에 같은 이름의 메서드가 여러개 존재할 수 있다

- 반환값이 다른 것은 오버로딩이 아니다

 

 

09. 변수의 종류


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

(1) 클래스(static) 변수

(2) 인스턴스 변수

(3) 지역변수

 

  • 변수의 범위 (Scope)

(1) 인스턴스 변수

  • 각 인스턴스의 개별적인 저장공간. 인스턴스 마다 다른 값 저장가능
  • 인스턴스 생성 후, ‘참조변수.인스턴스 변수명’으로 접근
  • 인스턴스를 생성할 때 생성되고, 참조변수가 없을 때 가비지 컬렉터에 의해 자동 제거됨

(2) 클래스(static) 변수

  • 같은 클래스의 모든 인스턴스들이 공유하는 변수
  • 인스턴스 생성없이 ‘클래스이름.클래스(스태틱)변수명’으로 접근
  • 클래스가 로딩될 때 생성되고 프로그램이 종료될 때 소멸

(3) 지역변수

  • 메소드 내에 선언되며, 메소드의 종료와 함께 소멸
  • 조건문, 반복문의 블럭{} 내에 선언된 지역변수는 블럭을 벗어나면 소멸

(4) 인스턴스 변수 와 클래스(static) 변수

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

* static 에서 instance호출 불가

* instance 에서 static 호출 가능

 

10. 클래스(static) 멤버


  • 클래스 멤버란?

- 전역 변수와 전역 함수를 만들 때 사용

- 모든 클래스에서 공유하는 전역 변수나 전역 함수를 만들어 사용할 수 있다

    - 클래스 멤버라고도 함

- 객체를 생성하지 않고 접근할 수 있다

- static 메서드 내에서는 this 사용 불가

- static 메서드 내에서는 static 멤버만 접근할 수 있다

- static 멤버의 초기화는 static 블록에서 할 수 있다 

    - static 블록은 클래스가 메모리에 로딩될 때 실행된다 

    - static 블록은 생성자보다 앞서 실행된다

 

  • static 멤버 -> 인스턴스 멤버 접근 불가능 
  • 인스턴스 멤버 -> static멤버 접근 가능

 

(static 멤버 예시)

package com.javaex.oop.staticmember;

public class StaticEx {
	public static int refCount; //클래스(static)멤버
	public static String classVar; //클래스 멤버
	public String instanceVar; //인스턴스 멤버
	
	// static 블록으로 static 영역의 초기화
	static {
		refCount = 0;
		classVar = "Static Memeber";
		//instanceVar = "Instance Member";
			//중요: static 영역에서는 static만 접근 가능
		System.out.println("Static Block");
	}
	
	// 생성자
	StaticEx(){
		//참조 카운트 증가
		//인스턴스 멤버 -> static 멤버 접근 가능
		refCount++;
		System.out.println("인스턴스 갯수:" + refCount);
		System.out.println("생성자 호출: 인스턴스 생성");
	}
}
package com.javaex.oop.staticmember;

public class StaticExApp {

	public static void main(String[] args) {
		StaticEx s1 = new StaticEx();
		//static 멤버는 new없이 접근 가능
		System.out.println("RefCount:" + StaticEx.refCount);
		
		StaticEx s2 = new StaticEx();
		//static 멤버는 new없이 접근 가능
		System.out.println("RefCount:" + StaticEx.refCount);
	}

}

 

11. Singleton Pattern


Design Pattern: 코드의 작성 패턴

 

- Singleton Pattern : 전체 프로그램 상에서 동일한 인스턴스를 사용해야 할 경우 활용

  • 어떠한 상황에서도 단 하나의 인스턴스만 유지한다 ("유일한 인스턴스 유지")
  • ex) 스마트폰의 주소록
static Singleton instance = new Singleton();

// 단 하나의 인스턴스 유지
  • singleton 객체의 예시
package com.javaex.oop.staticmember;

//목표: 어떤 상황에서든 단 한개의 인스턴스만 유지
public class Singleton {
	// static 블록에서 생성자를 호출
	private static Singleton instance = new Singleton();
	
	// 생성자
	private Singleton() {
		
	} 
	
	// getter
	public static Singleton getInstance() {
		return instance;
	}
	
	// getter
	
}
package com.javaex.oop.staticmember;

public class SingletonApp {

	public static void main(String[] args) {
		//Singleton s1 = new Singleton(); 
		Singleton s1 = Singleton.getInstance();
		Singleton s2 = Singleton.getInstance();
		
		// 객체 주소가 같으면 같은 객체이다
		System.out.println("s1, s2 같은 객체?" + (s1 == s2));
	}

}

 

12. 패키지(Package)


  • 패키지란?

- 서로 관련있는 클래스 또는 인터페이스들의 묶음

- 실제 저장 디렉토리를 명시한 것

 

  • 패키지 이용의 장점

- 클래스들을 묶음 단위로 제공하여 필요할 때만 사용 가능 (import문 이용)

- 클래스 이름의 혼란을 막고 충돌을 방지

- 패키지 단위의 접근 권한 지정 가능

 

  • 사용법

1) import 패키지명.클래스명(인터페이스명); // 지정된 클래스(인터페이스)만 불러옴

  • 예) import java.applet.Applet; // java.applet 패키지 내의 Applet을 불러옴 

2) import 패키지명.*; // 패키지 내의 모든 클래스(인터페이스)를 불러옴

  • 예) import java.io.*; // java.io 패키지 내 모든 클래스(인터페이스)를 불러옴

 

13. 상속


  • 상속이란?

- 부모 클래스에 정의된 필드와 메서드를 자식 클래스가 물려받는 것

 

  • 상속의 필요성

- 클래스 사이의 멤버 중복 선언 불필요

- 필드, 메서드 재사용으로 클래스가 간결

- 클래스간 계층적 분리 및 관리

 

  • 자바 언어 상속의 특징

- 다중 상속을 지원하지 않음

- 상속의 회수에 제한을 두지 않음

- 최상위 클래스는 java.lang.Object

- 상속이 깊어지면 유지보수가 어려워진다

 

  • 상속 선언의 예

 

  • 상속과 생성자

- 자식 생성자에서 특별한 지시가 없으면 부모 클래스의 기본 생성자가 선택된다 

- 부모 클래스의 특정 생성자를 호출해야 할 경우 super() 로 명시적으로 호출 

- 부모의 필드나 메서드에 접근시에는 super 키워드를 사용

 

  • 상속과 접근제한자

 

  • 메서드 오버라이딩

- 부모 클래스와 자식 클래스의 메서드 사이에서 발생하는 관계 

- 부모 클래스의 메서드를 동일한 이름으로 재 작성 

  • 같은 이름, 같은 리턴타입, 같은 시그너쳐
  • 메소드 시그니처: 메소드 인자의 타입, 개수, 순서

- 부모 클래스 메서드 무시하기 

- @Overriding

 

 

 

  • 자식 객체를 부모타입으로 참조할 수 있다(다형성)
Person p1 = new Student();

- Person에 해당하는 멤버변수, 메소드 사용 가능

- Student에서 Person 오버라이딩 한 메소드 사용가능

- Person에서 오버라이딩한 메소드 외 메소드는 사용 불가능 

 

 

  • super( ), super.

- super( ): 상속받은 부모 클래스의 생성자 호출

- super. : 상속받은 부모 멤버변수/메소드 호출

'Java' 카테고리의 다른 글

[Chapter11] 제네릭과 컬렉션  (0) 2021.12.08
[Chapter01]자바 언어 소개  (0) 2021.12.08
[Chapter07-1] 객체지향 프로그래밍1  (0) 2021.12.06
[Session] 세션 시간 및 연장 설정  (0) 2021.05.12
[간단한 for문] list  (0) 2021.04.30