[TIL] PowerJava chap4 - 클래스와 객체 1

은동·2023년 1월 19일
0

JAVA_TIL

목록 보기
4/8
post-thumbnail

✔️ 객체 지향 프로그래밍

데이터와 함수를 하나의 덩어리로 묶어서 생각하는 방법

+) 절차 지향 프로그래밍 : 데이터와 함수를 분리해서 생각하는 방법

  • 객체 지향 프로그래밍의 특징 : 캡슐화, 상속, 다형성, 추상화

✔️ 캡슐화 (encapsulation)

이전에 작성된 코드들을 재사용할 수 있는 메커니즘이 필요하다 ❓

그렇다면 데이터와 알고리즘을 캡슐에 넣어서 하나의 묶음으로 보호하자 ❗️

  • 객체 (필드, 메소드) == 캡슐 (데이터, 알고리즘)

  • 캡슐화의 목적:

  1. 서로 관련된 데이터와 알고리즘을 하나로 묶는 것
  2. 객체를 캡슐로 싸서 객체의 내부를 보호하는 것(객체의 실제 구현 내용을 외부에 감추는 것 -> 외부 객체는 내부 데이터 값에 직접 접근할 수 없고, 메소드를 통해 간접적으로 값을 전달 받음)

✔️ 상속 (inheritance)

이미 작성된 클래스(부모 클래스)를 이어받아서 새로운 클래스(자식 클래스)를 작성하는 기법


✔️ 다형성 (polymorphism)

동일한 이름의 동작이라도 객체의 실제 타입에 따라서 동작의 내용이 달라질 수 있다는 것


✔️ 추상화 (abstraction)

불필요한 정보는 숨기고 중요한 정보만을 표현함으로써 프로그램을 간단하게 만드는 방법


✔️ 클래스 (class)

객체에 대한 설계도 (클래스 != 객체 , 클래스 -> 객체)

클래스로부터 만들어지는 각각의 객체를 인스턴스 (instance)라고 함

  • 작성
ex.1)

public class Circle {

	public int radius;
    public String color;	//필드
    
    publie double getArea(){	//메소드
    	return 3.14 * radius * radius;
        
}	

ex.2)

public class DeskLamp {
	
	private boolean isOn;
	
	public void turnOn() {
		isOn = true;
	}
	public void turnOff() {
		isOn = false;
	}
	public String toString()	{
		return "현재 상태는 " +(isOn == true? "켜짐":"꺼짐");
	}
	
}

클래스 안에 필드와 메소드를 정의
필드는 객체 안에 정의된 변수, 메소드는 클래스 안에 정의된 함수


  • 객체 생성
ex.1)

public class CircleTest {

	public static void main(String[] args) {
		Circle obj;		//1. 참조 변수 선언
		obj = new Circle();		//2. 객체 생성
		obj.radius = 100;
		obj.color = "blue";		//3. 객체의 필드 접근
		double area = obj.getArea()	;		//4. 객체 메소드 접근
		System.out.println("area of circle : "+ area);

	}

}

ex.2)

public class DeskLampTest {

	public static void main(String[] args) {
		
		DeskLamp myLamp = new DeskLamp();
		
		myLamp.turnOn();
		System.out.println(myLamp);
		myLamp.turnOff();
		System.out.println(myLamp);		

	}

}
  1. Circle obj;
    객체를 가리킬 수 있는 참조 변수만 생성됨, 객체 생성 X,
    +) c++에서는 위의 문장으로 객체가 생성됨

  2. obj = new Circle();
    new 연산자를 사용하여 객체를 생성하고 객체의 참조값을 참조 변수에 저장하는 단계

  3. obj.radius = 100;, obj.color = "blue";
    객체의 필드와 메소드를 사용하는 단계
    dot(.) 연산자를 사용


✔️ 참조 변수

객체를 참조할 때 사용되는 변수
여기에는 객체의 참조값이 저장됨(일반적으로 객체의 주소)


✔️ 메소드 오버로딩

같은 클래스 내에서 메소드의 이름이 같아도 파라미터의 개수가 다르면 여러 번 선언할 수 있는 것
(-> 동일한 이름의 메소드를 여러 번 정의하는 것)

public class MyMath {
	
	int add(int x, int y) {return x+y;}
	int add(int x, int y, int z) {return x+y+z;}
	int add(int x, int y, int z, int w) {return x+y+z+w;}

	public static void main(String[] args) {
		MyMath obj;
		obj = new MyMath();
		System.out.print(obj.add(10, 20)+" ");
		System.out.print(obj.add(10, 20, 30)+" ");
		System.out.print(obj.add(10, 20, 30, 40)+" ");

	}

}
  • 메소드의 반환형만 다르다면 메소드 오버로딩 불가
	int add (int x, int y)
	double add (int x, int y)
  • 다형성을 구현하는 방법 중 하나

✔️ 생성자

객체가 생성될 때 객체를 초기화하는 메소드

생성자도 오버로딩 가능

class Pizza{
	int size;
	String type;
	
	public Pizza() {	//파라미터가 없는 생성자
		size =12;
		type = "슈퍼슈프림";
	}
	public Pizza(int s, String t) {	 //파라미터가 있는 생성자
		size = s;
		type = t;
	}
}
public class PizzaTest {

	public static void main(String[] args) {
		Pizza obj1 = new Pizza();
		System.out.println("("+obj1.type+" , "+obj1.size+")");
		
		Pizza obj2 = new Pizza(24, "포테이토");
		System.out.println("("+obj2.type+" , "+obj2.size+")");

	}

}
  • 기본 생성자(default constructor)
    - 매개변수가 없는 생성자

    - 자동적으로 모든 멤버 변수들을 기본값으로 초기화 함
    int와 같은 수치형 변수 -> 0, 참조형 변수 -> null, 부울형 변수 -> false

    - 하지만 개발자가 생성자를 하나라도 선언하면, 컴파일러는 기본 생성자를 추가하지 않음

  • 이클립스 내의 생성자 자동으로 만들어주는 기능 :
    마우스 우클릭 -> Source -> Generate Constructor using Fields


✔️ this 참조 변수

- 현재 객체 자신을 가리키는 참조 변수
- 흔히 생성자에서 매개변수 이름과 필드 이름이 동일한 경우에 혼동을 막기 위해서 사용

public Circle(int radius){
	this.radius = radius;
}

=> 매개변수 radius를 필드 radius에 대입해라


✔️ this()

흔히 가장 복잡한 생성자를 먼저 작성한 후에, 다른 생성자가 이 복잡한 생성자를 호출하게끔 할 때 사용

  • 주의 사항
    - this()는 반드시 생성자 안에서만 호출이 가능
    - this()는 반드시 첫 번째 문장이어야 함
    - this()는 다른 생성자를 호출할 때만 사용하여야 함

✔️ 접근제어(access control), 접근 지정자

접근 제어 : 클래스의 멤버에 접근하는 것을 제어하는 것

이 때, public이나 private와 같은 접근 지정자를 이용하여 접근을 제한함, 멤버나 메소드 앞에 붙여서 접근을 제한

접근 지정자해당 클래스 안패키지자식 클래스전체
publicOOOO
protectedOOOX
privateOXXX
defaultOOXX

pubic : 누구나 자유롭게 접근 가능
private : 클래스 안에서만 접근 가능
portected : 부모 클래스와 자식 클래스만 접근 가능
default : 동일한 패키지 안에서만 접근 가능

  • 왜 접근 제어가 필요할까?
    - 접근을 제어하게 되면 객체를 잘못 사용하는 것을 방지할 수 있음
    - 올바르게 정의된 메소드만 데이터를 사용할 수 있게 하면 데이터의 값이 부적절한 값으로 변경되는 것을 막을 수 있음

  • 접근 제어를 선택하는 팁
    - 일반적으로 멤버에 대해서는 가장 엄격한 접근 제어를 선택, 특별한 이유가 없으면 private를 선택
    - 상수를 제외하고는 필드에 public을 선택하지 않도록 함


✔️ getter, setter

필드와 관련된 두 가지 종류의 메소드 getter, setter

ex.

접근자 : getBalance()
설정자 : setBalance()

보통 클래스 안에 변수를 선언할 때는 private를 붙여서 사용하는 것이 좋음 그러나 만약 클래스 안에 저장된 필드 값이 꼭 필요한 경우에는 어떤 특수 메소드가 데이터 값을 읽어 외부로 전달해주면 되는데 이 때 사용하는 메소드가 getter, setter 이다.


  • 왜 사용할까?
    - getter와 setter를 사용해야만 나중에 클래스를 업그레이드할 때 편함( ex. 주민등록번호를 나타내는 필드인 regNumber를 외부에서 마음대로 사용하고 있었다면 주민등록번호 대신에 아이핀을 사용하도록 변경하는 것이 불가능할 것)
    - getter에서 매개 변수를 통하여 잘못된 값이 넘어오는 경우, 이를 사전에 차단할 수 있음( ex. 시간의 값을 25시로 변경하려는 시도, 인간의 나이를 음수로 변경하려는 시도)
    - 필요할 때마다 필드값을 동적으로 계산하여 반환할 수 있음
    - getter만을 제공하면 자동적으로 가능한 필드를 만들 수 있음

  • 이클립스 내의 getter, setter 자동으로 만들어주는 기능

    마우스 우클릭 -> Source -> Generate Getters and Stters


✔️ 무엇을 클래스로 만들어야 할까?

'객체 지향' 사고 과정을 이해해야 함

요구 사항 문서화 -> 클래스 식별 -> 클래스가 저장해야 하는 데이터 결정 -> 클래스가 수행해야 하는 작업 식별 -> 클래스 간의 관계 결정

ex. 은행은 정기 예금 계좌와 보통 예금 계좌를 제공한다. 고객들은 자신의 계좌에 돈을 입금할 수 있으며 계좌에서 돈을 인출할 수 있다. 그리고 각 계좌는 기간에 따라 이자를 지급한다. 계좌마다 이자는 달라진다.

  1. 클래스 식별
    (문서에 등장하는 명사가 클래스의 후보)
    "은행", "정기 예금 계좌", "보통 예금 계좌", "고객", "계좌", "돈", "이자" 등
    여기에서 반드시 필요한 클래스만을 선별해야 함
    어떤 단어는 다른 단어의 별칭인 경우가 있음, 어떤 단어는 다른 단어의 속성인 경우가 있음, 어떤 단어는 다른 클래스의 인스턴스인 경우가 있음


  2. 클래스가 저장해야 하는 데이터 결정
    ex. Account 객체는 계좌번호와 잔고가 반드시 있어야 함
    ex. Client 객체는 이름이나 주소, 아이디 등의 속성을 가질 수 있음


  3. 클래스가 수행해야 하는 작업 식별
    ex. Bank클래스는 addAccount(), addClient()와 같은 작업이 필요


  4. 클래스 간의 관계 결정
    상속, 구성


✔️ UML(Unified Modeling Languege)

객체 지향 설계시에 사용되는 일반적인 모델링 언어

✔️ toString() 메소드

객체의 상태를 return하는 메소드

  • 이클립스 내의 toString()메소드를 자동으로 생성하는 기능
    마우스 우클릭 -> Source -> Generate toString()...

+) 177p 자동차 클래스 메소드 추가해보기

✔️ JFrame

자바에서 윈도우를 나타내는 클래스

import javax.swing.JFrame;

javax.swing 은 GUI에 관련된 클래스들을 모아 놓은 패키지임

JFrame f = new JFrame("Frame Test");	//화면에 윈도우 생성

f.setSize(300, 200);	// 윈도우 크기 설정 setSize(width, height)
f.setVisible(true);	// 윈도우를 나타나게 하거나 보이지 않게 함 setVisible(boolean b)
f.setLocation(200, 400);	//윈도우의 위치 변경 x축은 오른쪽으로 갈 수록 값이 증가하고, y축은 아래로 갈 수록 값이 증가함

new를 이용하여 객체를 생성하면서 생성자를 호출

profile
자자 선수입장~

0개의 댓글