개체 : 인간이 관념적으로 인식한 것을 S/W로 구체화 한 것 속성(변수,필드) : 개체가 갖고 있는 값 메서드(함수) : 개체가 할수 있는 동작 이벤트 : 개체가 반응을 할수 있게 외부에서 가해지는 자극
- 클래스 : 객체의 형태를 정의(설계도) 객체(인스턴스) : 클래스를 기반으로 생성된(메모리에 할당된) 것
class 클래스명 { 속성 정의 생성자 정의 매서드 정의 }
- 클래스명은 소스파일명과 동일해야 한다.
클래스 변수(참조형 변수) : 생성된 인스턴스를 지정할 변수 클래스명 변수명; Ex> SportsCar car;
- 클래서 변수 선언과 동시에 인스턴스를 생성 클래스명 변수명 = new 클래스명(인수, 인수,...); Ex> SportsCar car = new SportsCar();
- 필드(속성, 변수) : 클래스의 상태값을 저장하는 변수
- 생성자(메서드) : new 연산자를 통해 객체가 생성될 때 최초로 동작되는 메서드. 클래스명과 동일해야 함. 일반적으로 클래스의 초기화를 담당. 생략될 경우 컴파일전 빈 생성자로 자동 추가.
- 메서드 : 객체가 수행할 동작
class 클래스명 {
자료형 필드명;
자료형 필드명 = 초기값;
}
- 필드는 인스턴스 생성시 초기값이 기술되어 있지 않으면 0에 준하는 값으로 초기화
class Car {
String model = "그랜저";
int speed;
boolean start;
Tire tire = new Tire();
}
Car c1 = new Car();
System.out.println(c1.model); //그랜저
c1.speed = 100;
- new 연산자는 클래스의 생성자를 호출
- 생성자는 클래스의 인스턴스 생성시 가장 먼저 실행되는 메서드
- 일반적으로 초기화를 담당
- 생성자명은 클래스명과 동일
- 모든 클래스는 생성자를 1개 이상 가져야 한다.
- 클래스 정의시 생성자를 생략하면 컴파일러는 기본 생성자를 추가하여 컴파일
class Car {
String model;
int maxSpeed;
boolean start;
Tire tire = new Tire();
}
- this : 생성된 객체 자신
- 오버로딩(overloading) : 매서드명은 동일하고 매개변수의 타입 및 수량을 달리하여 여러개를 정의
- 생성자 오버로딩 : 생성자를 다양하게 정의
package sec02;
public class Car {
String company = "현대자동차";
String model;
String color;
int maxSpeed;
Car() {}
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 sec02;
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);
}
}
- 생성자 오버로딩에서 중복코드가 많을 경우(단계적으로 내용이 증가되는 형태일 경우) 공통 코드를 가진 생성자만 정의하고 나머지는 this()를 사용하여 공통코드 생성자를 호출
package Example;
public class MemberService {
boolean login(String id, String password) {
if(id.equals("hong") && password.equals("12345")) {
return true;
}
else {
return false;
}
}
void logout(String id) {
System.out.println(id + "님이 로그아웃 되었습니다.");
}
}
// 다른 클래스
package Example;
public class MemberServiceExample {
public static void main(String[] args) {
MemberService memberService = new MemberService();
boolean result = memberService.login("hong", "12345");
if(result) {
System.out.println("로그인 되었습니다.");
memberService.logout("hong");
}
else {
System.out.println("id 또는 password가 올바르지 않습니다.");
}
}
}
// 결과 hong과 12345가 일치하니, 로그인 되었습니다. hong님이 로그아웃 되었습니다.
반환형 매서드명(매개변수, 매개변수, ...){ 메서드 실행문; ... }
- 반환형(리턴 타입, Return Type)
- 매서드의 실행결과를 호출한 장소로 반환할 경우의 자료형
- 리턴값(retrun 문에서 기술된 값 또는 변수 또는 식의 결과)의 자료형과 일치해야 한다.
- 만약 리턴값이 없을 경우 반환형을 void로 기술한다.
- 매서드명 : 관례로 소문자로 시작
- 매개변수 : 매서드 실행시 필요한 외부에서 전달되어지는 인수값을 저장할 변수
- 매개변수는 지역변수로 취급한다.(메서드 종료시 메모리에서 삭제. 자동 변수)
int divide(int x, int y){...} //매개변수마다 형선언을 해야 함 int divide(int x, y){...} //이건 안됨
- 객체 내부에서 호출 : 메서드명(인수, 인수,...);
- 객체 외부에서 호출 : 변수명.메서드명(인수, 인수,...);
package sec02;
public class Calculator {
void powerOn() {
System.out.println("전원을 켭니다.");
}
void powerOff() {
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;
}
}
// 다른 클래스
package sec02;
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator();
myCalc.powerOn();
int resultl = myCalc.plus(5, 6);
System.out.println("result1 : " + resultl);
int x = 10;
int y = 4;
double result2 = myCalc.divide(x, y);
System.out.println("result2 : " + result2);
myCalc.powerOff();
}
}
반환형 메서드명(자료형... 변수명) { }
- 매개변수는 입력된 값들의 길이만큼의 해당하는 배열로 생성하여 처리
package sec02;
public class Computer {
int sum(int ... values) { // int[] values 이런 형식으로 만들면 res1, res2는 안된다. res3, res4는 가능
int sum = 0;
for(int i=0; i<values.length; i++) {
sum += values[i];
}
return sum;
}
}
// 다른 클래스
package sec02;
public class ComputerExample {
public static void main(String[] args) {
Computer myCom = new Computer();
int res1 = myCom.sum(1,2,3);
System.out.println("res1 : " + res1);
int res2 = myCom.sum(1,2,3,4,5); // 길이가 달라져도 상관없고
System.out.println("res2 : " + res2);
int[] values = {1,2,3,4,5};
int res3 = myCom.sum(values); // 배열도 가능하다
System.out.println("res3 : " + res3);
int res4 = myCom.sum(new int[] {1,2,3,4,5}); // 이런 배열 형식도 가능
System.out.println("res4 : " + res4);
}
}
- 매서드를 종료하고 호출한 장소로 되돌아감
- 호출한 장소도 되돌아갈 때 1개값을 포함하여 호출한 장소로 전달 형식 return; return 값_또는_변수_또는_식;
- 주의 : 리턴값은 매서드의 리턴타입과 동일한 타입(자동 형변환 허용)이어야 한다.
- 메서드명은 동일하되 매개변수의 타입, 수량, 순서를 달리하여 여러개를 정의한 것
- 같은기능을 하되 매개변수의 종류가 다를 경우 매서드명을 달리하면 가독성 측면에서 불편, 네이밍 차원에서도 불편. 주의 : 반환형, 매개변수 이름은 오버로딩과 관련 없다. int add(int x, int y) {...} double add(int x, int y) {...} //오버로딩 아님. 메서드 중복 에러 int add(int num1, int num2) {...} //오버로딩 아님. 메서드 중복 에러
- 인스턴스 : new 연산자를 통해 힙 영역에 생성된 객체
- 맴버 : 클래스 내부에 선언된 요소(속성, 매서드)
- 인스턴스 맴버 : 객체에 소속된 맴버(객체를 생성해야 사용할 수 있는 맴버). 힙 영역에 존재하는 맴버
- 정적(static) 맴버 : 클래스에 고정된 맴버(객체 생성 없이도 사용가능한 맴버). 매서드 영역에 상주하는 맴버
- 생성된 인스턴스 자신.
- 인스턴스 내부에서 내부의 맴버를 호출할 때 사용.
class 클래스명 { static 자료형 변수명; //정적 맴버 변수
static 반환형 매서드명 (매개변수,...) { //정적 맴버 매서드 메서드 내용; }
}
Calculaotr myCal = new Calculaotr();
double result1 = 10 * 10 * myCal.pi;
int result2 = myCal.plus(10, 20);
int result2 = myCal.minus(100, 50);
- 정적 맴버를 초기화 하기 위한 블록
- 클래스가 메모리(메서드 영역)에 로드될 때 자동으로 실행
- 맴버의 접근은 객체 생성전(staic 맴버)과 생성 후(인스턴스 맴버)로 나눈다.
- 인스턴스 맴버는 객체 생성전 static을 통해 사용할 수 없다.
public class Exam18 {
int iv = 10;
static int cv = 20;
int iv2 = cv;
// static int cv2 = iv; // 라인 A 정적 변수 초기화에 인스턴스 변수 사용 불가
static void staticMethod1() {
System.out.println(cv);
// System.out.println(iv); // 라인 B 정적메서드에서 인스턴스 변수 사용 불가
}
void instanceMethod1() {
System.out.println(cv);
System.out.println(iv); //라인 C
}
static void staticMethod2() {
staticMethod1();
// instanceMethod1(); //라인 D static 메서드에서는 인스턴스 메서드를 사용할 수 없다.
}
void instanceMethod2() {
staticMethod1(); //라인 E
instanceMethod1();
}
}
- 전제 조건 : 외부에서 필드를 마음대로 접근하면 필드 값에대한 무결성이 깨질수 있다. 이를 보완하기 위해 필드를 private으로 노출을 막고 메서드를 public으로 하여 노출시킨다음 메스들 통해 필드값을 변경하게 한다.
- Setter : 필드의 값을 설정하는 메서드
- Getter : 필드의 값을 가져오는 메서드
- return 타입이 boolean인 경우 is접두사를 사용함.
package sec08;
public class Car {
private int speed;
private boolean stop;
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
if(speed < 0) {
this.speed = 0;
}
else {
this.speed = speed;
}
}
public boolean isStop() { // boolean 타입인 경우 get이 아니라 is로 나온다.
return stop;
}
public void setStop(boolean stop) {
this.stop = stop;
if(stop == true) {
this.speed = 0;
}
}
}
// 다른 클래스
package sec08;
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car();
myCar.setSpeed(-50);
System.out.println("현재 속도 : " + myCar.getSpeed()); // 0
myCar.setSpeed(60);
System.out.println("현재 속도 : " + myCar.getSpeed()); // 60
if(!myCar.isStop()) {
myCar.setStop(true);
}
System.out.println("현재 속도 : " + myCar.getSpeed()); // 0
}
}
// 패턴 : 객체지향 프로그래밍의 디자인(설계) 방식
// 싱글톤 패턴 : 객체가 1개만 생성되도록 디자인된 패턴 (여러개의 인스턴스에 의해 메모리가 낭비되는걸 방지하기 위해서) --> 생성자를 private으로 선언하여 외부에서 무분별하게 생성못하도록 막음.
// public static으로 선언된 메서드를 통해 1개의 인스턴스만 생성되도록 제한.
- 패턴 : 객체지향 프로그래밍의 디자인(설계) 방식
- 싱글톤 패턴 : 객체(인스턴스)가 1개만 생성되도록 디자인된 패턴
- 생성자를 private로 선언하여 외부에서 무분별하게 생성하지 못하도록 막음
- publuc static으로 선언된 메서드를 통해 1개의 인스턴스만 생성되로록 제한
package sec09;
public class Singleton {
private static Singleton singleton = new Singleton();
private int value;
private Singleton() {
}
static Singleton getInstance() {
return singleton;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
// 다른 클래스
package sec09;
public class SingletonExample {
public static void main(String[] args) {
// Singleton obj1 = new Singleton(); Err, private 이기 때문에
// Singleton obj2 = new Singleton();
Singleton obj1 = Singleton.getInstance();
Singleton obj2 = Singleton.getInstance();
if(obj1 == obj2) {
System.out.println("같은 Singleton 객체 입니다.");
}
else {
System.out.println("다른 Singleton 객체 입니다.");
}
System.out.println("obj1.value : " + obj1.getValue()); // 0
System.out.println("obj2.value : " + obj2.getValue()); // 0
obj1.setValue(10);
System.out.println("obj1.value : " + obj1.getValue()); // 10
System.out.println("obj2.value : " + obj2.getValue()); // 10
obj2.setValue(50);
System.out.println("obj1.value : " + obj1.getValue()); // 50 즉, obj1과 obj2는 연결되어 있다.
System.out.println("obj2.value : " + obj2.getValue()); // 50
}
}