230803 생성자 constructor, 배열 array
[23.08.03] 9일차
<<진도>>
- 과제풀이 (Instance)
* 객체지향 프로그래밍
- 생성자 constructor
- 참조변수 : this.멤버(변수/메서드)
- 생성자 호출 : this()
- 배열
: 1차원 배열, 2차원 배열, 배열명.length
<<오늘의 팁>>
- InstanceQuiz01
class Robott {
// 멤버변수 : field
// -인스턴스 변수(객체 변수)
int productYear;
String productName;
// setter / getter
public int getProductYear() {
return productYear;
}
public void setProductYear(int productYear) {
this.productYear = productYear;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public void showInfo() {
System.out.println(productYear);
System.out.println(productName);
}
}
// [클래스 동일]-====================================================
public class InstanceQuiz01 {
public static Robott constructRobot(int year, String name) {
Robott robot = new Robott(); // 호출 할때마다 ' new ' 새로운 Robot 객체를 생성
robot.setProductYear(year);
robot.setProductName(name);
return robot; // 리턴값이 참조변수가 됐다.
}
public static void main(String[] args) {
// 메서드를 호출 할 때 로봇의 생산년도, 제품명을 지정출력
// [문제] constructRobot() 메서드를 호출할 때,
// 로봇의 생산년도, 제품명을 지정하시오
// -----------------------------------------------
// 생산년도 제품명
// -----------------------------------------------
// robot : 2003 페퍼
// robotTwo : 2007 아틀라스
// -----------------------------------------------
Robott robot = constructRobot(2003, "페퍼");
System.out.printf("robot : %d %s\n", robot.getProductYear(), robot.getProductName());
Robott robotTwo = constructRobot(2007, "아틀라스");
System.out.printf("robotTwo : %d %s\n", robotTwo.getProductYear(), robotTwo.getProductName());
}
}
[풀이] ====================================================================
public class InstanceQuiz01 {
public static Robott constructRobot(int year, String name) {
Robott robot = new Robott(); // 호출 할때마다 ' new ' 새로운 Robot 객체를 생성
robot.setProductYear(year);
robot.setProductName(name);
return robot; // 리턴값이 참조변수가 됐다.
}
public static void main(String[] args) {
//지역변수 : local variable
Robott robot = constructRobot(2003, "페퍼");
System.out.println("참조변수 robot에 저장된 주소 >> " + robot);
System.out.printf("robot : %d %s\n", robot.getProductYear(), robot.getProductName());
Robott robotTwo = constructRobot(2007, "아틀라스");
System.out.println("참조변수 robotTwo에 저장된 주소 >> " + robotTwo);
System.out.printf("robotTwo : %d %s\n", robotTwo.getProductYear(), robotTwo.getProductName());
}
}
[객체 생성 순서]
1. 메모리 할당
2. 생성자 constructor 실행
(없으면 기본생성자라도 실행)
★ 객체는 (변수처럼)선언 이라고 하지않는다.
단순히 할당만 하는 것이 아닌 생성자(메서드)를 실행해야하기 때문
이다.
- ConstructorEx01
/*
* [생성자] constructor
* <<생성자를 사용하는 이유>>
* - 객체 생성하면서, 멤버변수 원하는값으로 초기화
* - 객체 생성하면서, 원하는 기능을 실행하기 위해서(특정 멤버메서드 실행)
*
* <<생성자의 특성>>
* - 객체 생성시, 무조건 하나의 생성자 호출 (실행)
* - 생성자는 '메서드'이다 -> '메서드 오버로딩'가능 -> 생성자 여러개 정의 가능
* ※) 메서드 오버로딩 : method overloading
* * 메서드명이 같고, 매개변수의 정보가 다르다
* (자료형, 개수)
* * 단, 반환형과는 관련 없음
*
* - 생성자는 반환형이 아예 없음(명시하지 않음) -> 리턴값 없음
* - 생성자명은 클래스명과 같아야 함
*
* (객체지향 언어(java 등)에서는 생성자를 명시하지 않으면)
* - <<기본생성자>> : default constructor 실행
* = 매개 변수없고, 하는 일도 없다 -> 객체지향언어 '형식 상의 실행'
* = 생성자가 하나라도 명시되어 있다면, 기본생성자는 실행되지 않는다
*
*
*/
class Student {
// 멤버변수 : field필드
int age; // heap의 인스턴스 안에 들어오는 변수기때문에 객체변수, 인스턴스변수라고 부른다.
String name;
// 기본생성자
// Student() { } // (클래스명과 동일) **단, 명시되는 순간 기본생성자가아님!
// 생성자 생성 =============================================================
// 메서드 오버로딩
//kim
Student(){
showInfo(); // 생성자도 메서드이므로 메서드안에서 메서드 호출가능
}
//lee
Student(int age){
this.age = age;
showInfo(); // 생성자(메서드)안에서 메서드 호출
}
//park
Student(String name){
this.name = name;
showInfo(); // 생성자(메서드)안에서 메서드 호출
}
//hong
Student(int age, String name){ // heap
this.age = age;
this.name = name;
showInfo(); // 생성자(메서드)안에서 메서드 호출
}
[중복되는 메서드가 있을때, 생성자안에 생성자를 호출하는 형태 ]
//kim
Student() {
//오버로딩된 생성자들 안에 showInfo() 메서드가 반복되므로
this(0, null);
// *caution 생성자 안에서 생성자를 호출할때는 이름(메서드취급)대신 this() 형태로 쓴다
// showInfo();
}
//lee
Student(int age) {
this(age, null); //**caution 생성자내에서 생성자 호출은 반드시 제일 먼정 와야한다.
//int num; < 다른 명령어가 오면 신텍스 에러
// this.age = age;
// showInfo();
}
//park
Student(String name) {
this(0, name);
// this.name = name;
// showInfo();
}
//hong // 생성자들에서 호출되는 생성자
Student(int age, String name){ // heap
this.age = age;
this.name = name;
showInfo(); // 생성자(메서드)안에서 메서드 호출
}
// setter =============================================================
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
// 멤버 메서드 : [method] ================================================
void showInfo() {
System.out.println("이름은 " + this.name + "이고, 나이는 " + this.age + "세 입니다.");
}
}
public class ConstructorEx01 {
public static void main(String[] args) {
Student hong = new Student(26, "홍길동"); // 홍길동, 26
// 생성자의 매개변수에 맞는 인수 입력 필요
int num = 5;
// 지역변수 선언과 동시에 값을 넣어 초기화하는것처럼,
// 생성자는 멤버 변수를 객체생성과 동시에 초기화해준다
// hong.setAge(26);
// hong.setName("홍길동");
// hong.showInfo();
Student park = new Student("박보검"); // 박보검, 32
// park.setAge(32);
// park.setName("박보검");
// park.showInfo();
Student lee = new Student(55);
// lee.showInfo();
Student kim = new Student();
// kim.showInfo();
//생성자로 field의 값설정(초기화)
}
}
- ConstructorEx02
class Fruit {
// constructor
// 1. 매개변수가 없는 생성자
Fruit() { // 일단 코드로 생성자를 명시하면 아무내용이 없어도 기본생성자가 아니다.
System.out.println("매개변수가 없는 생성자 실행");
}
// 2. 매개변수가 1개인 생성자 (정수)
Fruit(int count) { // 일단 코드로 생성자를 명시하면 아무내용이 없어도 기본생성자가 아니다.
System.out.println("============================");
System.out.println("매개변수가 1개인 생성자 실행");
System.out.println("count : " + count);
System.out.println("============================");
}
// 3. 매개변수가 1개인 생성자 (실수)
Fruit(double count) {
System.out.println("============================");
System.out.println("매개변수가 1개인 생성자 실행");
System.out.println("count : " + count);
System.out.println("============================");
}
}
public class ConstructorEx02 {
public static void main(String[] args) {
Fruit fruit = new Fruit(); // 1. 매개변수가 없는 생성자 호출 : "()"가 생성자 호출
Fruit fruitTwo = new Fruit(5); // 2. 매개변수가 1개인 생성자 호출
Fruit fruitThree = new Fruit(100);
Fruit fruitFour = new Fruit(100.1); // 3. 매개변수가 1개인 생성자 호출
}
}
- ArrayEx01
/*
* [배열] array
* : 하나의 이름으로 여러 값(요소, 원소, 객체)을 관리
* : 여러 값이 메모리에 연속 할당
* : 여러 값을 구분하기 위해 인덱스 사용
* -> 인덱스(index)는 0부터 시작
*
* : 자바는 무조건 배열을 객체로 생성
* -> 배열은 heap에 영역 생성(할당)
*
* : 그래서 주소로 접근 (간접 접근) / cf) 이름으로 접근 (직접접근)
*
* <<문법>>
* 자료형[] 배열명 = new 자료형[길이];
* (객체로 heap에 생성하기때문)
*
*/
ㅇㅇㅍㅍㅍㅍㅇㅍㅍ
public static void main(String[] args) {
// [우리반 학생들의 수학 점수 저장] ===========
// 변수 선언 - 비효율적인 반복
// int math01 = 80;
// int math02 = 95;
// int math03 = 90;
// int math04 = 70;
// int math05 = 100;
// 1. 배열 생성 ====================================================================
// 1-1) 참조변수 선언
int[] math;
// 자료형[] 참조변수; - int[] : int배열 type
// int형의 1차원 배열의 주소를 저장할 수 있는 참조 변수 math 선언
// 1-2) 배열생성
math = new int[3];
// math : 참조변수
// 참조변수 = new 자료형[길이]
// int형의 길이가 3인 1차원 배열을 heap 영역에 생성후
// 주소를 참조변수 math에 저장.
// 2. 배열 요소의 값 설정===========================================================
math[0] = 80;
math[1] = 95;
math[2] = 90;
// math[3] = 70;
// math[4] = 100;
// 배열 요소에 저장된 값 출력
// System.out.println("math[0] : " + math[0]); // 배열 생성 후 나오는 []대괄호는 index
// System.out.println("math[1] : " + math[1]);
// System.out.println("math[2] : " + math[2]);
// System.out.println("math[3] : " + math[3]);
// System.out.println("math[4] : " + math[4]);
// 배열의 길이가 자동으로 저장되는 변수 : length
// 참조변수.length
System.out.println("배열 길이 : " + math.length);
//임의로 length의 길이를바꿀수는 없다.
// [반복문] 반복횟수가 정해져있으므로 for문 활용
for (int i = 0; i < math.length; i++)
System.out.printf("math[%d] : %d\n", i, math[i]);
// 기존의 for문에서 배열에서 사용하는
// ****[향상된 for문]==============================================================
// <<문법>>
// for(자료형 변수명: 배열의 참조변수) {
// 명령어;
//}
for(int element: math) {
System.out.println(element);
}
// 1. stack에 int element를 할당
// 2. heap에있는 math 배열의 주소로 가서 index 0부터의 값을 가지고와 element에 할당
// System.out.println(element); 명령시행
// 3. 더이상 실행할 것이 없으면 다시 math에 주소로 찾아가 다음 index 1 값을 가져옴
// 4. index를 끝까지 반복하면 탈출
}
- ArrayEx01CleanCode
/*
* <<문법>>
* 자료형[] 배열명 = new 자료형[길이];
*
* : 배열 생성과 동시에 초기화할 경우, 반드시 길이 생략
* 자료형[] 배열명 = new 자료형[] {초기값1, 초기값2, ...}
* 자료형[] 배열명 = {초기값1, 초기값2, ...} - (축약 ver.)
*
* : 배열을 생성하면, 배열의 길이가 length 변수에 자동저장
* 배열명.length
* -> length는 변경, 대입이 불가능 ex) 배열명.lenth = 5;Xㄴ
*
*/
public class ArrayEx01CleanCode {
public static void main(String[] args) {
// [우리반 학생들의 수학 점수 저장] ==========================
//1. 배열생성과 동시에 초기화
// : 반드시 길이 표현을 생략!!
// int[] math = new int[] {80, 95, 90, 70, 100};
// 아래처럼 생략 가능 : 더 보편적인 표현
int[] math = {80, 95, 90, 70, 100};
// 배열명
// 길이가 5인 1차원 배열 math 생성
//
// << 일반 for문 >>
for (int i = 0; i < math.length; i++)
System.out.printf("math[%d] : %d\n", i, math[i]);
// << 향상 for문 >>
for(int element: math)
System.out.println(element);
}
}
- ArrayEx02
public class ArrayEx02 {
public static void main(String[] args) {
//[1차원 배열] 길이가 1개인 배열 ==================================
// int형의 길이가 5인 1차원 배열 arr 생성
int[] arr = new int[5];
System.out.println("arr : " + arr);
//arr은 주소 ( [I@~~~~ ) [ 하나는 1차원배열을 뜻함.
//[2차원 배열] 길이가 2개인 배열 ==================================
int[][] arr2 = new int[2][3];
// 자료형[][] 배열명 = new 자료형[행길이][열길이]
System.out.println("arr2 : " + arr2); // arr2[0], arr2[1] 1차원 배열 2개 행를 가진 배열의 주소
// 주소에 ( [[I@~~~~ ) [[ 2차원배열
System.out.println("arr2[0] : " + arr2[0]); // arr2 [0]행의 시작주소 : 특정 행을 찾아온 주소
System.out.println("arr2[1] : " + arr2[1]); // arr2 [1]행의 시작주소 : 특정 행을 찾아온 주소
arr2[0][0] = 2;
arr2[0][1] = 4;
arr2[0][2] = 6;
arr2[1][0] = 8;
arr2[1][1] = 10;
arr2[1][2] = 12;
// [일반 for문] 1)
// length 변수 사용 X
// 2 4 6
// 8 10 12
for(int i=0; i<2;i++) {
for(int j=0; j<3;j++) {
System.out.print(arr2[i][j] + " ");
}
System.out.println();
}
// [일반 for문] 2)
// length 변수 사용
// 2 4 6
// 8 10 12
for(int i=0; i < arr2.length; i++) {
for(int j=0; j < arr2[i].length; j++) {
System.out.print(arr2[i][j] + " ");
}
System.out.println();
}
}