2022-01-12 객체2

GGAE99·2022년 1월 12일
0

진도

목록 보기
5/43

객체2다!

오늘은 객체에 대한 완전 이해를 목적으로 내용을 정리해보겠다!
객체는 설계도의 역할을 하는 클래스의 완제품이라고 생각하면 이해가 쉬울 것 같다.
객체라는 제품을 만들기 위하여, 클래스에 필요한 부분들을 추상화해준다.

TV를 예로 클래스를 만들어보자.

TV -> 속성 / 기능
속성 - > 크기 / 전원 / 볼륨 / 채널 / 등등
기능 -> 전원 on/off / 볼륨 조절 / 채널변경 / 유튜브 / 넷플릭스 등등

이렇게 TV라는 제품을 만들기위한 구성 요소들을 구성해놓는 작업이 추상화이다.
아직 이 클래스를 어떤 코드로 구성할지는 모르겠지만, 이런 것들이 구현됐으면 좋겠다고 미리 적어놓는다.

이렇게 추상화가 끝나면 객체지향프로그래밍 언어를 사용해 클래스를 작성해준다.
일단 속성을 표현해줄 변수들을 만들어보자.

구분 / 자료형 / 변수명
크기 / int / inch
전원 / boolean / power
채널 / int / channel
볼륨 / int / volume

등과 같이 자료형과 변수명을 정해준다.
다음은 기능을 구현하는 메소드를 작성해보자.

구분 / 메소드 명 / 설명
전원 on/off / power() / 현재 power의 값을 반대로 변셩
채널변경 / channelUp(), channelDown() / 현재 채널에서 1증가, 1감소
볼륨 조절 / volumeUp(), volumeDown() / 현재 볼륨에서 1중가, 1감소
유튜브 / youtube() / 유튜브 앱 실행

위와 같은 변수, 메소드 등을 작성할 때, 변수를 사용하기 위해서 변수를 선언할 것 인데,
변수의 선언 위치에 따라 변수의 종류를 구분할 수 있다.

1. 지역변수
지역변수는 해당지역(메소드)에서만 사용 가능한 변수이다.

public void main(){
	int num;
}

위와 같이 int형 변수 num을 선언했다면, 변수 num은 main메소드를 벗어나면 사용하지 못한다.

2. 전역변수
전역변수(멤버변수, 인스턴스변수)는 해당 클래스 내부에서만 사용이 가능한 변수이다. 객체 생성시에는 해당 객체에서만 사용이 가능하다.

public class velog{
	private int num = 0;
    
	public void main{
		System.out.println(num);
	}
}

int형 변수 num을 class에 선언했기 때문에, main메소드에서도 num을 사용할 수 있다.
main메소드를 실행하면 0이라는 출력 결과가 나올 것 이다.

3.정적변수
정적변수(클래스 변수)는 클래스와 관계없이 사요 가능한 변수이다. static키워드를 이용해서 선언한다.

객체지향 3대 원직

객체지향의 3대 원칙으로
1. 캡슐화 2. 상속 3. 다형성 이 있다.
오늘은 이 중 캡슐화에 대해서 알아보려고한다.

캡슐화는 추상화를 통해 정의된 데이터들과 기능을 하나로 묶어 관리하는 기법이다. 클래스의 가장 중요한 목적인 데이터의 접근제한을 원칙으로 하여, 클래스 외부에서 데이터의 직접 접근을 막고, 대신 데이터를 처리하는 함수(메소드)들을 클래스 내부에 작성하여 데이터에 접근하는 방식이다.

간단히 정리하자면, 캡슐화를 위해 필요한 것은 다음과 같다.
1. 접근제어 지시자를 통한 데이터 접근 제한
2. 데이터 처리 함수(getter, setter)

접근제어지시자(접근제한자)
접근제어지시자는 public > protected > default > private의 순으로 접근 제어 범위의 크기가 나눠진다.
사실 저번 글에도 썼다. 하지만 정리할 겸 간단하게 다시한번 적어보자.

구분 / 해당 클래스 내부 / 같은 패키지 / 후손 클래스 / 전체
public / o / o / o / o
protected / o / o / o / x
default / o / o / x / x
private / o / x / x / x

접근제어지시자의 범위는 위와 같이 정리할 수 있다. 우리가 처음 변수를 선언할 때 배우는 int/ String 등의 형태의 변수에는 앞에 아무것도 붙어있지않은데, 그 이유는 기본값인 default가 자동으로 붙어있기 때문이다. 우리가 아무것도 붙이지 않고 변수를 선언하면, 같은 패키지내에서 까지 변수에 접근 가능하다.

위와 같이 접근제어지시자를 사용하는 이유 중 몇가지를 적어보자.

-정보를 숨기는 것
-의도치 않은 외부 접근에 대한 오류를 방지하기 위함
-만들어진 객체가 개발자의 의도대로 사용 될 수 있도록 하기 위함
-클래스의 멤버 변수는 일반적으로 private영역에 저장

이러한 이유로 접근제어지시자를 사용해, 접근을 제어해주는 것 이다.

그렇다면, 클래스의 객체를 생성해서 다른 클래스에서 그 변수들을 사용하기 위해서는 어떻게 해야할까?
그 답은 getter / setter 메소드이다.

getter / setter
변수 선언 시 정보은닉을 위해 private를 사용하면 외부에서 해당 변수의 데이터를 입력하는 것도 불가능하고, 변수안의 데이터 값을 사용하는 것도 불가능하다. 객체화를 하여 사용하는 경우 데이터에 값을 사용하기도 해야 하고, 필요에따라서는 변경도 해야 한다. 그렇기에 public 접근제어 지시자를 가지고있는 getter 와 setter 메소드를 만들어, 다른 클래스에서도 안의 변수에 접근하고, 수정할 수 있도록 한다.

getter
멤버변수의 값을 읽어와서 호출한 쪽으로 읽은 값을 넘기는 메소드를 getter 메소드라고 한다.

public class TV{
	private int inch;
	private boolean power;
	private int channel;
	private int volume;
    
	public int getVolume(){
	return volume;
	}
}

이 클래스의 변수들은 모두 private 접근제어 지시자를 사용한다. 그렇기에 다른 클래스에서 저 변수들을 직접 건드리는 것은 불가능하다. 그래서 전체 범위의 접근을 허용하는 public메소드를 클래스에 추가하여, 다른 클래스에서도 그 값을 불러들이는 것이 가능하도록 한다. getVlolume()이라는 메소드는 int형 변수 volume값을 return한다. 그러면 getVolume메소드에는 TV클래스에 저장되어있는 volume의 값을 가지고있게된다. 이 값을 다른 변수에 넣어 출력하는 과정을 거치면, 안에 있는 수가 무엇인지 알 수 있다. 이같은 방법으로 다른 클래스에서 접근이 불가능한 변수의 값을 가져올 때 사용하는 메소드가 getter메소드이다. 이 메소드는 변수에 접근이 가능한 같은 클래스 내부에 써준다.

setter
멤버변수에 변경할 값을 전달 받아서 멤버변수 값을 변경하는 메소드이다.

public class TV{
	private int inch;
	private boolean power;
	private int channel;
	private int volume;
    
	public void setVolume(int volume){
		this.volume = volume;
	}
}

getter메소드와 같은 원리이다. public void setVolume(int volume) 메소드를 사용하여 접슨하지 못하는 메소드에 접근한 후, 다른 클래스에서 정해준 임의의 int형 변수 값을 int volume 매개변수에 넣어주면,(int itVolume을 넣어줬다고 했을 때) 클래스에서 생성한 객체의 volume에 itVlolume값을 대입해주는 것 이다.

생성자

다음으로 알아볼 것은 생성자이다. 생성자는 클래스 작성 시, 아무것도 작성하지 않아도 JVM이 자동으로 기본생성자를 생성한다.

public class Silver {
	private String grade;
	private String name;
	private int point;
	
	//기본생성자
	public Silver(){
		
	}
}

기본 생성자의 형태는 다음과 같다. 안에 어떤 내용도 들어있지 않은데, 이렇게되면 grade, name, point 변수들은 각각 기본값을 초기화한다. System.out.println을 이용해 출력해 보면, 각각 null / null / 0의 값을 가지고 있을 것 이다.
매개변수가 있는 생성자도 만들 수 있다. 하지만 이를 작성했을 경우에는, JVM이 기본 생산자를 자동으로 생성하지 않기 때문에, 클래스를 작성하며 직접 기본 생성자를 작성해주어야한다.

public class Silver {
	private String grade;
	private String name;
	private int point;
	
	//기본생성자
	public Silver(){
		
	}
	//매개변수 생성자
	public Silver(String grade,String name,int point) { //매개변수 값을 전역 변수에 대입
		this.grade=grade; 
		this.name=name;
		this.point=point;
		
	}
}

위와 같은 형태를 가지게된다. 객체를 생성한 후, 매개변수 생성자를 사용해 객체의 변수에 값을 집어넣어줄 수 있다.
메소드 오버로딩을 이용하면, 여러 개의 생성자를 사용할 수 있다!
일반적으로는 기본생성자, 모든 멤버변수를 초기화 하는 매개변수가 있는 생성자를 작성하고, 필요에 따라서 추가로 생성자를 작성한다.

소멸자

생성자와 반대로 객체가 소멸할 때 자동으로 호출되는 메소드이다. java에서는 없으니, 다른 언어를 공부할 때 다시 찾아보도록 해야겠다. 필자는 꼭 c++를 다시 공부할거다. java의 경우에는
GC(Garbage Collector)가 메모리를 자동으로 정리하기 때문에 소멸자가 필요없다!

객체의 할당!!!!

필자가 진짜 헷갈리는 부분이었다.
new 생성자();를 사용하여 객체를 생성하면 heap메모리 공간에 서로 다른 자료형의 데이터가 연속으로 나열 할당된 객체공간이 만들어지는데 이를 인스턴스라고 한다.

TV tv = new TV();

tv라는 객체가 생성된 것 이다. tv에는 주솟값이 넣어져있고, 이를 따라가보면, TV클래스의 객체가 생성되어있는 개념인 것 이다. 처음엔 이게 무슨말인지 몰랐는데, 하다보니까 알겠더라...
오늘은 여기까지 정리하도록 하겠다!! 안녕!

0개의 댓글