다차원배열
배열 안에 배열이 있는 배열
자료형[ ][ ] 참조변수 = new 자료형[길이][길이]; 👉 2차원 배열
자료형[ ][ ][ ] 참조변수 = new 자료형[길이][길이][길이]; 👉 3차원배열
자료형[ ][ ] 참조변수 = {{값,값,값,값},{값,값,값,값}}; 👉 2차원배열
다차원배열의 첫번째 배열의 길이는 반드시 정의해야 하지만, 그 외의 배열길이는 배열 생성할 때 결정하지 않아도 된다.
X축, Y축을 이용한 차트를 만들 때 주로 쓴다. 배열 안에 배열이 있는 경우가 많다.
2차원배열 이상은 잘 안 쓴다.
- 2행3열의 2차원배열을 생성하고, 배열의 인덱스를 이용해서 배열의 각 칸에 값을 대입하기
int[][] numbers1 = new int[2][3];
numbers1[0][0] = 100; // numbers[0]번째 칸의 주소값으로 참조되는 배열의 0번째 칸에 100을 대입한다.
numbers1[0][1] = 110; // (0,1)에 110을 넣는다.
numbers1[0][2] = 120;
numbers1[1][0] = 200;
numbers1[1][1] = 210;
numbers1[1][2] = 220;
실제로 메모리 안에 생성되는건 다르게 생성된다. 2칸 짜리가 먼저 생성된 수에 3칸 짜리가 2개 생긴다.
new int[2][3]이기 때문에 length3짜리 2개가 생성된다. 그렇기 때문에 앞의 행은 꼭 만들어져야 한다.
- 배열 리터럴을 이용해서 배열 생성하기
// 2행3열의 2차원배열 생성하기
int[][] numbers2 = {{300,310,320},{400,410,420}};
// 2행n열의 2차원배열 생성하기
int[][] numbers4 = {{700, 710, 720},{800, 820, 820, 830, 850, 860}};
꼭 정방형이 아니어도 상관 없다.
- 행의 크기만 결정하고, 열의 크기는 지정하지 않고 배열 생성하기
int[][] numbers3 = new int[2][3];
numbers3[0] = new int[]{500, 510, 520};
numbers3[1] = new int[]{600, 610, 620}; //이럴땐 int[2][3]에서 3을 생략해도 된다 => int[2][]
int[][] numbers5 = new int[2][];
// 행배열(row array)의 0번째 칸에 열배열(column array)을 생성해서 연결시키기
numbers3[0] = new int[]{900, 910};
// 행배열(row array)의 1번째 칸에 열배열(column array)을 생성해서 연결시키기
numbers3[1] = new int[]{1000, 1010, 1020, 1030, 1040, 1050};
다차원 배열 출력하기
// 다차원 배열의 값 입력하기
int[][] numbers = {{10, 20, 30}, {40, 50, 60}};
- for문을 사용해서 다차원 배열 출력하기
for (int x = 0; x < numbers.length; x++) {
for (int y = 0; y < numbers[x].length; y++) {
int number = numbers[x][y];
System.out.println("["+x+"]["+y+"] " + number);
}
}
numbers가 바라보는 배열의 길이니까, x<2 대신 x<numbers1.length
numbers[0]이 바라보는 배열의 길이 = 3, numbers[1]이 바라보는 배열의 길이 = 3 이니까, y<numbers1[x].length
String[][] names = {{"김유신", "강감찬", "이순신"}, {"류관순", "안중근", "이봉창", "안창호", "김구", "윤봉길"}};
- 향상된-for문을 사용해서 다차원 배열 출력하기
for (String[] array : names) {
for(name : array) {
System.out.println(name);
}
}
array은 문자열을 여러 개 가지고 있는 배열이다.
array가 names의 0번째 배열이 대입되고, 안쪽 for문이 한 번 실행된다.
array가 names의 1번째 배열이 대입되고, 안쪽 for문이 한 번 실행된다.
객체지향프로그래밍
이제부터 자바의 핵심적인 내용을 배운다. 객체지향프로그래밍 언어에 대한 이해가 있어야 Spring이해도 훨씬 쉬워진다.
객체지향프로그래밍
- 부품에 해당하는 객체들을 만들고, 그 객체를 조립해서 소프트웨어를 만드는 개발방식이다.
- 부품에 해당하는 객체 : Instance, Object, Bean
메모리 안에 사용가능한 상태로 만들어져 있다. 어떻게 만들어지는지는 알 수 없다. 참조 변수를 통해 간접적으로 접근한다. 객체는 TV, 참조변수는 리모컨이라고 생각해보자. TV에 있는 기능들을 사용하려면 리모컨이 필요하다.
- 부품에 해당하는 객체를 생성하기 위한 설계도가 필요하다.
- 설계도 : class
우리는 class를 만들어야 한다. class와 함께 하나 더 만들어야 할 것이 있는데, 우리는 다른 설계도가 여러개 있어서 다른 클래스가 class1을 사용하는 것이 일반적이다. 이것을 객체와 객체간에 관계가 있다고 한다. 그 관계들도 설계도 안에 적어야 한다. 부품에 해당하는 객체를 만들고 조립해서 소프트웨어로 완성해가는 방식이다.
우리는 먼저 객체 안에다가 구성요소를 넣어야 하는데, 그 구성요소를 포함시키는 방법을 먼저 배운다.
객체지향프로그래밍언어의 주요 장점
- 재사용성이 높다. (👈상속)
새로운 코드를 작성할 때 기존코드를 사용할 수 있는데, 이를 상속이라고 부른다.
부모클래스에 저장되어있는 것을 자식클래스에서 물려받는다.
클래스에서 공통적으로 가지고 있는게 있으면, 빠르게 새로운 클래스를 만들 수 있다. 효율적인 코딩을 위해 코드의 재사용성이 높다.
- 코드의 관리가 용이하다.
예를들어 데이터베이스와 연결해서 실행하고 있는 프로그램이 있었는데, 클라우드하고만 연결해서 사용하고싶을 때 기존의 클래스와 연결을 끊고 새로운 클래스를 만들어 연결하면 된다. 즉, 다른 기능으로 바꾸기 쉽다.
- 신뢰성이 높은 프로그래밍을 가능하게 한다. (👈캡슐화)
"신뢰성이 높다."는 것은 접근제한자와 메소드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 한다는 것이다. 이것을 캡슐화 라고 부른다. 코드의 중복제거, 리팩토링을 통해서 코드의 중복을 제거하고 유지보수하기 쉽게 코드들을 재조정한다. 특징 중에 가장 큰 것이 캡슐화인데, 은닉화라고 하기도 한다.
자동차의 속도를 올리는 방법을 예로 들자면, 엑셀을 밟아야 속도가 올라간다는 것은 공개된 범위라고 말할 수 있다. 하지만 알려지지 않은 방법으로도 속도를 올릴 수 있을 것이다. 이것은 은닉이라하고, 값에 대한 접근은 공개된 기능을 통해서만 접근할 수 있다. 기능은 메소드에서 담당하고, 과도한 것인지는 메소드가 조절을 한다.
객체지향프로그램의 주요 특징
- 캡슐화
구현내용을 감춘다. 모두 공개해두게되면 잘못 사용함으로써 객체가 손상될 수 있다. 손상되는 것을 방지하기 위해 특정기능만 공개하고, 공개된 기능을 통해서만 객체를 사용할 수 있게 한다. 접근제한자를 통해 공개할 것인지, 비공개할 것인지 정한다.
- 상속
새로운 클래스를 만들 때 기존의 부모클래스의 구성요소들을 이용할 수 있다.(물려받을 수 있다) 재사용하기 때문에 하위클래스를 빠르게 만들 수 있다. 비슷한 기능에 대한 새로운 요구사항이 접수되면 빠르게 대응할 수 있다. (부모)상위클래스와 (자식)하위클래스는 종속관계가 성립된다. 즉,
사자 a = new 사자();
호랑이 b = new 호랑이();
원숭이 c = new 원숭이();
// 좌변의 사자, 호랑이, 원숭이는 타입을 나타낸다.
그 타입에 맞는 변수를 만들어야 한다.
사람 d = new 고양이 ( ); // 이건 안 된다.
포유류 x = new 사자( );
포유류 y = new 호랑이( );
포유류 z = new 원숭이( );
이건 가능하다.
포유류라고 하는 클래스를 상속받아 만들면, 클래스를 조직화 할 수 있다. 그래서 엄청엄청엄청 많이 활용된다.
- 다형성✨✨
같은 종류의 객체지만, 실행결과가 다양한 객체를 이용할 수 있는 성질을 다형성이라고 한다.
사용방법은 동일하지만, 사용하는 객체가 변경되면 실행결과가 다르게 구현된다. 컴퓨터의 흑백프린터와 컬러프린터를 예로 들 수 있겠다.
그럼 다형성을 어디에 써먹을까?
제일 중요한 것은 사용법이 다 똑같아야 한다는 점이다.
내가 UserService에서 save기능을 사용하고 싶은데, 다 save라는 기능을 가지고 있다. 똑같은 save인데 구현내용이 다르다.
- UserService객체에 어떤 Repository객체가 조립되느냐에 따라서 회원정보를 저장하는 방식이 달라지게 된다.
- UserService객체에서 회원정보를 저장하기 위해서 실행하는 메소드는 repository.save(user)라는 메소드를 실행한다.
- repository 참조변수에 실제로 조립된 객체에 따라서 회원정보가 데이터베이스, 네트워크, 클라우드에 저장될 수 있다.
- 회원정보를 저장하는 방식은 동일하지만 어떤 객체를 실제로 사용하는가에 따라서 회원정보가 특정한 저장소에 저장될 수 있다.
그러면 프로그램 확장성이 엄청 좋아진다. 필요한 객체만 만들어서 조립해서 사용하면 되니까. 객체지향프로그램에서 제일 핵심적인 내용은 다형성이라고 꼽을만큼 엄청엄청엄청엄청 중요한 특징이다.
객체
- 우리가 프로그램할 대상이 되는 것.
- 물리적으로 존재하거나 추상적으로 생각할 수 있는 것.
- 객체는 고유한 속성과 기능을 가지고 있다.
- 다른 객체와 고유하게 구별되는 것은 속성, 같은 객체여도 다른 속성을 가지고 있다. 구별하게 해주는 정보. 객체가 갖고 있는 값, 정보이다.
- 같은 설계도로 만들어진 객체는 기능(자동차 출력, 브레이크..)은 똑같다. 속성(자동차 색, 속도..)은 다 다르다.
- 자바를 사용할 땐 프로그램이 되는 객체를 먼저 뽑아낼 수 있어야 한다.
- 객체는 클래스의 인스턴스(실제로 메모리상에 할당되는 것)다.
- 객체간의 관계 : 사용관계, 상속관계, 집합관계
- 사람은 자동차를 사용한다. = 사용관계
- 자동차는 기계에 포함된다. = 상속관계
- 엔진, 타이어, 핸들을 모아서 자동차를 만든다. = 집합관계
객체를 만들기 위해 설계도를 먼저 만들어야 한다.
설계도에는 두 종류가 있다. 개발자용 설계도( .java)와 자바가상머신용 설계도( .class). class를 읽어서 객체를 생성한다.
참조변수를 사용해서 사용 가능해진 것을 객체라고 한다.
new연산자를 사용하면 클래스로부터 객체를 생성할 수 있다. 👉 new 클래스명
new Car( );
Car( ); 생성자 메소드
class의 이름과 똑같은 이름을 가진 메소드. 그것을 생성자 메소드라고 부른다.
왜 생성자 메소드를 사용했을까?
객체가 생성되자마자 실행하고 싶은 수행문이 있을 때, 그러려면 객체를 만들고 난 다음 메소드를 실행해야한다. 수행문은 메소드 안에만 적을 수 있다. 생성되자마자 수행문을 실행시키고 싶으면 그 메소드 이름을 뭘로 하는게 좋을까?
클래스 이름이랑 똑같이 짓자.
장점 1. 어떤 설계도를 가지고 객체를 만들어야되는지 알 수 있다.
장점 2. 객체가 만들어지자마자 어떤 메소드를 실행해야 하는지 알 수 있다.
객체는 메모리의 heap힙 영역에 만들어진다.
객체 생성하기
참조변수 = new 클래스명( );
무슨 타입으로 해야할까?
- 기본자료형 변수 : boolean, byte, short, int, long, float, double, char
int a;
// 정수값 담는 변수 a를 생성함
double b;
// 실수값 담는 변수 b를 생성함
- 참조자료형 변수 : 기본자료형 변수를 제외한 모든 변수. 참조자료형 변수는 설계도의 이름이 곧 변수의 타입이다.
String c;
// String 설계도로 생성된 객체의 참조값(주소값)을 담는 참조변수 c를 생성함
// 문자열을 포함하고 있는 String객체의 참조값(주소값)을 담는 참조변수 c를 생성함
Book d;
// Book 설계도로 생성된 객체의 참조값(주소값)을 담는 참조변수 d를 생성함
new라는 연산자로 객체가 바로 만들어지게 된다. 연결이 끊어졌다고 객체가 사라지는건(clean) 아니다. 언제 없어지냐면 프로그램이 휴지상태일때, 메모리가 부족할 때 가비지컬렉터가 청소한다. 가비지 컬렉터 수행방식을 조절할 수는 있는데, 성능튜닝이라는 책같은 곳에 방법이 나와있다. 자바개발과는 무관하게 자바의 성능 튜닝하는 기법들이 있다. 거기서 수행전략을 조절할 수 있다.
클래스
클래스는 필드, 생성자, 메소드로 크게 세 파트로 나뉘어져 있다.
필드 : 객체의 데이터 저장
생성자 : 객체 생성시 초기화 역할 담당, 객체가 생성되자마자 실행된다.
메소드 : 객체의 고유한 기능을 정의
- 필드
필드, 프로필, 멤버변수, 인스턴트변수 모두 같은 말이다.
다른 객체랑 구분짓는 고유한 속성, 변수와 비슷한 형태로 정의한다.
필드는 객체를 생성한 다음에 사용할 수 있다.
참조변수를 사용해서 필드에 값을 저장하거나, 값을 사용할 수 있다.
객체가 생성되면 각각의 필드는 해당 데이터타입의 기본값으로 자동으로 초기화된다. (초기화값을 지정하지 않는 경우)
정수형 : 0 , 실수형 : 0.0 , 문자형 : '\u0000' , 불린형 : false , 참조자료형: null
객체가 사라질 때까지 유지된다.
객체 내의 다른 구성요소(생성자, 메소드)에서 사용할 수 있다.
메소드 안에서는 변수라고 부르고, 클래스 안에서는 필드라고 부른다.
변수의 차이점을 서술하자면,
1. 변수는 메소드 안에서 선언한다. 지역변수(Local variable)라고 한다.
2. 변수는 선언한 그 메소드 안에서만 사용 가능하다. 다른 메소드에서 사용할 수 없다.
3. 메소드의 실행이 종료되면 즉시 사라진다.
4. 변수가 자동으로 초기화되지 않기 때문에 반드시 초기화한 후에 사용해야 한다.
그럼 언제 클래스를 만들어야 할까?
첫번째 경우. 서로 다른 타입의 값으로 구성된 정보를 저장하는 경우.
값 하나를 저장하자
int x = 10;
String y = "체다치즈";
같은 타입의 값을 여러개 저장하자.
int[] x = {10, 20, 30, 40};
String[] y = {"치즈", "길동", "유신", "순신"};
서로 다른 타입의 값으로 구성된 정보를 저장하자.
👉 여러 값이 모여서 정보가 된다 👉 여러 값의 타입이 다 다르네? 👉 클래스를 만든다✨
학생정보, 부서정보, 사원정보, 주문정보, 책정보, 상품정보, 영화정보, 예매정보, 게시글정보, ...
클래스는 사용자정의 자료형이다. 객체를 자료형으로 쓰려고 사용한다.
프로그램 대상이 되는 정보를 저장하는 객체를 VO(ValueObject : 값 객체)라고 한다.
public class Student {
int no;
int grade;
String name;
String email;
boolean isGraduated;
} // 이거 한 뭉탱이를 VO라고 한다.
참고로, DAO(Database Access Object) 안에는 insert, update, 게시글 전부 조회, 게시글 한 개 가져오기, 게시글 전부 삭제하기 이런 기능들이 부여되어 있다. 전부 기능밖에 없다. 데이터베이스 엑세스 기능이 부여되어있는
다양한 역할의 클래스를 만들 것이다. 그 중 하나가 VO이다. 값을 저장할 목적으로 객체를 만드는 것을 위한 설계도를 만들 것이다.
모든 객체는 Object의 자식이다. 즉, Object의 기능을 다 쓸 수 있다.
값 담아보기
여러 종류의 값을 담고있는 객체를 참조변수 하나로 참조할 수 있으니까 참조변수 하나만 알고 있으면 타입이 다르더라도 모든 값에 접근할 수 있다.
학생이름 | 국어점수 | 영어점수 | 수학점수 |
"홍길동" | 100 | 90 | 80 |
"김유신" | 80 | 80 | 70 |
"강감찬" | 70 | 70 | 100 |
우리는 같은 값만 담을 수 있어서 세로줄로 담았다. 그러면 한 사람의 정보가 흩어질 수밖에 없다. 응집력있게 한 곳으로 모으기 위해 클래스를 사용하여 저장할 것이다.
public class Score {
String name;
int kor;
int eng;
int math;
}
바이트 코드는 JVM이 이해하는 코드이다.
객체가 되고나면 실제로 저장소가 생긴다. 객체에 값을 담기위해 참조변수를 사용해야한다.
stud1.no = 1000;
코딩을 하면 이 그림이 자꾸 그려져야 한다. 그래야 내가 뭘 하는지 파악할 수 있으니까. 시각화하는 연습을 하자!
자바는 항상 객체를 가지고 장난친다. 그 객체 안에는 여러가지 구성요소가 들어있고, 그 객체를 만들기 위해 클래스를 정의한다. 항상 객체를 만들어서 객체를 조립해야한다. 어떤 부품인지 알아야 내가 코딩이 쉽다.
배열을 이용하여 값 담기
위의 코딩을 참고해서 여러 권의 책을 담아보자
Book book1 = new Book();
Book book1 = new Book();
Book book1 = new Book();
...
수많은 책이 있다면 이렇게 담기는 현실적으로 어려울 것이다. 그렇다면 배열을 이용해서 담아보자.
Book[] books = new Book[5]; // 같은 객체여도 가능하다. 같은 객체도 같은 타입이다.
객체메모리에 있는 공간이 배열객체의 필드이다.
우리의 목적은 변수를 많이 만드는게 아니라, book 하나 가지고 정보를 매달아 놓고 싶은 것이다. 위의 사진을 보면 배열에 객체 2개가 매달려 있다. books로 book객체 2개를 관리할 수 있다. 객체를 여러개 담아다닐 수 있다.
잠깐 다차원배열 이야기를 해보자. 엑셀에 보면 행과 열이 있다. 거기에 코딩한 값을 넣어보면
no | title | author | publisher | price | discountPrice | stock | onSell | unPublished |
100 | 자바의 정석 | 홍길동 | 한빛미디어 | 35000 | 3200 | 10 | TRUE | FALSE |
200 | 혼자공부하는 자바 | 김유신 | 한빛미디어 | 28000 | 26500 | 5 | TRUE | FALSE |
다차원 배열은 같은 타입의 값만 담는다. 우리의 프로그래밍 대상이 되기에는 너무 부족하다.
한 행에 해당되는걸 한 객체로 만들어버리면, 1차원배열, 선형적인 구조만 있으면 된다. 다차원배열은 그래서 필요 없다.
우리가 다루는건 엑셀에 사용하는 표의 형태로 가능하다. 클래스 하나가 행 하나가 된다.
참고로 자바스크립트에서 차트그릴때 다차원배열을 쓰는데, 자바스크립트에서는 같은 배열에 다른 타입의 값도 담을 수 있다. 자바스크립트는 자바와 다르게 타입이 느슨한 언어이다.
맨 처음의 질문에 다른 타입의 값들을 응집력있게 묶을때 클래스를 사용한다고 결론이 내려진다.
그렇다면 어디에 활용될까?
예를 들어, 유튜브 홈화면에 여러 영상들의 섬네일로 가득한데, 그 중 하나의 영상의 정보를 보자면 그 영상 하나에 섬네일, 프로필, 제목, 영상길이, 채널이름, 스트리밍여부, 10만배지 등의 값들이 모여있다. 이렇게 하나가 하나의 객체인 것이다.
다시 돌아와서, 우리는 book1, boo2, book3,...,book20 이렇게 줄 순 없다.
그래서 books배열에 예쁘게 담아서 주소값(참조값)을 준다.
코딩하기
- Book.java 만들기
- 책번호, 제목, 저자, 출판사, 가격, 할인가격, 재고수량, 판매여부, 절판여부를 저장하는 필드 정의하기
public class Book {
int no;
String title;
String author;
String publisher;
int price;
int discountPrice;
int stock;
boolean onSell;
boolean unPublished;
}
// 프로그램 대상이 되는 것을 먼저 도출해내야 한다. 그것이 코딩의 시작
- BookApp.java 만들기
- main메소드를 만들어, books 참조변수가 참조하는 배열의 저장된 책정보 출력하기
public class BookApp {
public static void main(String[] args) {
// new Book[2] : Book객체를 참조하는 참조값을 2개 저장할 수 있는 배열을 생성한다.
// Book[] books : Book 설계도로 만들어진 Book객체 여러개 저장하는 배열객체의 참조값을 저장하는 변수를 생성한다.
Book[] books = new Book[2]; // 같은 객체여도 가능하다. 같은 객체도 같은 타입이다.
// 첫번째 책정보 저장하는 객체를 생성하고, 책정보를 필드에 대입함
Book book1 = new Book();
book1.no = 100;
book1.title = "자바의 정석";
book1.author = "남궁성";
book1.publisher = "도우출판사";
book1.price = 35000;
book1.discountPrice = 32000;
book1.stock = 5;
book1.onSell = true;
book1.unPublished = false;
// 두번째 책정보 저장하는 객체를 생성하고, 책정보를 필드에 대입함
Book book2 = new Book();
book2.no = 200;
book2.title = "혼자 공부하는 자바";
book2.author = "신용권";
book2.publisher = "한빛미디어";
book2.price = 32000;
book2.discountPrice = 29000;
book2.stock = 10;
book2.onSell = true;
book2.unPublished = false;
// 첫번째 책정보 객체의 참조값을 배열의 0번째 칸에 대입함
books[0] = book1;
// 두번째 책정보 객체의 참조값을 배열의 1번째 칸에 대입함
books[1] = book2;
System.out.println("객체정보 확인하기");
System.out.println("book1이 참조하는 객체의 정보: " + book1);
System.out.println("book2이 참조하는 객체의 정보: " + book2);
System.out.println("books[0]이 참조하는 객체의 정보: " + books[0]); // book1과 같은 값이 나온다.
System.out.println("books[1]이 참조하는 객체의 정보: " + books[1]); // book2와 같은 값이 나온다.
// books 참조변수가 참조하는 배열의 저장된 책정보 출력하기
for (Book book : books) {
System.out.println(book.no + ", " + book.title);
} // books가 바라보는게 주소값. 따라가면 book객체, 출력은 주소값 따라가서 book title을 출력.
// 객체가 달려있다는 것을 기억하자.
}
}
우리가 앞으로 해야할 일은 웹브라우저에 전달하는 일이다. 우리는 역할을 나눠서 일을 하게 된다. 다른 팀에게 줄 때 예쁘게 한번에 배열, list에 담아서 줘야 한다. 쉽게 주고받아야하고, 객체를 사용해서 여러 종류를 담을 수 있어야한다.
항상 생각해야하는건
어디에 담아야 하는지?
담으려면 뭘 만들어야 하는지?
데이터는 한 개? 여러개를 줘야하는지?
생각하면서 코딩해야한다.
앞으로 배워야할 것은 데이터베이스에서 가져오기, 웹브라우저에 전달하기 이렇게 배우면 된다.
'Skill Tree🌲 > coding_package' 카테고리의 다른 글
Java 웹개발자 과정 8일차 - 중복정의, 생성자, this, 프로그램만들기(1) (0) | 2022.03.17 |
---|---|
Java 웹개발자 과정 7일차 - 메소드 (0) | 2022.03.16 |
Java 웹개발자 과정 5일차 - 약간의 메소드, 배열 (0) | 2022.03.12 |
Java 웹개발자 과정 4일차 - switch문, for문, 이중for문, Scanner (0) | 2022.03.08 |
Java 웹개발자 과정 3일차 - 비교연산자, 논리연산자, 삼항연산자, if문, 변수의 스코프, 내포된 if문과 빠른 종료 (0) | 2022.03.06 |