기본형,참조형 차이
▶기본형
-논리형 : boolean (1 byte)
▶참조형
-배열(array[])
-열거(enum)
-클래스(class)
-인터페이스(interface)
void changeParam(int num) {
num *= 2;
System.out.println("changeParam→ num: "+num);
}
public static void main(String[] args) {
Ex8 ex8 = new Ex8();
int num = 1234;
System.out.println("메서드 호출전→ num: "+num);
//changeParam 메서드를 호출
ex8.changeParam(num);
System.out.println("메서드 호출후→ num: "+num);
}
-기본형은 변수의 실제 값만 가져오는 것이기에 읽기만 가능한다.
그래서 메서드 호출을 해도 num값이 안바뀌는듯.
void changeRefparam(int [] arr) {
for(int i=0; i<arr.length; i++) {
arr[i] *= 2;
}
System.out.print("changeRefparam() arr[]: ");
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
System.out.print("메서드 호출 전: ");
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
Ex9 ex9 = new Ex9();
ex9.changeRefparam(arr);
System.out.print("메서드 호출 후: ");
for(int i=0; i<arr.length; i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
}
-참조형은 변수의 값을 읽고 변경할 수 있다.
그래서 기본형과 다르게 메서드 호출후 값이 바뀐듯함.
-메서드 내에서 자기자신을 반복적으로 호출하는것
-재귀호출은 반복문으로 바꿀 수 있으며 반복문보다 성능이 나쁨
-이해하기 쉽고 간결한 코드를 작성할 수 있다.
-상대적으로 속도가 느리다.
-실제로는 거의 사용 안하는듯?
-유용하게 쓰여지는 경우: 분할정복
int sum(int num) {
if(num==1) {
return 1;
}
return num * sum(num-1);
}
public static void main(String[] args) {
/*
int total =0;
for(int i=1; i<=10; i++) {
total += i;
}
System.out.println("total: "+total);
*/
Ex10 ex10 = new Ex10();
System.out.println("total: "+ex10.sum(5));
}
-인스턴스 생성후, '참조변수.메서드이름()'으로 호출
-인스턴스변수나 인스턴스메서드와 관련된 작업을 하는 메서드
-메서드 내에서 인스턴스변수 사용가능
-객체생성없이 '클래스이름.메서드이름()'으로 호출
-인스턴스변수나 인스턴스메서드와 관련없는 작업을 하는 메서드
-메서드 내에서 인스턴스변수 사용불가
-메서드 내에서 인스턴스변수를 사용하지 않는다면 static을 붙이는것을 고려한다.
-static붙은애들은 static끼리만 사용
-circle 클래스 바꿔보기-
static double pi; //pi값 기본으로 0가지게됨
int radius;
static void setPi(double pi) { //static안에 static메서드만 사용할수있음
Circle3.pi=pi;
}
void setRadius(int rad) {
radius = rad;
}
double getArea() {
double area;
area = radius * radius * Circle3.pi; //Circle3.pi라고 적어주는게 가독성 좋음
return area;
}
-circletest4-
Circle3 c1,c2;
Circle3.setPi(3.14);
c1 = new Circle3();
c2 = new Circle3();
c1.setRadius(5);
c2.setRadius(7);
System.out.printf("반지름이 %d 인 원의 넓이는 %f 입니다.\n",c1.radius,c1.getArea());
System.out.printf("반지름이 %d 인 원의 넓이는 %f 입니다.\n",c2.radius,c2.getArea());
Circle3.setPi(3.141592);
System.out.printf("반지름이 %d 인 원의 넓이는 %f 입니다.\n",c1.radius,c1.getArea());
System.out.printf("반지름이 %d 인 원의 넓이는 %f 입니다.\n",c2.radius,c2.getArea());
▶메서드 오버로딩
-하나의 클래스에 같은 이름의 메서드를 여러 개 정의하는 것을 메서드오버로딩.
▶오버로딩의 조건
-메서드의 이름이 같아야 한다.
-매개변수의 개수 또는 타입이 달라야 한다.
-매개변수는 같고 리턴타입이 다른 경우는 오버로딩이 성립되지 않는다.
int add(int num1, int num2) { //정수값받는 add 메서드
return num1 +num2;
}
/*
int add(int a, int b) { //메서드가 같지만 안에 int값 변수명만 바꾼거라 안됨
return a +b;
}
int add(int a, int b) { //결국 add에 값이 int라서 이거도 안됨
return (long)a +b;
}
*/
double add(double num1, double num2) { //실수값받는 add메서드
return num1 + num2;
}
int add(int [] arr) { //배열값받는 add메서드
int total = 0;
for(int num : arr) {
total += num;
}
return total;
}
public static void main(String[] args) {
Ex11 ex11 = new Ex11();
System.out.println("ex11: add(3,4): "+ex11.add(3,4)); //첫번째 메소드 사용
System.out.println("ex11: add(3.5,4.2): "+ex11.add(3.5,4.2)); //두번째 메소드 사용
System.out.println("ex11: add(new int[]{1,2,3,4,5}): "+ex11.add(new int[]{1,2,3,4,5})); //세번째 메소드 사용
//메서드는 여러개지만 상황에 맞게 써짐
}
-내가한거-
void up(double num1) {
if(num1 == (int)num1) {
System.out.println("올림: "+(int)(num1));
}else{
System.out.println("올림: "+(int)(num1+1));
}
}
void down(double num) {
System.out.println("버림: "+(int)num);
}
void banup(double num) {
System.out.println("반올림: "+(int)(num+0.5));
}
public static void main(String[] args) {
double i;
Scanner sc = new Scanner(System.in);
System.out.print("하나의 실수를 입력하세요: ");
i = sc.nextDouble();
Exam1 ex1 = new Exam1();
ex1.up(i);
ex1.down(i);
ex1.banup(i);
}
-클래스를 2개로 하라 하셨는데 그럼 계산하는 클래스파일 한개, 출력하는 클래스파일 한개 란건가..?
-계산하는 클래스-
public class Exam1_2 {
void up(double num1) {
if(num1 == (int)num1) {
System.out.println("올림: "+(int)(num1));
}else{
System.out.println("올림: "+(int)(num1+1));
}
}
void down(double num) {
System.out.println("버림: "+(int)num);
}
void banup(double num) {
System.out.println("반올림: "+(int)(num+0.5));
}
}
-출력하는 클래스-
public static void main(String[] args) {
double i;
Scanner sc = new Scanner(System.in);
System.out.print("하나의 실수를 입력하세요: ");
i = sc.nextDouble();
Exam1_2 ex1 = new Exam1_2();
ex1.up(i);
ex1.down(i);
ex1.banup(i);
}
잘나오긴 한다!
버림 - floor 반올림-round 올림-ceil 변수명을 이렇게 쓰는듯.
--모범답안--
1.추상화클래스
public class FloatToInteger {
double num;
void setNum(double a) {
num = a;
}
int floor() {//버림
return (int)num;
}
int round() {//반올림
return (int)(num+0.5);
}
int ceil() {//올림
int result = 0;
if((int)num == num) {
result = (int)num;
}else {
result = (int)(num+1);
}
return result;
}
}
2.출력클래스
public static void main(String[] args) {
FloatToInteger fti = new FloatToInteger();
Scanner sc = new Scanner(System.in);
double num;
System.out.print("하나의 실수값을 입력하세요: ");
num = sc.nextDouble();
sc.close();
fti.setNum(num); //입력한수 setnum에 넣기
System.out.println("버림: "+fti.floor());
System.out.println("반올림: "+fti.round());
System.out.println("올림: "+fti.ceil());
}
훨씬 간결해지긴 한다.
-인스턴스가 생성될 때마다 호출되는 '인스턴스 초기화 메서드'
-인스턴스 변수의 초기화 또는 인스턴스 생성시 수행할 작업에 사용
-인스턴스 초기화= 인스턴스 변수에 적절한 값을 저장하는것.
-클래스로부터 인스턴스를 생성하는 방법
-반드시 클래스마다 하나이상 존재해야함
-클래스 에 생성자가 하나도 없으면 컴파일러 할때 default 생성자가 제공됨.
조건
1.클래스이름이랑 같아야함.-생성자 오버로딩
2.생성자는 반환형 자체가 없다, 리턴값이 없다 (void를 쓰지 않는다.)
3.괄호안에 매개변수를 가질수 있다.
ex)
Exam1_2 ex1 = new Exam1_2();
→괄호에 생성자를 넣어야하는데, 안넣어서 생성자가 하나도 없어서 default 생성자가 제공된거였음. default 생성자↓
FloatToInteger(){
// default생성자, 뒤에 매개변수 없는, 중괄호도 비어있음
}
-계산코드-
public class FloatToInteger2 {
double num;
FloatToInteger2(){ //defualt생성자
}
FloatToInteger2(double a){
num = a;
}
void setNum(double a) {
num = a;
}
int floor() {//버림
return (int)num;
}
int round() {//반올림
return (int)(num+0.5);
}
int ceil() {//올림
int result = 0;
if((int)num == num) {
result = (int)num;
}else {
result = (int)(num+1);
}
return result;
}
}
-출력코드-
FloatToInteger2 fti1 ,fti2; //생성자가2개라서 인스턴스를 만드는방법도 2가지
double num1 = 3.6, num2 = 3.4;
fti1 = new FloatToInteger2(); //생성자 하나라도 있으면 default생성자 제공안됨.
fti1.setNum(num1);
fti2 = new FloatToInteger2(num2);
System.out.println("버림: "+fti1.floor());
System.out.println("반올림: "+fti1.round());
System.out.println("올림: "+fti1.ceil());
System.out.println("--------------------------");
System.out.println("버림: "+fti2.floor());
System.out.println("반올림: "+fti2.round());
System.out.println("올림: "+fti2.ceil());
-생성자, 같은 클래스의 다른 생성자를 호출할 때 사용
-다른 생성자 호출은 생성자의 첫 문장에서만 가능
-키워드라서 변수명으로 this 못씀.
-인스턴스 자신을 가리키는 참조변수, 인스턴스의 주소가 저장되어있음
-모든 인스턴스 메서드에 지역변수로 숨겨진 채로 존재
-car클래스-
public class Car {
String color;
String gearType;
int door;
Car(){
this.color = "black";
this.gearType = "auto";
this.door = 4;
}
Car(String color){
this.color = color;
this.gearType = "auto";
this.door = 4;
}
Car(String color,String gearType){
this.color = color;
this.gearType = gearType;
this.door = 4;
}
Car(String color,String gearType,int door){
this.color = color;
this.gearType = gearType;
this.door = door;
}
}
-carTest 클래스-
public static void main(String[] args) {
Car car1,car2,car3,car4;
car1 = new Car();
car2 = new Car("white");
car3 = new Car("white","menual");
car4 = new Car("white","menual",3);
System.out.println("Car1: "+car1.color+" : "+car1.gearType+" : "+car1.door);
System.out.println("Car2: "+car2.color+" : "+car2.gearType+" : "+car2.door);
System.out.println("Car3: "+car3.color+" : "+car3.gearType+" : "+car3.door);
System.out.println("Car4: "+car4.color+" : "+car4.gearType+" : "+car4.door);
}
생성자에서 다른 생성자호출로 바꿔서하기
-car2 클래스-
package chap06;
public class Car2 {
String color;
String gearType;
int door;
Car2(){
this("black","auto",4); //this앞에는 아무것도 있으면 안됨. 무조건 첫번째 문장이여야함
System.out.println("첫번째 생성자: ");
}
Car2(String color){
this(color,"auto",4);
System.out.println("두번째 생성자: ");
}
Car2(String color,String gearType){
this(color,gearType,4);
System.out.println("세번째 생성자: ");
}
Car2(String color,String gearType,int door){
this.color = color;
this.gearType = gearType;
this.door = door;
System.out.println("네번째 생성자: ");
}
Car2(Car2 car2){
this.color = car2.color;
this.gearType = car2.gearType;
this.door = car2.door;
System.out.println("다섯번째 생성자: ");
}
}
-carTest2 클래스-
public static void main(String[] args) {
Car2 car1,car2,car3,car4;
car1 = new Car2(); //매개변수 없는 생성자 호출 첫번째로 가서 네번째로 가서 출력
car2 = new Car2("white");//
car3 = new Car2("white","menual");
car4 = new Car2("white","menual",3);
car5 = new Car2(car2);
System.out.println("Car1: "+car1.color+" : "+car1.gearType+" : "+car1.door);
System.out.println("Car2: "+car2.color+" : "+car2.gearType+" : "+car2.door);
System.out.println("Car3: "+car3.color+" : "+car3.gearType+" : "+car3.door);
System.out.println("Car4: "+car4.color+" : "+car4.gearType+" : "+car4.door);
System.out.println("Car5: "+car5.color+" : "+car5.gearType+" : "+car5.door);
}
1.네번째&첫번째 = 첫번째 생성자
2.네번째&두번째 = 두번째 생성자
3.네번째&세번째 = 세번째 생성자
4.네번째 = 네번째 생성자
5.다섯번째 = 다섯번째 생성자
참고문헌- 자바의정석 (남궁성)