몽환화

230119 객체배열관리 본문

JAVA 때려잡기

230119 객체배열관리

hyeii 2023. 1. 21. 17:20

패키지

프로그램의 많은 클래스를 관리하기 위해 패키지 이용

클래스와 관련있는 인터페이스들을 모아두기 위한 이름 공간 name space

이름으로 구분되어서 공간 안에 들어가기 때문이지

List 라는 클래스가 있다고 해봐

java.awt

java.utill

이 리스트는 이름이 똑같아서 같은거라고 혼동할 수 있지만 구분이 가능하다는 거지

인터페이스만 모아둔건 아니고 관련된 모든걸 모아둔거임

패키지는 패키지 속의 패키지로 중첩이 가능하며 dot (.) 연산자를 사용함

시중에 나와있는 패키지들과 구분되게 이름지어야 함

 

왜 패키지를 사용해야하징? :

1. 정리가 가능해!

2. 패키지 단위로 접근제어가 가능해 - 보안

3. 클래스를 구별하기 위해서 사용

 

import

다른 패키지에 있는 클래스를 사용하기 위해서 필요한 과정

이거 봐바바

지금 패키지가 두개야 .dto 랑 .service랑

근데 오른쪽에 보면 패키지는 .service를 쓰잖아?

근데 .dto에 있는 Person의 클래스를 쓰고싶으니까 import를 쓰는거임

 

import package_name.*;

이 패키지의 모든 클래스를 임포트 하려면 이렇게 쓰면 돼

 

 

패키지 만들때는 저렇게 이름에 dot 이용해서 패키지 속 패키지를 만들 수 있는데

실제 경로를 찾아보면 이렇게 형성되는걸 확인할 수 있음!!

 

package pkg1; //패키지 선언문 : 이 클래스가 어떤 패키지에 속하는지?
// 항상 클래스는 하나의 패키지 안에 포함이 되어야 한당

public class Person {
    public String pkg = "pkg1";

}

 

pkg1 에 Person이라는 클래스를 만들었다.

pkg1.pkg2에 Person이라는 클래스를 또 만들 수 있을까?

가능!! 엄연히 다른 패키지이다

 

package pkg1;

import pkg1.pkg2.pkg3.Person; //지금 import로 pkg3에 있는 Person 클래스를 불러옴

public class PackageTest {
	public static void main(String[] args) {
		
		// 서로 다른 패키지에 있는 클래스 중에서
		// 하나를 골라서 쓸 때만 이렇게 쓸 수 있음
		Person p1 = new Person();
		System.out.println(p1.pkg);
        /*
        pkg1
        */
		 
		// 만약에 서로 다른 패키지에 있는 이름이 같은 클래스를 
		// 두 개 이상 사용하고 싶다면 -> 패키지를 생략할 수 없고
		// 패키지명.클래스명 을 동시에 써 줘야 함 : 풀패키지 이름 이라구 해 !
		
		pkg1.Person p1 = new pkg1.Person();
		pkg1.pkg2.Person p2 = new pkg1.pkg2.Person();
		pkg1.pkg2.pkg3.Person p3 = new pkg1.pkg2.pkg3.Person();
		Person p4 = new Person();
		
		System.out.println(p1.pkg);
		System.out.println(p2.pkg);
		System.out.println(p3.pkg);
		System.out.println(p4.pkg);
        /*
        pkg1
        pkg1.pkg2
        pkg1.pkg2.pkg3
        pkg1.pkg2.pkg3
        */
	}

}

import java.utill.Arrays;

import java.utill.Date;

import java.utill.Scanner;

=> import java.uitll.*;

java.utill의 모든 클래스를 한꺼번에 import 할 수 이찌!

 

java.utill.logging.Logger

사용할 수 있는거 아님?

얘는  import java.utill.logging.*; 를 해줘야 사용가눙함

 

하위 패키지에 있는 클래스까지 임포트되는건 아님! 그 지정된 지점까지만 되는거지

 

캡슐화

정보은닉이 필요하기 때문에 접근제한자를 이용해

 

접근 제한자

클래스, 멤버 변수, 멤버 메소드 등의 선언부에서 접근 허용 범위를 지정하는 역할의 키워드

멤버 변수, 메소드

public : 모두 공개

protected

(default)

private : 나만

 

객체 A가 객체 B의 변수와 메소드에 접근할 수 있을까?

클래스는 public (default) 만 가능

 

그 외 static final abstract 등

 

((클래스, 객체) 패키지)

public : 모든 위치, 패키지 밖의 전혀 다른 클래스도 접근 가능

protected : 같은 패키지에서 접근 가능 다른 패키지 불가능, 하지만  상속관계의 다른 패키지에서는 가능

default : 같은 패키지에서 접근이 가능 다른 패키지는 불가능

private : 내 클래스 내부에서만 가능

 

 

1. private

// class는 public으로 통일했어 다 보여야 하니까

Person 이라는 클래스에서 private을 사용해서 멤버변수를 만들었어

같은 패키지이지만 다른 클래스인 PersonTest에서 Person으로 객체 p1을 만들어봤어

Person 없는거 보이지? 접근이 안돼

물론 저 위의 Person 클래스에서는 당연히 자기 자신이 만든 private 멤버변수에 접근이 가능하지

 

2. default

Person 이라는 클래스에서 default 변수인 name과 private 변수인 age를 만들었어

같은 패키지이지만 다른 클래스인 PersonTest라는 클래스에서 객체를 만들었더니 봐바

default로 만든 name은 접근이 가능하지만 private으로 만든 age는 접근이 안돼!

지금 보면 패키지가 다른거 보이지? 다른 패키지인데 import로 Person클래스를 불러오긴 했어

그렇지만 접근은 안된다는걸 확인할 수 있음! default로 변수를 만들었으니까 같은 패키지 다른 클래스에서만 보이눈거야

 

3. protected

Person이라는 클래스에서 protected로 변수를 만들었어

 

잘 봐바 객체를 만들고 나서

왼쪽의 같은 패키지 다른 클래스에서는 접근이 가능해 당욘

오른쪽은 다른 패키지 다른 클래스이지만 이 Student라는 클래스가 Person이라는 클래스의 상속을 받았더니

접근이 가능해졌어! 상속이 아니었으면 접근이 불가능했을거야

(import는 클래스 불러와야 하니까 다 하는거야)

 

4. public

public... 해야하냐

걍 다른패키지에서도 가능함

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ

 

 

접근자(getter) 설정자(setter)

우리가 방금까지 사용한 건 사실 좋은 방법이 아니었대 ㅂㄷ

접근자와 설정자를 써야한대

클래스에서 선언된 변수 중 접근제한에 의해 접근할 수 없는 변수(ex. private)같은 경우 다른 클래스에서 접근할 수 없기 때문에 접근하기 위한 메소드(getter setter)를 public으로 선언해서 사용해

p1.name = "name'; => 데이터를 직접 건드는 것

p1.setName("name"); => 메소드를 한번 거치는 것, 간접적인 방식!

왜 필요할까?

멤버변수를 직접 고치는건 오류가 발생할 가능성이 높기 때문이얌

 

 

 

 

 

 

 

이제 저 sysout에서는 밍밍이 출력되는거야

 

p1.setAge(300); // setter를 이용해서 멤버 변수의 값을 수정하고
System.out.println(p1.getAge()); // getter를 이용해서 수정한 값을 얻어오는거지

 

봐바 Person 클래스에서 저 set부분을 바꿨어

나이가 음수이거나 너무 많거나 하면 반환하게 했어

그런다음에 여기를 봐바

setAge(30)

setAge(300)

에서 처음에 30으로 수정했다가

그다음에 다시 300으로 수정하고 출력했더니

의학기술 어쩌구 소리를 하고 반환해서

이전의 30으로 출력을 하는거야

 

신기하냉,,,,,

 

 

Singleton Pattern

객체를 단 하나만 만들 때 사용함

1. 자기 자신의 객체를 private으로 딱 한번만 생성함

2. 외부에서 새로운 객체를 생성할 수 없도록 생성자를 private으로 막음

3. 이 유일한 객체를 반환해주는 public 메소드를 getter로 만들어서 return함

    그럼 다른 클래스에서 사용할 수 있겠지

package test7_singleton;

public class Person {

	// 싱글턴으로 바꾸기

	// 1. private으로 자기 자신을 만들기
	// - static : 객체를 생성하지 않고 클래스 이름으로 접근하기 위해 이렇게 함
	// Person p1 = new Person(); 이런거 안한다는거
	private static Person instance = new Person();

	// 2. 생성자를 private 으로 막기
	// 이 생성자는 바로 위에 new Person에서만 단 한번 호출되고 더 이상 호출 ㄴㄴ
	// 호출 될 때 그 인스턴스가 아래 this 키워드 두개처럼 형성이 되는거지
	private Person() {
		this.name = "유일한사람";
		this.age = 32132132;
	}

	// 3. 유일한 객체에 접근할 수 있는 통로를 public으로 만들기
	public static Person getInstance() {
		return instance;
	}

	// 접근자와 설정자를 만들어보자!
	// 먼저 멤버 변수를 private으로 선언한다.
	private String name;
	private int age;
	private boolean hungry;

	// 위 멤버 변수에 접근할 수 있는 통로를
	// public한 메서드로 만들어줌
	// 값을 변경시켜 주는 것 => 설정자 (setter)
	// 값을 조회해주는 것 +> 접근자 (getter)
	// 마우스 우클릭 => Source => generate getters and setters => 변수 클릭 후 generate

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		if (age < 0) {
			System.out.println("삐빅");
			return;
		}
		if (age > 200) {
			System.out.println("덜덜");
			return;
		}
		this.age = age;
	}

	public boolean isHungry() {
		return hungry;
	}

	public void setHungry(boolean hungry) {
		this.hungry = hungry;
	}

}
package test7_singleton;

public class PersonTest {
	public static void main(String[] args) {
//		Person p1 = new Person(); // 싱글턴에서는 객체를 추가로 생성할 수 없음
		Person p1 = Person.getInstance();
		// 우리 Person에서 getInstance 만들었던거로 이렇게

//		p1.name = "이승재"; private 멤버변수에 접근 불가 !
		System.out.println(p1.getName());
		System.out.println(p1.getAge());

		Person p2 = Person.getInstance();
		System.out.println(p2.getName());
		System.out.println(p2.getAge());
		// 똑같은 객체 두개가 되는거임
		// 변수 이름은 다르지만 같은 객체로부터 가져오는거임

	}

}
/*
유일한사람
32132132
유일한사람
32132132
*/

 

 

 

static

클래스 정보가 등록될 때 클래스의 이름으로 만들어지는 것들

non-static 인스턴스를 만들 때 만들어지는 것 

 

static - 클래스 당하나의 메모리

non-static - 인스턴스당 메모리 할당

 

지금 Person 클래스에서 static으로 선언이 됐잖아

그럼 객체를 만들어서 객체의 멤버변수로 접근하는 게 아니라

Person 이라는 클래스 이름으로 바로 접근해버려

나머지 멤버변수들은 객체를 만들고 객체의 멤버변수로 접근

 

static => non-static 직접 접근 불가능 (인스턴스가 없잔아!)

non-static => static 직접 접근 가능 (인스턴스가 만들어 졌우니까)

 

 

package practice_car;

public class CarManager {

	private int size = 0;

	private Car[] carList = new Car[100];

	public boolean add(Car car) {
		if (size <= 100) {
			carList[size++] = car;
			return true;
		} else {
			return false;
		}

	}

	public Car[] getList() {

		Car[] result = new Car[size];

		for (int i = 0; i < size; i++) {
			result[i] = carList[i];
		}

		return result;
	}

	public Car[] searchByModelName(String modelName) { // 1. contain을 배열로 서치
		int cnt = 0;

		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().contains(modelName)) {
				cnt++;
			}
		}

		Car[] result = new Car[cnt];
		int idx = 0;
		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().contains(modelName)) {
				result[idx++] = carList[i];

			}
		}
		return result;
	}

	public Car searchByModelName2(String modelName) { // 2. contains을 그냥 서치
		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().contains(modelName)) {
				return carList[i];
			}
		}
		return null;
	}

	public Car[] searchByModelName3(String modelName) { // 3. equals를 배열로 서치
		int cnt = 0;

		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().equals(modelName)) {
				cnt++;
			}
		}

		Car[] result = new Car[cnt];
		int idx = 0;
		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().equals(modelName)) {
				result[idx++] = carList[i];

			}
		}
		return result;
	}

	public Car searchByModelName4(String modelName) { // 4. equals를 그냥 서치
		for (int i = 0; i < this.size; i++) {
			if (carList[i].getModelName().equals(modelName)) {
				return carList[i];
			}
		}
		return null;
	}

}
package practice_car;

public class CarTest {
	public static void main(String[] args) {
					
		Car car1 = new Car("QWERTY", "K5", "BLACK", 15000);
		Car car2 = new Car("ASDFGH", "WOW", "BLUE", 4000);
		
		System.out.println(car1);
		System.out.println(car2);
		
		CarManager CM = new CarManager();
		
		CM.add(car1);
		CM.add(car2);

		System.out.println();
		
		System.out.println("검색 : W");		
		// 1. contains 배열
		Car[] searchList = CM.searchByModelName("W");
		for(Car W : searchList)
			System.out.println(W);
		// 2. contains 그냥
		System.out.println(CM.searchByModelName2("K"));
		// 3. equals 배열
		Car[] searchList2 = CM.searchByModelName3("WOW");
		for(Car W : searchList2)
			System.out.println(W);
		// 4. equals 그냥
		System.out.println(CM.searchByModelName4("K5"));
		
		System.out.println();
		
		for(int i = 0; i < CM.getList().length; i++) {
			System.out.println(CM.getList()[i]);
			
		}
	
	}

}

/* output

CarTest [VIN=QWERTY, modelName=K5, color=BLACK, mileage=15000]
CarTest [VIN=ASDFGH, modelName=WOW, color=BLUE, mileage=4000]

검색 : W
CarTest [VIN=ASDFGH, modelName=WOW, color=BLUE, mileage=4000]
CarTest [VIN=QWERTY, modelName=K5, color=BLACK, mileage=15000]
CarTest [VIN=ASDFGH, modelName=WOW, color=BLUE, mileage=4000]
CarTest [VIN=QWERTY, modelName=K5, color=BLACK, mileage=15000]

CarTest [VIN=QWERTY, modelName=K5, color=BLACK, mileage=15000]
CarTest [VIN=ASDFGH, modelName=WOW, color=BLUE, mileage=4000]

*/

'JAVA 때려잡기' 카테고리의 다른 글

230127 컬렉션  (0) 2023.01.28
230126 인터페이스, 제네릭  (0) 2023.01.27
230125 추상클래스  (0) 2023.01.25
#가위바위보 게임(5판3선승, 3판2선승, 단판승)  (0) 2023.01.24