관리 메뉴

개발 노트

7/22 캡슐화, Method OverLoading, SingleTon 패턴, 디자인패턴, Getters and Setters, 상속, Object 클래스 본문

프로젝트 기반 JAVA 응용 SW개발 : 22.07.19~23.01.20/JAVA

7/22 캡슐화, Method OverLoading, SingleTon 패턴, 디자인패턴, Getters and Setters, 상속, Object 클래스

hayoung.dev 2022. 7. 22. 16:38

ch04> ArrTest9.java

package ch04;

// 출력 결과
//  이름   국어   영어   수학   총점   평균   
//  --------------------------------------------
//  김준수   80   70   90   240   80
//  이하이   70   90   90   250   83
//  안예은   80   70   80   230   76
//  국카스텐   90   90   70   250   83
//  --------------------------------------------
//  총계       320   320   330   970   80

public class ArrTest9 {

	public static void main(String[] args) {
		String[] m = {"이름","국어","영어","수학","총점","평균"};
		String[] name = {"김준수","이하이","안예은","국카스텐"};
		int[][] score = {{80,70,90}, {70,90,90}, {80,70,80}, {90,90,70}};
		int[] tot = new int[3];
		int sum = 0, avg = 0, totSum = 0, totAvg = 0;
		System.out.println("성적표 \n");
		for(int i = 0; i<m.length; i++)
			System.out.print(m[i]+"\t");
		System.out.println("\n-------------------------------------------");
		
		for(int i = 0; i<score.length; i++) {
			System.out.print(name[i] + "\t" );
			for(int j = 0; j<score[i].length; j++) {
				System.out.print(score[i][j] + "\t");
				sum += score[i][j]; tot[j]+=score[i][j];
			}
			avg = sum / score[i].length;
			System.out.println(sum + "\t" + avg); sum = 0;
		}
		System.out.println("----------------총계 출력----------------------");
		System.out.print("총계" + "\t");
		for(int j = 0; j<3; j++) {
			System.out.print(tot[j] + "\t");
			totSum += tot[j];
		}
		// totAvg = totSum / 12;
		totAvg = totSum / (score.length * score[0].length);
		System.out.println(totSum + "\t" + totAvg);
	}
}

출력 결과

 

ch05> Variable.java

package ch05;

class Var {
	//Class 변수
	static int k;
	//Instance 변수
	String 	color = "멋있어";	//Member 변수, 필드
	int 	speed = 33;
	
	//범위
	void scope() {
		//지역변수
		int s = 77;
		System.out.println(s+"scope method");
	}
	
}

public class Variable {

	public static void main(String[] args) {
		Var.k = 10;				//인스턴스 생성 없이 '클래스이름.클래스변수명'으로 접근
		Var var1 = new Var();	//인스턴스 생성 후
		var1.speed = 55;		//'참조변수.인스턴스변수명'으로 접근
		System.out.println("speed->"+var1.speed); //멤버변수. 이름만 불러주면 언제든 쓸 수 있는 변수.
		var1.scope();
		//System.out.println("scope.s->" + var1.s); //지역변수는 지역메소드를 통해서만 볼 수 있다. 오류남. 

	}

}

출력 결과

 

ch06 > EncapsuleEx.java

package ch06;

// Encapsulation은 정보보호를 위해 쓰는 것.
class Encapsule {
	private String 	name;
	private int 	age;
	
	//위에서 변수를 private로 만들었으니 public으로 getter, setter를 만들어서 접근함.
	//private은 직접 접근하면 오류가 나기 때문에 getter, setter로 접근하는 것임.
	public String getName() {
		return name;
	}
	public int getAge() {
		return age;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(int age) {
		if (age < 0) System.out.println("나이입력오류");
		else this.age = age;
	}
}

public class EncapsuleEx {

	public static void main(String[] args) {
		Encapsule h1 = new Encapsule();	//Encapsule은 같은 파일에만 있을 뿐 다른 class임.
		//h1.name = "홍길동";	//private 이기 때문에 다른 클래스여서 접근이 불가능하다.
		h1.setName("홍길동");
		h1.setAge(-10);
		System.out.println("이름 : " + h1.getName());
		//결과값의 나이가 0인 이유 : 캡슐화를 통해 정보보호를 할 수 있다.
		System.out.println("나이 : " + h1.getAge());
		

	}

}

출력 결과

 

 

6.자바 메서드와 캡슐화.pdf > p.24 (중요, 면접)

접근제어자

private는 같은 클래스 내에서만 접근이 가능한 것.

default는 같은 패키지 안에서 접근이 가능한 것. 같은 패키지 내에서 private나 public 등등 작성을 하지 않았으면 default인거임.

protected는 부모가 자식을 보호해주기 때문에 자식을 보호해주는 것.

 

이것이 같은 패키지

 

 

FactorialEx.java

package ch06;

import java.util.Scanner;

class Factorial {
	int result = 1;
	//자신을 다시 호출하는 함수 = 재귀함수
	void factorial(int cnt) {
		if (cnt>1) {
			result *=cnt;
			System.out.print(cnt + " * ");
			factorial(--cnt);
		}
		else {	//이렇게 재귀함수가 빠져나오는 구멍을 만들지 않으면 무한루프에 빠질 수 있다.
			System.out.println(cnt);
			System.out.println("Factorial 결과는 " + result);
			return;
		}
	}
}

public class FactorialEx {

	public static void main(String[] args) {
		Factorial fac = new Factorial();
		int InNum;
		System.out.println("Factorial 할 10이하의 숫자를 입력하세요 ");
		Scanner sc = new Scanner(System.in);
		InNum = sc.nextInt();
		fac.factorial(InNum);
	}
}

출력 결과

 

MethodOVEx.java

package ch06;

//Method OverLoading -> 같은 class 내 매개변수 개수가 다르거나, Data형이 다른 경우 
class MethodOV {
	
	void print() {
		System.out.println("매개변수 없음");
	}
	void print(int a1) {
		System.out.println("매개변수 int 1개:" + a1);
	}
	void print(String x1) {
		System.out.println("매개변수 Str 1개:" + x1);
	}
	void print(int a1, String x1) {
		System.out.printf("매개변수 int 1개[%d] Str 1개[%s]:", a1, x1);
	}
}


public class MethodOVEx {

	public static void main(String[] args) {
		MethodOV mov1 = new MethodOV();
		mov1.print();
		mov1.print(7);
		mov1.print("짜장면");
		mov1.print(3, "짜장면");
	}
}

출력 결과

 

 

SingleTonEx.java

package ch06;

//디자인패턴 중 하나인 싱글톤
//데이터베이스에 접근할 때 싱글톤으로 접근함. 자원(리소스) 절감.
class SingleTon {
	String str;
	private static SingleTon instance;	//Encapsulation, '나' 형의 instance 선언 (static은 공유라는 뜻)
	//아무나 나를 생성하지 못하게 하겠다는 뜻
	private SingleTon() {
		
	}
	// 생성자의 역할 : 인스턴스 메모리를 만든다, 초기값을 세팅해준다. (중요 외우기, 면접질문)
	// 1. instance를 private로 해놓고 getInstance로만 받아서 하단 안의 로직을 구성하면서 남들이 함부로 자원을 건들지 못하도록 함.
	public static SingleTon getInstance() {	//메소드의 이름을 getInstance 등으로 잘 지어야 커뮤니케이션 비용이 들지 않음.
		if (instance == null) instance = new SingleTon();
		return instance;
	}
}

public class SingleTonEx {

	public static void main(String[] args) {
		//2. 그래서 st1과 st2는 이름만 다를 뿐, 내부 주소는 같음.
		 SingleTon st1 = SingleTon.getInstance();	//static이라 .getInstance 자동완성이 되는 것임.
		 //SingleTon st2 = new SingleTone();	-> private으로 해놔서 아무나 날 생성하지 못하므로 오류
		 SingleTon st2 = SingleTon.getInstance();
		 st1.str = "스스로 있는자";
		 System.out.println(st2.str);
		 //3. 그렇게 리소스를 많이 절감할 수 있음.
		 if (st1 == st2) System.out.println("같다");
		 else			 System.out.println("다르다");

	}

}

출력 결과

 

캡슐화를 하면 외부에서 내부 데이터를 직접 접근하거나 조작할 수 없다.

Singleton패턴은 객체의 생성과 관련된 패턴으로서 특정 클래스의 객체가 오직 한개만 갖도록 보장한다. 즉 클래스의 객체를 하나로 제한한다. 동일한 자원이나 데이터를 처리하는 객체가 불필요하게 여러 개 만들어질 필요가 없는 경우에 주로 사용한다.

 

 

[Design Pattern] 

1. 정의 : 유능한 개발자들이 반복해 발생한 문제점을 해결해놓은 해결책 또는 라이브러리 모음집

2. 가장 유명한 디자인패턴 :  GOF D/P (gang of four)

3. 유형 
 1) 생성 

  (1) Singleton(싱글톤) : 전역 변수를 사용하지 않고 객체를 하나만 생성하도록 하며, 생성된 객체를 어디에서든지 참조할 수 있도록 하는 패턴. (하나의 객체를 생성하면 생성된 객체를 어디서든 참조할 수 있지만, 여러 프로세스가 동시에 참조할 수는 없음. 클래스 내에서 인스턴스가 하나뿐임을 보장하며, 불필요한 메모리 낭비를 최소화 할 수 있음.

 

 2) 구조

  (1) Adater(어댑터)  : 한 클래스의 인터페이스를 클라이언트에서 사용하고자 하는 다른 인터페이스로 변환 (호환성이 없는 클래스들의 인터페이스를 다른 클래스가 이용할 수 있도록 변환해주는 패턴. 기존의 클래스를 이용하고 싶지만 인터페이스가 일치하지 않을 때 이용함.)

  (2) Facade(퍼싸드) : 어떤 소프트웨어의 다른 커다란 코드 부분에 대하여 간략화된 인터페이스를 제공 (복잡한 서브 클래스들을 피해 더 상위에 인터페이스를 구성함으로써 서브 클래스들의 기능을 간편하게 사용할 수 있도록 하는 패턴. 서브 클래스들 사이의 통합 인터페이스를 제공하는 Wrapper 객체가 필요함.)

 

 3) 행위  

  (1) Strategy(전략) : 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴 (동일한 계열의 알고리즘들을 개별적으로 캡슐화하여 상호 교환할 수 있게 정의하는 패턴. 클라이언트는 독립적으로 원하는 알고리즘을 선택하여 사용할 수 있으며, 클라이언트에 영향 없이 알고리즘의 변경이 가능함.)

  (2) Template Method(템플릿 메소드): 어떤 작업을 처리하는 일부분을 서브 클래스로 캡슐화해 전체 일을 수행하는 구조는 바꾸지 않으면서 특정 단계에서 수행하는 내역을 바꾸는 패턴 (상위 클래스에서 골격을 정의하고 하위 클래스에서 세부 처리를 구체화하는 구조의 패턴. 유사한 서브 클래스를 묶어 공통된 내용을 상위 클래스에서 정의함으로써 코드의 양을 줄이고 유지보수를 용이하게 해줌.)

 

Student.java

package ch06;

//여러개의 클래스를 한 번에 쓸 수 있도록 함.
public class Student {
	//변수의 첫 자를 소문자로 만들어야 getters, setters 만들 때 오류날 확률을 덜 수 있음.
	//멤버변수들은 private로 하는 것이 권장이다.
	private String name;
	private int age;
	private String sno;
	
	public void printAll() {
		System.out.println("이름: "+name+", 나이: " + age + ", 학번: "+sno);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getSno() {
		return sno;
	}

	public void setSno(String sno) {
		this.sno = sno;
	}
	

}

 

Getters and Setters 자동 생성하는 법.

 

Teacher.java

package ch06;

public class Teacher {
	private String 	name;
	private int		age;
	private String 	subject;
	
	public void printAll() {
		System.out.println("이름: "+name+", 나이 : "+age+", 과목: " + subject);
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getSubject() {
		return subject;
	}
	public void setSubject(String subject) {
		this.subject = subject;
	}

}

 

Manager.java

package ch06;

public class Manager {
	private String name;
	private int age;
	private String part;
	
	public void printAll() {
		System.out.println("이름 : "+name+", 나이 : "+age+", 담당 : " + part);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getPart() {
		return part;
	}

	public void setPart(String part) {
		this.part = part;
	}

}

 

 

PersonEx.java

package ch06;

//이걸로 실행 (Student, Teacher, Manager은 실행x)
public class PersonEx {
	
	public static void main(String[] args) {
		Student st1 = new Student();
		st1.setName("수지");
		st1.setAge(21);
		st1.setSno("1234");
		// st1.printAll();
		
		Teacher th1 = new Teacher();
		th1.setName("길동");
		th1.setAge(35);
		th1.setSubject("JAVA");
		
		Manager mg1 = new Manager();
		mg1.setName("원빈");
		mg1.setAge(19);
		mg1.setPart("청소");
		
		System.out.println("이름: "+st1.getName()+", 나이: " + st1.getAge()+", 학번: " + st1.getSno());
		
		th1.printAll();
		mg1.printAll();
	}

}

출력 결과

 

Computer.java

package ch06;

public class Computer {
	int sum1(int[] values) {
		int sum = 0;
		
		for(int i=0; i<values.length; i++) {
			sum += values[i];
		}
		return sum;
	}
	
	//...은 주는대로 다 받음. 그래서 ComputerEx에서 5개를 줬는데 다 받음. 가변변수일때 이렇게 해주면 편하다.
	int sum2(int ... values) {	
		int sum = 0;
		
		for(int i=0; i<values.length; i++) {
			sum += values[i];
		}
		return sum;
	}
}

 

 

ComputerEx.java

package ch06;

public class ComputerEx {

	public static void main(String[] args) {
		Computer myCom = new Computer();
		int[] arrays = {1,2,3};
		int result1 = myCom.sum1(arrays);	//Computer.java에서 배열값으로 저장했었음
		System.out.println("result1: " + result1);
		
		int result2 = myCom.sum1(new int[] {1, 2, 3, 4, 5});	
		System.out.println("result2: " + result2);
		
		int result3 = myCom.sum2(1,2);
		System.out.println("result3: " + result3);
		
		int result4 = myCom.sum2(1,2,3);
		System.out.println("result4: " + result4);
		
		int result5 = myCom.sum2(1,2,3,4,5);	//파라미터를 넣는 대로 다 들어감. 배열 아님.
		System.out.println("result5: " + result5);

	}

}

출력 결과

 

 

[7. 자바 상속-중첩]

p.2 클래스는 상속한다 인터페이스는 구현한다 라는 말로 표현하지만 둘 다 상속 맞음.

[3R]

Reuse

ReEngineering

Reverse-Engineering

 

p.7 Object클래스

– 모든 클래스의 최고조상

- 조상이 없는 클래스는 자동적으로 Object클래스를 상속

- 상속계층도의 최상위에는 Object클래스가 위치한다.

 

p.8 Private와 상속을 둘 다 사용하였을 때 private이 상속보다 영향력이 더 큼. 정보보호가 중요하기 때문. 즉 private 객체변수는 상속 안됨.

 

p.9 상속(inheritance)-super

1. 하위 클래스에 의해 가려진 상위 클래스의 멤버 변수나 메소드에 접근할 때

 - super.객체변수

 - super.메소드이름(매개변수)

2. 상위 클래스의 생성자를 호출할 때

 - super(매개변수)

3. super문장은 반드시 첫 번째 라인에 와야 한다.

4. this( )가 자신의 생성자를 호출하기 위해 제공되는 예약어라면 수퍼 클래스의 생성자를 호출하기 위해서는 super( ) 예약어가 제공.

5. 만일 매개 변수가 있는 수퍼 클래스의 생성자를 호출하고 싶은 경우에는 super(매개 변수)라고 호출.

6. 주의할 점은 수퍼 클래스의 생성자를 호출하는 위치이다. 서브 클래스의 생성자에서 무엇보다도 수퍼 클래스의 생성자를 제일 먼저 호출해주어야 함.

 

 

 

 

ch07 > Engine.java

package ch07;

public class Engine {
	//같은 성질로 되어있는 객체들을 묶어서 쓰는 것이 객체지향
	String 	type;	//타입
	int		cc;		//배기량
	
	Engine(String type, int cc) {
		this.type = type;
		this.cc = cc;
	}
	
	void print() {
		System.out.println("타입 : " + type);
		System.out.println("배기량 : " +cc);
	}
}

 

CarEx.java

package ch07;

public class CarEx {
	String kind;
	//멤버변수로 객체를 쓸 수 있다.(흔하게 씀)
	//알파엔진, 베타엔진. Engine.java에서 같은 묶음별로 객체를 관리하기 위함.
	Engine eg;	//연관관계 맺어서 사용함.
	
	//객체에서 객체 사용 방법
	//1. 상속 관계를 맺어서 사용한다.
	//2. 연관 관계(Association)를 맺어서 사용한다.
	
	CarEx(String kind, Engine eg) {
		this.kind = kind;
		this.eg = eg;
	}
	
	void print() {
		System.out.println("종류 : " +kind);
		eg.print();
		System.out.println("===================");
	}

	public static void main(String[] args) {
		Engine eg1 = new Engine("알파엔진", 2000);
		Engine eg2 = new Engine("베타엔진", 3000);
		//--------------------------------------------
		CarEx[] car = new CarEx[3];		//배열안에도 객체가 들어갈 수 있음.
		car[0] = new CarEx("모닝", eg1);
		car[1] = new CarEx("소나타", eg1);
		car[2] = new CarEx("그랜저", eg2);
		
		//객체를 배열로 만들었을 때의 장점 : 로직을 자유자재로 구성할 수 있다.
		for (CarEx c : car ) {
			c.print();
		}
	}
}

출력 결과

 

Association 연관관계

반응형