모든 프로그래밍 언어의 기본이자 중요한 내용이다!
객체(object): 물리적 존재 or 추상적 생각하는 것 중에서 식별가능한 자신의 속성을 가진 것
ex) 식별가능하고 특징있는 세상의 모든 사물들; 볼펜, 볼펜잉크, 볼펜 심 등
속성(field 필드) + 동작(method 메소드)로 구성
형태적인 것들(정의)
ex) 걷는 속도 <- 이 개념은 필드. 실제로 걷는 것은 메소드
자동차의 필드는 색깔 속도 등. 메소드는 달린다와 멈춘다.
메소드 호출 : 무언가를 시키는 것
매개값 = 매개변수 ( arg;argument) = input값
[객체관계]
1. 집합 관계: 부품과 완성품의 관계
2. 사용 관계: 객체 간 상호작용
3. 상속 관계: 상위(부모) 객체 기반 하위(자식) 객체 생성
Class(클래스): 자바의 설계도
Instance(인스턴스): 클래스로부터 만들어진 객체
OOP: 클래스 설계 -> 사용할 객체(인스턴스) 생성 -> 생성된 객체 이용
지금까지 정리한 자바 기본 문법은 main() 메소드만 작성해서 실행할 목적으로 클래스 이용함
main()이 없다면 객체 생성 과정을 거쳐 사용해야 함
클래스 선언: 객체 구상 후 이름 결정. 첫 단어 대문자 중요
보통은 java 소스파일 하나 당 하나의 클래스만 선언하지만 2개 이상도 가능은 하다.
package sec01.exam01;
public class Student {
}
public class Teacher { //2개 이상 클래스 선언하는 경우
}
이 경우 class 파일이 2개 생김. 이처럼 Student라는 클래스를 실행 클래스 (StudentExample)에서 사용한다면
package sec01.exam01;
public class StudentExample {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("s1 변수가 Student 객체를 참조합니다.");
Student s2 = new Student();
System.out.println("s2 변수가 또 다른 Student 객체를 참조합니다.");
}
}
s1 변수가 Student 객체를 참조합니다.
s2 변수가 또 다른 Student 객체를 참조합니다.
이처럼 API(Application program Interface) 라이브러리 목적(Student) 클래스와 실행 클래스(StudentExample)을 분리하여 작성한다.
[클래스를 구성하려면?]
Field: 객체 데이터 저장소
Constructor(생성자): 객체 초기화 담당. new로 호출되는 { } 블록
Method: 객체 동작 실행 { } 블록
Field: 객체 데이터 저장소
아래 두 java 파일은 반드시 같은 패키지안에 있어야 자동으로 가져온다. public이라서 자유롭게 가져오는 것이다.
package sec02.exam01;
public class Car {
//필드 이 자바파일은 실행시키지 않는다.
String company = "현대자동차";
String model = "그랜저";
String color = "검정";
int maxSpeed = 350;
int speed; // 초기값은 0이다.
}
외부 클래스 (CarExample)에서 Car의 field의 값을 읽는다.
package sec02.exam01;
public class CarExample {
public static void main(String[] args) {
//객체 생성
Car myCar = new Car(); // 생성된 자동차 클래스의 필드값 객체를 가져온다.
//필드 값 읽기
System.out.println("제작회사: " + myCar.company);
System.out.println("모델명: " + myCar.model);
System.out.println("색깔: " + myCar.color);
System.out.println("최고속도: " + myCar.maxSpeed);
System.out.println("현재속도: " + myCar.speed);
//필드 값 변경
myCar.speed = 60; // 클래스 jave파일은 그대로이고 여기서만 반영된다.
System.out.println("수정된 속도: " + myCar.speed);
}
}
제작회사: 현대자동차
모델명: 그랜저
색깔: 검정
최고속도: 350
현재속도: 0
수정된 속도: 60
각종 타입의 초기값을 알아보자. (외부클래스에서 읽기)
package sec02.exam02;
public class FieldInitValue {
//필드
byte byteField;
short shortField;
int intField;
long longField;
boolean booleanField;
char charField;
float floatField;
double doubleField;
int[] arrField;
String referenceField;
}
package sec02.exam02;
public class FieldInitValueExample {
public static void main(String[] args) {
FieldInitValue fiv = new FieldInitValue();
System.out.println("byteField: " + fiv.byteField);
System.out.println("shortField: " + fiv.shortField);
System.out.println("intField: " + fiv.intField);
System.out.println("longField: " + fiv.longField);
System.out.println("booleanField: " + fiv.booleanField);
System.out.println("charField: " + fiv.charField);
System.out.println("floatField: " + fiv.floatField);
System.out.println("doubleField: " + fiv.doubleField);
System.out.println("arrField: " + fiv.arrField);
System.out.println("referenceField: " + fiv.referenceField);
}
}
byteField: 0
shortField: 0
intField: 0
longField: 0
booleanField: false
charField:
floatField: 0.0
doubleField: 0.0
arrField: null
referenceField: null
Constructor(생성자): 객체 초기화 담당. new로 호출되는 { } 블록
package sec03.exam01;
public class Car {
//생성자 color와 cc값이 있음 (형식)
Car(String color, int cc) {
}
}
package sec03.exam01;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car("검정", 3000); // color와 cc값 형식을 맞추었다.
//Car myCar = new Car(); (이러한 기본 생성자는 존재하지 않으므로 오류)
} // 이걸 사용하려면 기본 생성자 전용도 따로 만들어줘야 함.
}
필드와 생성자(매개변수)는 이름을 동일한 경우가 많다. 이 경우 this를 통해(파이썬 self개념) 필드임을 구분한다
package sec03.exam02;
public class Korean {
//필드
String nation = "대한민국";
String name;
String ssn;
//생성자 이렇게 잘 안씀
/* public Korean(String n, String s) {
name = n;
ssn = s;
}*/
// 생성자 보통 이렇게 씀
public Korean(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
}
package sec03.exam02;
public class KoreanExample {
public static void main(String[] args) {
Korean k1 = new Korean("박자바", "011225-1234567");
System.out.println("k1.name : " + k1.name);
System.out.println("k1.ssn : " + k1.ssn);
Korean k2 = new Korean("김자바", "930525-0654321");
System.out.println("k2.name : " + k2.name);
System.out.println("k2.ssn : " + k2.ssn);
}
}
k1.name : 박자바
k1.ssn : 011225-1234567
k2.name : 김자바
k2.ssn : 930525-0654321
생성자 여러개 준비하기 (생성자 overloading)
단 순서만 바꾼다거나 이름만 바꾸는 것는 해당안됨을 유의한다.
package sec03.exam03;
public class Car {
//필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
//생성자
Car() {
} // 아무것도 없는 경우(default)이며 new가 입력 가능하다.
Car(String model) {
this.model = model;
}
Car(String model, String color) {
this.model = model;
this.color = color;
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
package sec03.exam03;
public class CarExample {
public static void main(String[] args) {
Car car1 = new Car();
System.out.println("car1.company : " + car1.company);
System.out.println();
Car car2 = new Car("자가용");
System.out.println("car2.company : " + car2.company);
System.out.println("car2.model : " + car2.model);
System.out.println();
Car car3 = new Car("자가용", "빨강");
System.out.println("car3.company : " + car3.company);
System.out.println("car3.model : " + car3.model);
System.out.println("car3.color : " + car3.color);
System.out.println();
Car car4 = new Car("택시", "검정", 200);
System.out.println("car4.company : " + car4.company);
System.out.println("car4.model : " + car4.model);
System.out.println("car4.color : " + car4.color);
System.out.println("car4.maxSpeed : " + car4.maxSpeed);
}
}
car1.company : 현대자동차
car2.company : 현대자동차
car2.model : 자가용
car3.company : 현대자동차
car3.model : 자가용
car3.color : 빨강
car4.company : 현대자동차
car4.model : 택시
car4.color : 검정
car4.maxSpeed : 200
-> 생정자가 여러개라서 이에 맞는 다양한 형식의 출력이 가능해졌다.
this()를 통해서 클래스의 반복되는 생성자 구문을 간략하게 할 수 있다.
package sec03.exam04;
public class Car {
//필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
//생성자
Car() {
}
Car(String model) {
this(model, null, 0);
}
Car(String model, String color) {
this(model, color, 0);
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
제일 밑에 모든 필드가 있는 경우를 놓고 위에 this로 호출이 가능하다.
Method: 객체 동작 실행 { } 블록. 관례적으로 소문자로 이름 지음. (클래스는 첫 글자 대문자)
리턴값: 메소드 결과값. 메소드는 리턴값 유무가 제각각
필드는 괄호가 없지만 메소드는 () 괄호가 있다.
리턴값 없는 메소드 = void (실행 강제)
package sec04.exam01;
public class Calculator {
//메소드
void powerOn() {
System.out.println("전원을 켭니다.");
}
int plus(int x, int y) {
int result = x + y;
return result;
}
double divide(int x, int y) {
double result = (double)x / (double)y;
return result;
}
void powerOff() {
System.out.println("전원을 끕니다");
}
}
package sec04.exam01;
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator(); // 클래스 객체화
myCalc.powerOn(); // 클래스의 print문 출력
int result1 = myCalc.plus(5, 6);
System.out.println("result1: " + result1);
byte x = 10;
byte y = 4;
double result2 = myCalc.divide(x, y);
System.out.println("result2: " + result2);
myCalc.powerOff();
}
}
전원을 켭니다.
result1: 11
result2: 2.5
전원을 끕니다
매개변수 ... (도트연산자) 는 배열이아닌 값만 가져올 때 사용한다.
매개변수의 개수를 모를 때에는 배열 타입으로 선언한다.
package sec04.exam02;
public class Computer {
int sum1(int[] values) { // 여기서 values는 이름일 뿐이다.
int sum = 0;
for(int i=0; i<values.length; i++) {
sum += values[i];
}
return sum;
}
int sum2(int ... values) { //배열이 아니더라도 알아서 맞춰 넣어준다.
int sum = 0;
for(int i=0; i<values.length; i++) {
sum += values[i];
}
return sum;
}
}
package sec04.exam02;
public class ComputerExample {
public static void main(String[] args) {
Computer myCom = new Computer();
int[] values1 = {1, 2, 3};
int result1 = myCom.sum1(values1);
System.out.println("result1: " + result1);
int result2 = myCom.sum1(new int[] {1, 2, 3, 4, 5});
System.out.println("result2: " + result2);
int result3 = myCom.sum2(1, 2, 3);
System.out.println("result3: " + result3);
int result4 = myCom.sum2(1, 2, 3, 4, 5);
System.out.println("result4: " + result4);
}
}
result1: 6
result2: 15
result3: 6
result4: 15
return은 메소드 실행을 강제 종료한다. (break보다 효율적으로 전체종료 可)
package sec04.exam03;
public class Car {
//필드 (보안문제로 이렇게 작성하기보단 아래 메소드형식으로 쓴다)
int gas;
//생성자 없어도 기본 생성자는 자동으로 생성된다!
//메소드
void setGas(int gas) { // set는 값 주입하는 것.
this.gas = gas;
}
boolean isLeftGas() {
if(gas==0) {
System.out.println("gas가 없습니다.");
return false;
}
System.out.println("gas가 있습니다.");
return true;
}
package sec04.exam03;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.setGas(5); //Car의 setGas() 메소드 호출
boolean gasState = myCar.isLeftGas(); //Car의 isLeftGas() 메소드 호출
if(gasState) {
System.out.println("출발합니다.");
myCar.run(); //Car의 run() 메소드 호출
}
if(myCar.isLeftGas()) { //Car의 isLeftGas() 메소드 호출
System.out.println("gas를 주입할 필요가 없습니다.");
} else {
System.out.println("gas를 주입하세요.");
}
}
}
gas가 있습니다.
출발합니다.
달립니다.(gas잔량:5)
달립니다.(gas잔량:4)
달립니다.(gas잔량:3)
달립니다.(gas잔량:2)
달립니다.(gas잔량:1)
멈춥니다.(gas잔량:0)
gas가 없습니다.
gas를 주입하세요.
클래스 내부에서 메소드를 계속 호출하는 예제이다.
package sec04.exam04;
public class Calculator {
//필드
//생성자
//메소드
int plus(int x, int y) {
int result = x + y;
return result;
}
double avg(int x, int y) {
double sum = plus(x, y);
double result = sum / 2;
return result;
}
void execute() {
double result = avg(7, 10);
println("실행결과: " + result); //이것도 메소드이다.
}
void println(String message) {
System.out.println(message);
}
}
package sec04.exam04;
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator();
myCalc.execute(); // 실행한 것은 이것 뿐
}
}
실행결과: 8.5
메소드 오버로딩(overloading): 같은 이름의 메소드인데 기능이 여러개임을 구현하는 경우
package sec04.exam06;
public class Calculator {
//정사각형의 넓이
double areaRectangle(double width) {
return width * width;
}
//직사각형의 넓이
double areaRectangle(double width, double height) {
return width * height;
}
}
package sec04.exam06;
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalcu = new Calculator();
//정사각형의 넓이 구하기
double result1 = myCalcu.areaRectangle(10);
//직사각형의 넓이 구하기
double result2 = myCalcu.areaRectangle(10, 20);
//결과 출력
System.out.println("정사각형 넓이=" + result1);
System.out.println("직사각형 넓이=" + result2);
}
}
정사각형 넓이=100.0
직사각형 넓이=200.0
직사각형 넓이의 경우 int로 들어갔으므로 밑에 같은 이름에 int로 지정된 곳을 가지만 없으면 자동타입변환 규칙에 의해
double이 있는 경우가 실행되었다.
'Programming > Java' 카테고리의 다른 글
Interface (인터페이스) (0) | 2023.10.17 |
---|---|
Inheritance(상속) (1) | 2023.10.16 |
instance, static, package, access modifier (0) | 2023.10.16 |
참조타입, 배열, 열거타입 (0) | 2023.10.12 |
java basic (기본 문법) (0) | 2023.10.11 |