본문 바로가기

Programming Language/JAVA

[JAVA] This포인터와 정보은닉 & 캡슐화

 

 This
- 자기 자신의 정보를 가지고 있다.
- 멤버함수에서 멤버변수에 접근하기 위하여 사용된다.
- 객체의 0번째 매개변수라고도 칭한다.

 

 

 

 

class This_01{
	public int a = 10;
	public void func() {
		int a = 2;
		System.out.println("func() a :" +this.a + "\t"+a);
	}
	public void funcOne() {
		System.out.println("funcOne() a: " +a);
	}
}
	public class Test01 {
	public static void main(String[] args) {
		This_01 T = new This_01();
		T.func();
		T.funcOne();
		System.out.println(T.a);

	}
}

* This포인터 설명


This_01클래스와 Test01클래스를 두개로 나눠서 실습해보겠습니다.

This_01클래스에서 전역변수로 a를 10으로 선언해주고, func메소드에서 a를 2로 선언해줬습니다. 
저번시간에 배웠던 전역변수,지역변수를 참고해주시면 더 이해하기 수월하실겁니다! 
그리고 메시지출력으로 this.a를 하면 전역변수에있는 즉, 클래스에있는 자기자신의 a를 불러옵니다.
this는 앞서 말씀드렸다시피 자기자신을 가르킵니다. 그리고 \t을 해서 a를 출력하면 func메소드안에서 선언한 a를 출력해줍니다. 
funcOne메소드는 그냥 a만 출력해보면 전역변수에서 선언한 a인 10이 출력됩니다. funcOne메소드에서는 a를 선언하지 않았기 때문입니다.
Main메소드가있는 Test01클래스에서 This_01클래스 객체생성해준후, 메소드(기능)들을 호출해보면 콘솔로 출력됩니다.
그리고, T라는 객체를 생성했고, "T.a"라고 입력하고 출력하면 This_01클래스에있는 변수a가 출력되서 10이 출력됩니다.

 

 

 

 

 

 

import java.util.Scanner;

	class Ageclass{
		public int age;
		public void ageFunc(int age) {
			this.age = age-1;
		}
		public void printAge() {
			System.out.println("당신의 나이는 : "+age);
		}
	}

	public class Quiz {

		public static void main(String[] args) {
			Scanner sc = new Scanner(System.in);
			Ageclass oop = new Ageclass();
			System.out.print("당신의 나이는 : ");
			int a = sc.nextInt();
			oop.ageFunc(a); //사용자가 입력한 나이값을 AgeClass에 저장하는 메소드
			oop.printAge();	//저장된 메소드를 출력해주는 메소드
		}

	}

Ageclass와 Quiz클래스 두개로 실습해보겠습니다.
Ageclass에서 age변수를 전역변수로 선언해주고, ageFunc메소드에서 매개변수로 age를 가져옵니다.
가져온 age값에 -1연산을 해주고 this포인터를 사용해서 자기자신(Ageclass)안에있는 전역변수 age에 저장해줍니다.
예를들어 호출될때 매개변수인 age가 20이면 -1 연산을 통해 19가되고, 19가 자기자신(Ageclass)의 전역변수age에 저장됩니다. 두번째 메소드인 printAge는 저장된 전역변수 age를 출력해주는 메소드입니다.
Main메소드가 있는 Quiz클래스에서 사용자가 콘솔창을통해 입력받기위해 Scanner클래스를 사용해서 객체생성고, Ageclass도 객체생성해줍니다. 그리고 나이를 입력받아 그값을 a변수에 저장해줍니다. 50을 입력했다면, 50이 저장된 a를 ageFunc메소드를 호출해서 a값(50)을 파라미터로 같이 넘겨줍니다. ageFunc메소드에 넘어간 a(50)을 age 매개변수가 받아주고 age는 50이됩니다. 50-1을 연산처리해서 this인 자기자신(Ageclass) age(49 저장)에 저장해줍니다.
다시 메인메소드로와서 printAge로 메시지를 출력해주면 Ageclass안에있는 변수 age가 출력되는데 49가 출력됩니다.

 

 

 

 

 

 

 

 

 

class Machine{
	private int num;
	public void func() {
		System.out.println("num : "+num);
	}
}
public class Test03 {
	public static void main(String[] args) {
		Machine mac = new Machine();
		mac.num=100;
		mac.func();
	}

}

Machine클래스와 Test03클래스 두개로 실습해보겠습니다.
Machine클래스에서는 func메소드를 선언해주고 전역변수로 num을 선언해준걸 출력해주는 메소드입니다.
하지만, num이 현재 private 접근제한자로 되어있습니다. 이건 Main메소드가 있는 Test03클래스에는 Machine클래스의 
객체를 생성하고나서 인스턴스명.변수명으로 호출해서 100을 저장하려하면 에러가 발생합니다. 그이유는 private 접근제한자로 되어있기때문에 숫자가 저장되지않습니다. 에러를 수정해주기위해 아래 소스에서 살펴보겠습니다.

 

 


 

 

 캡슐화

: 하나의 객체는 독립적으로 완벽한 역할을 수행할 수 있게 디자인 되어야한다. 또한, 내부에서 발생하는 경계 검사 등의
  동작은 외부에서 알 필요가 없다.
  예를들어 프로그램을 이용하는사람이 마음대로 코드의 값들을 수정하면 문제가 발생한다. 

 

 

 

 

class Machine{
	private int num;
	public void func() {
		System.out.println("num : "+num);
	}
	public void setNum(int num) {
		this.num = num;
	}
}
public class Test03 {
	public static void main(String[] args) {
		Machine mac = new Machine();
		mac.setNum(100);
		mac.func();
	}

}

num변수가 private접근제한자로 되어있지만, 하나의 메소드를 setter로 만들어줍니다.
여기서 클래스에있는 변수들의 값을 셋팅해주고 꺼내준다해서 setter , getter라고 합니다. 
메소드명을 setNum으로 만들어주고, Machine클래스안에있는 num변수를 저장해주는 메소드입니다.
this 포인터를 사용해서 Machine클래스안에있는 num변수를 매개변수로 받아온 num을 그대로 저장해줍니다.
그러면 Main메소드가있는 Test03클래스를 객체생성해주고 setNum메소드를 호출할때 100을 보내면 그값으로 100이 저장
이 되고 func메소드를 호출해서 그값을 출력해줍니다.

 

 

 

 

 

import java.util.Scanner;

class SetGet{
	private String name;
	public void display() {
		Scanner sc = new Scanner(System.in);
		System.out.print("이름 입력 : ");
		name = sc.next();	
		System.out.println("당신의 이름은 : "+name+"이군요");
	}
}
public class Test04 {
	public static void main(String[] args) {
	SetGet sg = new SetGet();
	sg.display();
	}
}

 SetGet클래스와 Test04클래스를 나눠 실습하겠습니다.
name변수를 private접근제한자로 전역변수로 선언해주고, display메소드안에서 이름을 입력받아서 name변수에 저장하고 
그값을 출력해주는 메소드입니다. Test04클래스에서 SetGet클래스에서 객체를 생성해주고, display메소드를 호출해주면 
이름을 입력해주고, name변수를 출력해줍니다. 따로 set메소드를 선언해주지않아도 이렇게 해도 출력됩니다.
하지만, setter와 getter를 사용하는것이 캡슐화라고 할수있습니다.

 

 

 

 

 

import java.util.Scanner;
class SetGet_01{
	private String name;
	public void dispaly() {
		Scanner sc = new Scanner(System.in);
		String name;
		System.out.println("이름 입력: ");
		name = sc.next();
		setName(name);
		System.out.println("당신의 이름은 : "+getName()+"이군요");
	}
		public void setName(String name) {
		this.name=name;
		}	
		public String getName() {
			return name;
		}
	}
	public class Test05 {
	public static void main(String[] args) {
		SetGet_01 sg = new SetGet_01();
		sg.dispaly();
		}
	}

이번에는 setter , getter을 이용해서 사용해보겠습니다.
위소스에서 setName메소드와 getName메소드를 만들어줍니다.
setName메소드는 매개변수로 받아온 name을 SetGet_01클래스안에있는 변수 name을 저장해주는 역할을합니다.
getName메소드는 setName한 name변수 즉, SetGet_01클래스안에있는 변수값을 그대로 리턴해줍니다.
display메소드는 이름을 입력받고 그값을 name변수로 받고 setName메소드를 통해 name변수를 파라미터로 보내줍니다.
SetGet_01클래스안에있는 name변수에 입력된 값이 저장되고, 그값을 getName메소드를 통해 값을 받아와 콘솔에 
출력해줍니다.

 

 

 

 

 

 

 

import java.util.Scanner;

class SumClass1{
	private int kor,eng,math;
	public int sum(int kor,int eng, int math) {
		this.kor = kor;
		this.eng =eng;
		this.math = math;
		return kor+eng+math;
	}
}

public class Test06 {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		SumClass1 sc = new SumClass1();
		System.out.println("국,영,수 입력");
		int k = input.nextInt();
		int e = input.nextInt();
		int m = input.nextInt();
		int result = sc.sum(k, e, m);
		System.out.println("3과목의 합 : "+result);
		
	}
}

이번에는 위 소스를 가지고 setter와 getter로 변경해보겠습니다!
( 각자 실습해보시고 아래 소스를 봐주시길 바랍니다. )

 

 

 

 

 

 

import java.util.Scanner;

class SumClass1{
	private int kor,eng,math;

	public int getKor() {
		return kor;
	}

	public void setKor(int kor) {
		this.kor = kor;
	}

	public int getEng() {
		return eng;
	}

	public void setEng(int eng) {
		this.eng = eng;
	}

	public int getMath() {
		return math;
	}

	public void setMath(int math) {
		this.math = math;
	}
	public int sumFun() {
		int sum = this.kor + this.eng + this.math;
		return sum;
	}
	public void disPlay() {
		Scanner input = new Scanner(System.in);
		int k,e,m,result;
		System.out.println("국어 입력");
		k = input.nextInt();
		setKor(k);
		System.out.println("국어입력한값 : "+getKor());
		System.out.println("영어 입력");
		e = input.nextInt();
		setEng(e);
		System.out.println("영어입력한값 : "+getEng());
		System.out.println("수학 입력");
		m = input.nextInt();
		setMath(m);
		System.out.println("수학입력한값 : "+getEng());
		
		result = sumFun();
		System.out.print("3과목의 합 : "+result);
	}
	
}
public class Test06 {

	public static void main(String[] args) {
		SumClass1 sc = new SumClass1();
		sc.disPlay();
	}

}

SumClass1와 Test06클래스로 나누어 실습해보겠습니다.
SumClass1에서는 변수로 kor,eng,math를 선언해주되, 캡슐화이기에 private접근제한자로 만들었습니다.
set메소드들로 셋팅(저장)해주고, get메소드들로 그값을 리턴해줍니다.
그리고 sumFun메소드는 저장된 kor,eng,math변수들을 더한 연산값을 sum변수에 저장하고 리턴해줍니다.
display메소드에서는 각각의 점수들을 입력받고 모두 set메소드들로 저장해주고, 그값을 각각 get메소드들로 출력해줍니다.
그리고 sumFun메소드를 호출해서 모든 과목 합친점수를 result변수에 저장해주고 3과목의 합을 메시지출력해줍니다.
그러면 Main메소드가 있는 Test06클래스에서 SumClass1클래스의 객체를 생성해주고 display메소드하나로 구현해줍니다.