객체지향 프로그래밍 이해하기
자바라는 프로그램 안에서 객체를 여러개 만들어서 그 부품을 조립해서 한 제품을 완성시킨다.
※객체 : 세상에 존재하는 물체, 식별이 가능한 것
자동차, 도서관, 계산기
강의, 배달주문, 운동
식별이 가능한 모든 것
객체는 속성(색상, 가격 등)과 행위(브레이크, 기어 변속 등)로 구성이 되어있다.
자바에서는 이러한 속성과 행위를 필드와 메서드로 구현한다
사람(Person) 객체가 자동차의(Car) gasPedal()이라는 메서드를 호출하면 자동차는 return double을 준다
캡슐화(encapsulation)
상속
다형성
추상화
객체와 클래스
클래스를 만들기 위한 4가지 STEP
1. 만들려고 하는 설계도를 선언. (class 선언)
2. 객체가 가지고 있어야 할 속성(필드)을 정의.
3. 객체를 생성하는 방식을 정의 (생성자)
4. 객체가 가지고 있어야 할 행위(메서드()를 정의
Car 클래스에서 만들어놓은 객체로 new키워드를 메인에 만든다
Main에서 Car클래스를 사용할 수 있는 이유는 접근제어자를 public으로 설정하였기 때문
ex)
Car car1 = new Car();
Car[] carArray = new Car[3]; // 배열 만들기
Car car1 = new Car();
car1.changeGear('P');
carArray[0] = car1;
고유데이터 ex) color / 상태데이터 ex) speed, lights / 객체데이터 (하위)
필드를 사용한다?
=> 값을 변경하거나 읽는다.
클래스를 이용해서 객체를 만들어야 필드를 사용할 수 있다.
만들어진 객체로 클래스의 필드에 접근하는 방법은 2가지 방법이 있다
1. 외부에서 접근
double brakePedal() {
speed = 0;
return speed;
}
초기화 해준 값은 그 값이 들어가고 아닌 값은 default가 들어간다
메서드 선언
리턴타입 메서드명(매개변수, ...) {
실행할 코드 작성
}
ex) gasPedal(double kmh, char type) 메서드가 있을 경우
가변길이 매개변수 선언 가능
메서드 호출
메서드 오버로딩
하나의 메서드 이름으로 여러 기능을 구현하도록 하는 java의 기능
조건
메서드의 이름이 같고, 매개변수의 개수, 타입 또는 순서가 달라야 한다
응답값만 다른 것은 오버로딩 할 수 없다.
오버로딩의 장점
메서드 이름 하나로 상황에 따른 동작을 개별로 정의할 수 있다.
메서드의 이름을 절약할 수 있다.
기본형 매개변수
매개변수의 타입이 기본형일 때는 값 전체가 복사되어 넘어가 매개값으로 지정된 변수의 원본 값이 변동되지 않는다.
읽는 것만 가능하다
원본 객체는 변치 않는다.
참조형 매개변수
주소를 불러오기 때문에 읽고 변경하는 것도 가능하다
객체에 주소값 자체를 넘겨줬기 때문에 변경 가능
멤버 = 필드 + 메서드
선언하는 방법에 따라 인스턴스 멤버와 클래스 멤버로 구분
인스턴스 멤버는 객체 생성 후 사용할 수 있고 클래스 멤버는 객체 생성 없이도 사용할 수 있다.
인스턴스 멤버
클래스 멤버
지역변수 <-> 전역변수(static)
해당 메서드가 실행될 때 마다 독릭적인 값을 저장하고 관리
이 지역변수는 메서드 내부에서 정의될 때 생성된다
이 메서드가 종료될 때 소멸된다.
final
생성자
객체가 생성될 때 호출되며 객체를 초기화하는 역할 수행
public Car() {} // 선언 ( 기본생성자 )
생성자를 안 넣어줘도 컴파일러가 자동으로 추가해줌
이 경우 해당 클래스의 접근제어자를 따름
public Car(String model) {}
생성자가 한 개 이상 선언되었기 때문에 기본 생성자를 추가하지 않음.
ex) 자동차가 만들어질 때마다 기어의 상태를 'P'로 고정해야 한다면 초기값을 직접 대입하는 것이 좋다.
객체를 만들 때마다 다른 값을 가져야 한다면 ex) Car = sorento / SM5
생성자를 사용하여 필드의 값을 초기화 하는 것이 좋다.
this 와 this()
this()키워드를 사용하면 코드의 중복을 제거할 수 있다.
public Car(String model) {
this.model = model;
this.color = "Blue";
this.price = 50000000;
// -> 자기 자신에 있는 생성자 호출
public Car(String model) {
this(model, "Blue", 50000000);
}
// 어떠한 로직도 this 위에 있으면 안됨!!
public Car(String model, String color, dounle price) {
this.model = model;
this.color = color;
this.price = price;
}
접근제어자
사용가능한 접근제어자
클래스 내부에 선언된 데이터를 보호하기 위해서 사용
생성자에 접근 제어자를 사용함으로 인스턴스의 생성을 제한할 수 있다.
일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자를 따른다.
객체의 무결성 즉, 변경이 없는 상태를 유지하기 위해 접근 제어자를 사용
Getter와 Setter
하나하나의 필드마다 getter와 setter가 존재한다
private boolean lights;
//
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
Package 와 import
week03.packageExample.pk1.Car car = new week03.packageExample.pk1.Car();
2) import를 해온다.
import week03.packageExample.pk1.Car;
클래스간의 관계와 상속
클래스간의 상속은 extends 키워드를 사용하여 정의한다.
public class 자식클래스 extends 부모클래스 {
}
부모클래스와 자식클래스의 관계
상속관계와 포함관계
다중상속과 단일상속
final 클래스와 final 메서드
Object 클래스
오버라이딩(overriding)
@Override // 애노테이션(annotation)
public double brakePedal() {
speed = 100;
System.out.println("스포츠카에 브레이크란 없다");
return speed;
}
@Override
public void horn() {
booster();
}
super와 super() <-> this, this()
(각각 생성자와 관련 있겠구나, 인스턴스와 관련 있겠구나)
super
public void setCarInfo(String model, String color, double price) {
super.model = model; // model은 부모 필드에 set
super.color = color; // color는 부모 필드에 set
this.price = price; // price는 자식 필드에 set
}
자식 클래스의 메서드를 호출하면 super 키워드로 접근한 부모 클래스의 model, color 필드에 매개변수의 값이 저장된다.
this키워드로 접근한 자식 클래스의 price 필드에는 매개변수의 값이 저장된다.
다형성 ( 부모자식간 일어날 수 있는 특징 중 하나)
Mammal mammal = new whale(); => // 생성된 객체는 결국 포유류다.
//포유류 전부가 수영을 할 수 있는 것은 아님
// 수영하다 메서드는 실행 불가
mammal.swimming(); // 오류발생
// Whale whale = new Mammal(); // 오류발생
// 자식타입객체가 자동 타입변환된 부모타입의 변수
Mammal mammal = new whale();
mammal.feeding();
// 자식객체 고래의 수영 기능을 사용하고 싶다면
// 다시 자식타입 객체로 강제 타입변환.
Whale whale = (Whale) mammal;
whale.swimming();
강제타입변환 조건
instanceof
Parent p = Parent();
System.out.println(p instanceof Object); // true 출력
System.out.println(p instanceof Parent); // true 출력
System.out.println(p instanceof Child); // false 출력
Parent c = new Child();
System.out.println(c instanceof Object); // true 출력
System.out.println(c instanceof Parent); // true 출력
System.out.println(c instanceof Child); // true 출력
추상클래스
public abstract class 추상클래스명 {
}
상속 : 부모 -> 자식클래스
추상화 : 자식클래스에 필요한 기능들을 한 군데 모아서 규격을 정한다. 이를 모호하게 추상클래스로 만들어서 다시 나눠준다.
public abstract class 추상클래스명 {
abstract 리턴타입 메서드이름(매개변수, ...); // 구현부분 {}가 없다.
}
누군가 extends해서 구현을 해야한다.
public class GenesisCar extends Car {
@Override
public void horn() { sout("Genesis 빵빵:);}
인터페이스
publoc interface 인터페이스명 {
}
모든 멤버변수는 public static final이어야 한다.
모든 메서드는 public abstract 이어야 한다.
인터페이스는 추상 클래스와 마찬가지로 직접 인스턴스를 생성할 수 없기 때문에 클래스에 구현되어 생성된다.
implements 키워드를 사용하여 인터페이스를 구현할 수 있다.
public class 클래스명 implements 인터페이스명 {
// 추상 메서드 오버라이딩
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
default와 static 메서드
defailt메서드
static메서드
다형성