230802 재귀 메서드, setter / getter, 다양한 메서드 형태(참조형 매개변수, 반환(리턴)형이 참조형)
[23.08.02] 8일차
<<진도>>
- 과제풀이 (method, Instance)
- 객체지향 프로그래밍
클래스, 객체(인스턴스)
- getter / setter
- 참조변수 주소를 활용한 heap의 할당된 클래스의 멤버와 set, get 메커니즘
<<오늘의 팁>>
alt + shift + s -- > r : getter / setter 추가 단축키
ctrl + shift + f : 들여쓰기 / 내어쓰기 자동정렬
- MethodQuiz01
// [메서드 정의] =========================================
// 기능 : 인수로 정수 1개를 입력하면, 제곱값 출력
// 메서드명 : square, 매개변수 1개, 리턴값 없음
// =======================================================
public static void square(int num) {
int sqr = num * num;
System.out.printf("%d의 제곱값 = %d\n", num, sqr);
}
public static void main(String[] args) {
square(2);
square(5);
}
[풀이]=====================================================================
public static void square(int num) {
System.out.printf("%d의 제곱값 = %d\n", num, num*num);
}
public static void main(String[] args) {
square(2);
square(5);
}
- MethodQuiz02
// [메서드 정의] =========================================
// 기능 : 인수로 정수 2개를 입력받아, 몫 출력
// 단, 분모가 0이면 계산 불능
// 메서드명 : divide, 매개변수 2개, 리턴값 없음
// =======================================================
public static void divide(int n1, int n2) {
if(n2 != 0) {
int dvd = n1 / n2;
System.out.println("나눗셈 결과 : " + dvd);
}else {
System.out.println("분모가 0으로 계산불능");
}
}
public static void main(String[] args) {
divide(5, 3); // 나눗셈 결과 : 1
divide(4, 0); // "분모가 0으로 계산불능"
divide(6, 2); // 나눗셈 결과 : 3
}
[풀이]=====================================================================
/*
* [통상적으로 Error 발생시기]
* - 컴파일 에러 (거의 모두 문법적인 에러 -> 컴파일 불가-> 실행 불가)
* - 실행 에러 (매우 다양하다, 환경적인것 등)
*
* - 실행시 exception 아래에서 위로 오류확인
*
*/
public static void divide(int n1, int n2) {
// [방법1] ==========================================
if(n2 != 0)
System.out.println("나눗셈 결과 : " + (n1 / n2));
else
System.out.println("분모가 0으로 계산 불능");
// [방법2] ==========================================
if(n2 != 0) {
System.out.println("나눗셈 결과 : " + (n1 / n2));
return; // 리턴 값은 없고, 순수하게 if시 메서드의 끝 탈출역할만
}
System.out.println("분모가 0으로 계산 불능");
}
public static void main(String[] args) {
divide(5, 3);
divide(4, 0);
divide(6, 2);
}
- MethodQuiz03
// [메서드 정의] =========================================
// 기능 : 인수로 정수 1개를 입력받아, 팩토리얼 결과 리턴
// 메서드명 : factorial, 매개변수 1개, 리턴값 있음
// =======================================================
public static int factorial(int num) {
int fac = 1;
for(int i=1; i <= num; i++) {
fac = fac*i;
}
System.out.printf("%d!의 값 : ", num);
return fac;
}
public static void main(String[] args) {
System.out.println(factorial(5));
System.out.println(factorial(7));
}
[풀이]=====================================================================
// [방법 1] ===============================================
public static int factorial(int num) {
int factorial = 1;
for(int i=1; i<=num; i++) {
factorial = factorial * i; // 누적곱
}
return factorial;
}
public static void main(String[] args) {
System.out.println("3! : " + factorial(3));
}
// [방법 2] ===============================================
// 재귀 메서드 - 메서드안에서 자기자신 메서드를 호출하는법
// 반복됨 -> 탈출구문이 필요함
public static int factorial(int num) {
//return num * factorial(num-1); // stack overflow - 이 줄만으론 탈출하지 못한다.
if(num == 1)
return 1; //return은 본인(해당 메서드)을 호출한 곳으로 값으로 돌아간다
else
return num * factorial(num-1); //재귀 호출
}
public static void main(String[] args) {
System.out.println("3! : " + factorial(3));
}
** 변수 종류
- 지역변수
- 멤버변수
- 인스턴스 변수(객체 변수)
- InstanceEx01
//Fruit class 정의
class Fruit {
// 멤버 변수
int count;
String sort; // 멤버변수 sort, heap에 할당
// setter
void setCount(int count) {
this.count = count; //this. (멤버변수)count로 접근
}
// getter
int getCount() {
return this.count; //getter에는 this가 없어도 되나 명확한 의미전달을 위해 붙임
}
// 멤버 메서드
void showInfo() {
String sort = "사과"; // 지역변수 sort - 지역변수라 초기화필요
// stack에 할당 메서드 후 사라지는 값
System.out.println("과일 종류 : " + sort);
// 멤버변수X 멤버메서드 내의지역 변수인 sort 사용
System.out.println("과일 개수 : " + count);
System.out.println("==============================\n");
}
}
public class InstanceEx01 {
public static void main(String[] args) {
// 객체 생성
Fruit fruit = new Fruit();
fruit.showInfo();
fruit.setCount(5);
fruit.showInfo();
System.out.println("과일 개수 : getter >> " + fruit.getCount());
}
}
- InstanceEx02
class Thing {
int num;
void show() {
int var = 100;
System.out.println("참조변수 this : " + this);
// 클래스 객체 내에서 자신의 주소를 나타내는 참조변수 ' This '
System.out.println("멤버변수 num : " + num);
System.out.println("멤버변수 num : " + this.num);
//this 참조변수를 통해 접근하는 멤버변수 num
// System.out.println("멤버변수 num : " + this.var);
//this는 heap에 할당이 된 것(멤버)만 찾아갈 수 있음//error
}
}
public class InstanceEx02 {
public static void main(String[] args) {
Thing one =new Thing();
System.out.println("참조변수 one에 저장된 주소 : " + one);
// = Thing @ 75a1cd57
// type | 주소
// (주소->정수->16진수)보안문제
//
// Thing one 처럼 외부에서 접근하는 참조변수도 있지만
// 객체 내에서 자신의 클래스 객체 주소를 나타내는 참조변수 ' this ' 내부적
//외부접근=============
// 참조변수.멤버변수
// 참조변수.멤버메서드
// ====================
System.out.println("[외부 접근] 멤버 변수 num 접근 >> " + one.num);
// 멤버는 항상 참조변수를 통해 접근
// System.out.println("[외부 접근] var 접근 >> " + one.var);
// int var은 show(); 멤버메서드가 실행되어야 stack에 할당되는 지역변수이므로 heap에 없음
// one 참조변수로 접근불가
one.show(); // = Thing one에 있는 주소와 같음
Thing two = new Thing();
System.out.println("참조변수 two에 저장된 주소 : " + two);
//one과 Thing과 같이 type은 같지만 heap의 별도영역에 객체 'two' 할당 (*다른주소)
two.show();
}
}
- InstanceEx03
//class Thing { // bin 폴더에 같은 이름의 class 존재할 수 없음.
// 클래스 정의 불가. 중복된 이름이면 다른 위치에 만들어야함
class ThingTwo {
}
- InstanceEx04
/*
* class = 붕어빵 틀 / 인스턴스, 객체 = 빵 실제
*/
//Person class 정의
class Person { // 클래스 설계 : 관련있는 여러 변수와 메서드들을 묶어서 한 번에 관리
// 멤버 변수
int age;
String name;
String address;
// 멤버 메서드 (변수를 쓰는 것은 메서드)
void showInfo() {
System.out.println("나이 : " + this.age);
System.out.println("나이 : " + this.name);
System.out.println("나이 : " + this.address);
}
}
public class InstanceEx04 {
public static void main(String[] args) {
// 1. 참조변수 선언
// 자료형 변수명;
// 클래스명 참조변수
Person p1;
// 2. 인스턴스(객체) 생성
// new 클래스명();
// new : heap 영역에 할당하시오~
p1 = new Person();
// 1과 2 한번에
Person p1 = new Person();
}
}
- InstanceEx05
class Dog {
// 멤버 변수
int age;
String name;
// setter/getter 설정
// <<단축키>> alt + shift + s -> r
public int getAge() {
return age;
}
//보통 메서드와 메서드 사이는 한줄 띄운다
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class InstanceEx05 {
public static void main(String[] args) {
// 객체 생성
Dog happy = new Dog();
// 참조변수
// 객체명
// 인스턴스명
Dog sky = new Dog();
happy.setAge(1);
sky.setAge(10);
Dog copy = happy;
System.out.println("copy 나이 : " + copy.getAge());
copy.setName("해피");
System.out.println("copy 이름 : " + copy.getName());
System.out.println("happy 이름 : " + happy.getName());
//
}
}
- InstanceEx06
class Dog {
// 멤버 변수
int age;
String name;
// setter/getter 설정
// <<단축키>> alt + shift + s -> r
public int getAge() {
return age;
}
//보통 메서드와 메서드 사이는 한줄 띄운다
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class InstanceEx05 {
public static void main(String[] args) {
// 객체 생성
Dog happy = new Dog();
// 참조변수
// 객체명
// 인스턴스명
Dog sky = new Dog();
happy.setAge(1);
sky.setAge(10);
Dog copy = happy;
System.out.println("copy 나이 : " + copy.getAge());
copy.setName("해피");
System.out.println("copy 이름 : " + copy.getName());
System.out.println("happy 이름 : " + happy.getName());
//
}
}
- InstanceEx07
class Robot {
// 멤버변수 : 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 class InstanceEx07 {
// 메서드의 리턴형으로 참조형(참조변수)이 올 수 있다
public static Robot constructRobot() {
Robot robot = new Robot(); //호출 할때마다 ' new ' 새로운 Robot 객체를 생성
robot.setProductYear(2000);
robot.setProductName("옵티머스");
return robot; // 리턴값이 참조변수가 됐다.
}
public static void main(String[] args) {
// 지역변수 : local variable
Robot robot = constructRobot();
System.out.println("참초변수 robot에 저장된 주소 : " + robot);
System.out.println("robot 생산년도 : " + robot.getProductYear());
System.out.println("robot 제품명 : " + robot.getProductName());
//입력되는 값은 같으나 robot과 robotTwo는 서로 다른 주소를 가진 객체
Robot robotTwo = constructRobot();
System.out.println("참초변수 robotTwo에 저장된 주소 : " + robotTwo);
System.out.println("robotTwo 생산년도 : " + robotTwo.getProductYear());
System.out.println("robotTwo 제품명 : " + robotTwo.getProductName());
}
}