자바에서 사용되는 3가지 변수에 관한 내용
1) 변수 (variable)
배열, 컬렉션 ==> 참조형 변수
=> stack 할당
=> heap 할당 , 자동 초기화
package array.test;
public class Ex05_4 {
public static void main(String[] args) {
// new
int [] num;
num = new int[4];
num[0] = 1;
num[1] = 2;
num[2] = 3;
// literal
int [] num = {1,2,3,4};
/*int [] num;
* num = {1,2,3};
*/
for(int x :num) {
System.out.println("정수 배열 값: "+x);
}
// new, literal 사용
int [] num;
num = new int[] {1,2,3};
for(int x : num) {
System.out.println(" 정수 배열 값: "+x);
}
}
가) 배열 선언
int [][] n;
String [][] s;
대괄호의 갯수가 차원을 결정
나) 배열 생성 (1): 정방형
모든 열의 크기가 동일
n = new int [3][2];
행의 길이 구하기: n.length
열의 길이 구하기: n[0].length
다) 배열 생성 (2): 비정방형
(행의 열 크기가 다름)
행의 크기만 지정해주고, 열의 크기는 동적으로 할당하는 방식
n = new int [3][ ];
=> 열 크기 지정 x
라) 배열 생성 : 열 생성
n[0] = new int [2] ;
=>0행에 2열을 삽입
n[1] = new int [1];
=>1행에 1열을 삽입
n[2] = new int [3];
=>2행에 3열을 삽입
int[][] scores = {{1, 2}, {3, 4, 5}};
int [][] num = new int[3][];
2) 열 생성
3) 초기화
package workshop;
import java.util.Scanner;
public class Test16 {
public static void main(String[] args) {
// 2차원 배열
// 가. new 이용
int [][] n;
String [][] s;
// 나. 배열 생성 ( 정방형 : 모든행의 열 크기가 동일)
n = new int[3][2];
s = new String[3][2];
// 다. int형 배열 초기화 (자동 초기화x)
n[0][0]=1;
n[0][1]=2;
n[1][0]=3;
n[1][1]=4;
n[2][0]=5;
n[2][1]=6;
// 다. String형 배열 초기화 (자동 초기화x)
s[0][0]="A1";
s[0][1]="A2";
s[1][0]="A3";
s[1][1]="A4";
s[2][0]="A5";
s[2][1]="A6";
// for each 문 사용해 초기화
for (int[] arr : n)
{
for (int x : arr)
System.out.println(x);
}
System.out.println();
// for each 문 사용해 초기화
for (String[] arr : s)
{
for (String x : arr)
System.out.println(x);
}
System.out.println();
// 이중 for 문 사용해 초기화 (int형 배열)
for(int i =0; i<n.length;i++) {
for(int j =0;j<n[i].length;j++)
{
System.out.println("n["+i+"]"+"["+j+"]"+"="+n[i][j]);
}
}
System.out.println();
// 이중 for 문 사용해 초기화 (String형 배열)
for(int i =0; i<s.length;i++) {
for(int j =0;j<s[i].length;j++)
{
System.out.println("s["+i+"]"+"["+j+"]"+"="+s[i][j]);
}
}
}
}
실행 결과
비정방형
new
package exam02;
public class ArrayTest8 {
public static void main(String[] args) {
// 2차원 배열
// 가. new 이용
int [][] n;
String [][] s;
// 나. 배열 생성 - 행크기 생성 (비정방형 : 행의 열 크기가 다름)
n = new int [3][];
s = new String [3][];
// 다. 배열 생성 - 열 생성 (서로 다른 크기의 열을 동적으로 생성함)
n[0] = new int[2];
n[1] = new int[2];
n[2] = new int[3];
s[0] = new String[2];
s[1] = new String[2];
s[2] = new String[3];
// 라. 배열 초기화
n[0][0] = 1;
n[0][1] = 2;
n[1][0] = 3;
n[1][1] = 4;
n[2][0] = 5;
n[2][1] = 6;
s[0][0] = "A1";
s[0][1] = "A2";
s[1][0] = "A3";
s[1][1] = "A4";
s[2][0] = "A5";
s[2][1] = "A6";
for (int[] arr : n) {
for (int x : arr) {
System.out.println(x);
}
}
for (int i = 0; i < n.length; i++) {
for (int j = 0; j < n[i].length; j++) {
System.out.printf("n[%d][%d] = %d \n", i, j, n[i][j]);
}
}
}
}
package exam02;
import java.util.Scanner;
public class ArrayTest9 {
public static void main(String[] args) {
// 2차원 배열
// 가. literal 이용
// 선언과 동시에 초기화
int [][] n = {{1,2},{3},{4,5,6}}; // 비정방형 => 열의 크기가 다름
String [][] s = {{"A", "B"}, {"C"},{"D", "E", "F"}};
// 이중 for 문 사용해 초기화 (int형 배열)
for(int i =0; i<n.length;i++) {
for(int j =0;j<n[i].length;j++)
{
System.out.println("n["+i+"]"+"["+j+"]"+"="+n[i][j]);
}
}
System.out.println();
// 이중 for 문 사용해 초기화 (String형 배열)
for(int i =0; i<s.length;i++) {
for(int j =0;j<s[i].length;j++)
{
System.out.println("s["+i+"]"+"["+j+"]"+"="+s[i][j]);
}
}
}
}
package exam02;
public class ArrayTest8 {
public static void main(String[] args) {
// 2차원 배열
// 가. new 이용
int [][] n;
String [][] s;
// 나. 배열 생성 - 행크기 생성 (비정방형 : 행의 열 크기가 다름)
n = new int [3][];
s = new String [3][];
// 다. 배열 생성 - 열 생성 (서로 다른 크기의 열을 동적으로 생성함)
n[0] = new int[2];
n[1] = new int[1];
n[2] = new int[3];
s[0] = new String[2];
s[1] = new String[1];
s[2] = new String[3];
// 라. 배열 초기화
n[0][0] = 1;
n[0][1] = 2;
n[1][0] = 3;
n[2][0] = 4;
n[2][1] = 5;
n[2][1] = 6;
s[0][0] = "A1";
s[0][1] = "A2";
s[1][0] = "A3";
s[2][0] = "A4" ;
s[2][1] = "A5" ;
s[2][2] = "A6" ;
for (int[] arr : n) {
for (int x : arr) {
System.out.println(x);
}
}
for (int i = 0; i < n.length; i++) {
for (int j = 0; j < n[i].length; j++) {
System.out.printf("n[%d][%d] = %d \n", i, j, n[i][j]);
}
}
}
}
http://www.tcpschool.com/java/java_api_arrays
package exam02;
// 배열 사용시 도움을 받을 수 있는 배열 유틸리티 클래스
import java.util.Arrays;
import java.util.List;
public class ArrayTest11 {
public static void main(String[] args) {
// 1. 배열값 출력 (문자열로 출력)
int [] n = {10, 20, 30};
String [] s = {"A", "B", "C"};
System.out.println(Arrays.toString(n));
System.out.println(Arrays.toString(s));
// 2. 값 변경: 모든 배열 값이 변경
String [] s2 = {"A", "B", "C"};
Arrays.fill(s2, "X");
System.out.println(Arrays.toString(s2));
// 3. 값 변경: 일부분 배열값이 변경
String [] s3 = {"A","B","C", "D", "E", "F"};
Arrays.fill(s3, 0,4,"X");
System.out.println(Arrays.toString(s3));
//4. 값 비교
int [] x = {1,2,3};
int [] x2 = {1,2,3};
System.out.println(Arrays.equals(x, x2));
//5. 정렬 (오름차순(기본), 내림차순)
int [] k = {54,2,1,57,9,74};
Arrays.sort(k);
System.out.println(Arrays.toString(k));
//6. 특정값의 위치 :binarySearch()
//이진 검색 알고리즘을 사용하므로, 매개변수로 전달되는 배열이 sort() 메소드 등을 사용하여
// 미리 정렬되어 있어야만 제대로 동작합니다.
int [] k2 = {54,2,1,57,9,74};
for(int i = 1; i < k2.length; i++) {
k2[i] = i;
}
Arrays.sort(k2);
System.out.println(Arrays.binarySearch(k2, 2));
//7. 배열 길이 변경 (배열 복사) ==> 원래 배열을 복사하면서 배열 길이를 늘리는 방식
int [] y = {1,2,3};
int [] y2 = Arrays.copyOf(y, 5);
System.out.println(Arrays.toString(y));
System.out.println(Arrays.toString(y2));
// 8. 개별적인 값들을 컬렉션 API로 생성 ( ******* )
// import 필
// import java.util.List;
List<String> list = Arrays.asList("A", "B", "C");
System.out.println(list); // [A, B, C]
List<Integer> list2 = Arrays.asList(10, 20, 30);
System.out.println(list2); // [10, 20, 30]
}
}
package array.test;
public class Ex05_5 {
public static void main(String[] args) {
int [][] num = {{1,2},{3,4},{5,6,7}};
for(int i =0; i<num.length;i++)
for(int j =0;j<num[i].length;j++)
{
System.out.println("num["+i+"]"+"["+j+"]"+"="+num[i][j]);
}
}
}
int [][] num = new int[][]{{1,2},{3,4},{5,6,7}};
package array.test;
public class Ex05_5 {
public static void main(String[] args) {
int [][] num = new int[][]{{1,2},{3,4},{5,6,7}};
for(int i =0; i<num.length;i++)
for(int j =0;j<num[i].length;j++)
{
System.out.println("num["+i+"]"+"["+j+"]"+"="+num[i][j]);
}
}
}
클래스 구성요소 3가지 : 인스턴스 변수(필드), 메서드, 생성자
oop(object oriented programming)
프로그램 개발하기 위해 필요한
객체 추출/ 속성 추출/ 동작 추출하는 작업 (필요 없는 것들을 구분해낸다)
- 예) 학생 관리 프로그램을 개발
의뢰
=>분석
=>설계
=>
1) 분석
: 현실 세계의 객체 추출
예) 학생 객체, 교수 객체 추출
추출한 객체에서 기능, 속성을 추출
학생 객체
=> 속성
: 학번, 이름, 나이, 주소
학생 객체
=> 동작
: 공부, 운동
2) 설계
: 객체를 프로그래밍 언어(가상세계 java)에 맞게끔 설계하는 과정
분석 단계에서 추출한 학생이라는 객체가, 설계 단계에서 클래스로 변환됨
즉, 설계 단계에서 학생 클래스가 생성
됨
분석 단계에서 추출한 객체의 속성
은 변수(=인스턴스 변수, 필드)
로 생성됨.
분석 단계에서 추출한 객체의 동작
은 메서드
로 생성됨.
상속: 상위 클래스의 특성을 하위 클래스가 물려 받음.
애완동물 관리 프로그램
주문
=> 분석
=> 설계
1) 분석
2) 설계
클래스 형
이므로 (변수 앞에 있는 자료형으로 구분) 참조형 변수에 해당new
로 변수 생성public class Cat{
String name; // 인스턴스 변수(멤버 변수) !
// 메서드 (멤버 메서드)
// 생성자
}
// 인스터스 변수와 메서드는 data 저장
// 생성자는 멤버 변수와 멤버 메서드 변경, 조회, 초기화 가능
public 클래스명() {
}
public Cat() {
} // 생성자
new
생성자 호출 package test.mypac;
public class Car {
//필드 정의하기
public Engine engine;
//객체를 new(생성) 할때 호출되는 생성자
public Car() {
System.out.println("Car() 생성자 호출됨");
}
// Engine 객체를 인자로 전달 받는 생성자
public Car(Engine engine) {
//지역변수에 담긴 값을 필드에 저장하기
this.engine = engine;
System.out.println("Car(Engine engine) 생성자 호출됨");
}
//달리는 메소드
public void drive() {
if(this.engine==null) {
System.out.println("Engine 이 없어서 달릴수가 없어요!");
return; //메소드를 여기서 끝내기
}
System.out.println("신나게 달려요~");
}
}
package p01;
// 애완동물 관리 프로그램 개발
// 1. 분석 단계에서 추출한 객체
/*
* 고양이 객체
* 속성: 이름, 나이, 성별
* 동작: 먹기(), 자기(), 뛰기()
*
* 2. 설계 단계에서 표현 => 클래스로 이용 (main 메서드가 없다)
*
* Cat 클래스 ========> public class
* 고양이 객체에 대응되는 Cat 클래스 생성
*
* 변수(인스턴스변수):
* String name;
* int age;
* String sex;
*
* 메서드: 먹기(), 자기(), 뛰기()
*
*
* */
public class Cat {
// 인스턴스 변수
String name;
int age;
String sex;
// 메서드
}
/* Cat c = new Cat(); // 생성자 호출
* 명시적으로 생성자를 작동안하면 자동으로 생성된다 (기본 생성자)
*
* cf. 명시적 생성
* public Dog() {
System.out.println("Dog 생성자");
}
* */
public Shirt(){} // Default Constructor(기본 생성자)
public Shirt(String m, boolean longs, char c){
// Explicit Constructor(명시적 생성자)
maker = m; // 명시적 생성자가 하는 일 = 필드 초기화(Field Initialization)
longSleeved = longs;
color = c;
}
package p01;
/*
* Cat 클래스를 관리하는 클래스
*
* 1. Cat 클래스를 메모리에 올림 (객체 생성)
*
* 클래스명 변수명 = new 클래스명();
*
* 예> Cat c = new Cat();
*
* 2. Cat 정보를 저장
*
*
* */
public class TestCat {
public static void main(String[] args) {
//Cat 클래스 객체 생성
Cat c = new Cat(); // 생성자 호출
c.name = "야옹이";
c.age = 2;
c.sex = "암컷";
Cat c2= new Cat();
c2.name = "나비";
c2.age =1;
c2.sex = "암컷";
System.out.printf("고양이 이름: %s, 나이: %d, 성별: %s", c.name, c.age, c.sex);
System.out.println();
System.out.printf("고양이 이름: %s, 나이: %d, 성별: %s", c2.name, c2.age, c2.sex);
}
}
package p02;
// 애완 동물
public class Dog {
String name;
int age;
String sex;
// 생성자 : 인스턴스 변수 초기화
public Dog() {
System.out.println("Dog 생성자");
}
}
package p02;
public class TestDog {
public static void main(String[] args) {
Dog d = new Dog(); // 생성자 호출
}
}
생성자 정리
객체 생성할 때 타입이 있어야 하고, new라는 키워드가 있어야 하고, 생성자가 호출되어야 한다.
객체를 생성하면 객체의 멤버(필드, 메소드)가 가상 메모리 JVM 안에 있는 Heap이라는 공간에 올라간다. Heap에는 반드시 new라는 키워드를 통해서 생성된 객체만 올라간다.
객체 생성의 결론 -> Stack에 주소값 할당! 저장된 객체의 위치값이 지정된다.
생성자가 하는 일은 필드 초기화(Field Initialization)이다.(X) - null값을 가지는 기본 생성자도 있음.
★명시적 생성자가 하는 일은 필드 초기화(Field Initialization)이다.(O)
생성자는 메소드 중에서 set메소드와 기능이 같다.(아래 setter 참고) 애초부터 값을 넣어서 만드는 것.
public Cat() { };
public Cat(int n ) { };
package p02;
// 애완 동물
public class Dog {
String name;
int age;
String sex;
// 생성자 : 인스턴스 변수 초기화
// 오버로딩 생성자(over loading)
// ==> 하나의 클래스에 같은 이름의 생성자를 여러 개 지정 가능.
// ==> 구별위해 argumnet list (갯수, 타입, 순서) 달라야 한다.
public Dog() {
System.out.println("Dog 생성자1");
}
public Dog(int a) {
System.out.println("Dog 생성자2");
} // 오버로딩 생성자
public Dog(int a, String a2) {
System.out.println("Dog 생성자3");
} // 오버로딩 생성자
public Dog(String a2, int a) {
System.out.println("Dog 생성자4");
} // 오버로딩 생성자
public Dog(String n, int a, String s) {
System.out.println("Dog 생성자5");
} // 오버로딩 생성자
}
package p02;
public class TestDog {
public static void main(String[] args) {
// 생성자 호출시 설정하는 값: 인자 (argument)
// 인자 안에 설정되어 전달되는 실제 값(즉, 인자의 값을 저장하는 변수): 매개변수(parameter)
Dog d = new Dog(); // 생성자 호출
/*
Dog d1 = new Dog(int a);
Dog d2 = new Dog(int a, String a2);
Dog d3 = new Dog(String a2, int a);
Dog d4 = new Dog(String n, int a, String s);
*/
Dog d1 = new Dog(20);
Dog d2 = new Dog(20, "AA");
Dog d3 = new Dog("AA", 20);
Dog d4 = new Dog("AA",30, "BB");
}
}
package p03;
public class Cat {
// 인스턴스 변수 (필드)
String name;
int age;
String sex;
// 생성자
// 명시적으로 지정해주지 않으면, 기본 생성자가 자동으로 제공됨
// 명시적으로 만들면 기본 생성자는 자동생성 안됨
// public Cat() {} ;
// 명시적으로 여러 생성자 생성 ==> 오버로딩 생성자 (핸들링 클래스 내 호출 해 사용)
public Cat() {}
public Cat(int n) {}
public Cat(String n) {}
public Cat(String n, int a) {}
public Cat(String n, int a, String s) {
name = n;
age = a;
sex = s;
}
// Cat c = new Cat("야옹이", 2, "암컷"); <= Dog.java
// 야옹이가 n에 저장되고, n을 인스턴스 변수 name에 저장 (인스턴스 변수 초기화 수행)
}
package p03;
public class TestCat {
public static void main(String[] args) {
// 객체의 인스턴스 변수 초기화 방법 2가지
// 1. 생성자 사용
// 생성자 이용해서 초기화 하는 방법은 초기화 시점이 가장 빠른 방법이다.
//heap 메모리에 인스턴스 변수 할당 후(객체 생성)과 동시에 값이 초기화 됨
// 생성자 생성 후 핸들링 클래스의 main() { }내 호출하여 사용 필
Cat c = new Cat("야옹이", 2, "암컷");
// 인스턴스 변수에 직접 접근해서 초기화하는 방법은 초기화 시점이 매우 늦다
/* c.name = "야옹이"; // 객체 생성 이후에 name 변수에 값을 할당
c.age = 2;
c.sex = "암컷";
*/
}
}
의문점) 인스턴스 변수를 인자로 모두 포함하는 생성자로 인스턴스 변수 값 초기화 가능한데,굳이 오버로딩 생성자를 만드는 이유는?
현실 세계에서 모르면 명부를 비워두는 논리와 유사~
Cat c = new Cat("야옹이", "암컷");
=> 성별을 모르는 경우
=> 명시적으로 인스턴스 변수 sex에 null을 기재하지 않아도 자동으로 null로 형 변환 발생함
Cat c = new Cat("야옹이");
=> 이름만 아는 경우
=> 명시적으로 인스턴스 변수 sex, age에 null을 기재하지 않아도 자동으로 null로 형 변환 발생함