[학습목표]
1. 객체지향 프로그래밍에 대한 개념을 이해합니다.
2. 클래스를 설계하는 방법에 대해 학습합니다.
3. 객체의 구성요소(필드, 메서드, 생성자)에 대해서 학습합니다.
4. 클래스 변수, 인스턴스 변수의 차이점에 대해서 학습합니다.
5. 생성자와 생성자 오버로딩에 대해 학습합니다.
6. this와 this() 키워드에 대해 학습합니다.
7. 접근 제어자에 대해 학습합니다.
8. pakage와 import에 대해 학습합니다.
9. 상속, 오버라이딩 을 통해 기능을 확장하는 방법을 배웁니다.
10. super와 super() 키워드에 대해 학습합니다.
11. 다형성의 원리와 구현 방법에 대해 학습합니다.
12. 추상 클래스에 대해 학습합니다.
13. 인터페이스의 역할에 대해 이해하고 구성 요소와 구현 방법에 대해 학습합니다.
14. 인터페이스의 디폴트 메서드와 static 메서드에 대해 학습합니다.
15. 인터페이스의 다형성 원리와 구현 방법에 대해 학습합니다.
세상에 존재하는 물체, 식별이 가능한것
-특징과 행동 -> 속성과 행위 -> 필드와 메서드
-현실 세계 객체를 소프트웨어 객체로 설계하는 것 => 객체 모델링
< 객체간의 협력>
< 객체 간의 관계>
-캡슐화, 상속,다형성(여러개의 형태) ,추상화(구체적인것을 모호하게 뺌)
캡슐화(encapsulation)상속다형성C 언어에서는 매개변수 다르면 메소드명도 다르게 해줘야함!(절차지향언어)
제네릭(4주차)으로 한 메서드로 다른 타입도 재사용가능
**파이썬은 타입없음(인터프린터 언어) 빠름 ->코테에 유리
추상화(구체적인것->추상적으로 모호하게)<객체와 클래스>
객체를 생성하기 위해서는 설계도 필요=> 클래스
클래스를 토대로 생성된 객체=> 인스턴스(과정을 인스턴스화)
new 키워드 사용
<클래스 만드는 단계>
1.클래스 선언
2.객체 속성(필드) 정의
3.객체 생성 방식 정의(생성자,constructor)->인풋,로직
4.객체가 가지고 있어야할 행위 정의
생성자: 처음 객체가 생성될 때(인스턴스화) 어떤 로직을 수행하며, 어떤 값이 필수로 들어와야하는 지 정의! 클래스 이름과 동일
기본 생성자(매개변수 없는 생성자) : 생략이 가능
필드 메서드 생성자
1.고유 데이터
2.상태 데이터
3.객체 데이터(객체 내에서 하위객체 가질수있다.)
선언 하고 초기화 하지 않으면 기본값으로
필드 사용방법
정의(선언) 하는 방법
리턴타입 메서드명(매개변수,...){
실행할 코드
return 반환값;//리턴 타입 void아니면 반드시 있어야함
}
void
return; 없어도 되지만 있을 수 있다.(원하는 지점에서 메서드 종료)
input : 매개변수
output : return 값
input값 없으면 매개변수 생략 가능
가변길이 매개변수
void carSpeeds(double ... speeds) { for (double v : speeds) { System.out.println("v = " + v); } }몇개 들어와도 상관 없이 받을 수 있음
carSpeeds(100, 80);carSpeeds(110, 120, 150);
<메서드 호출>
메서드 내부 코드 실행
외부 접근: car.breakPedal(); 매개변수 순서,타입에 맞게 넣어줘야함
내부 접근: 클래스 내부 메서드 내에서 사용.
오버로딩
한클래스에서 하나의 메서드 이름으로 여러기능을 구현
매개변수의 개수 또는 타입, 순서가 다게 작성
- '응답 값만' 다른 것은 오버로딩을 할 수 없습니다.
- 접근 제어자만 다른 것도 오버로딩을 할 수 없습니다.
- 결론, 오버로딩은 매개변수의 차이로만 구현할 수 있습니다.
장점: 메서드 이름 하나 상황에 따른 동작을 개별로 정의 ,이름절약
ex)println()
오버 라이딩
부모 클래스의 메서드 재사용
멤버 = 필드+메서드
선언하는 방법에 따라 구분
인스턴스 멤버는 객체 생성 후 사용가능, 클래스 멤버는 객체 생성 없이 사용
객체 생성해야 사용가능
static 키워드 사용
-인스턴스마다 모두 가지고 있을 필요 없는 공용적인 데이터
인스턴스 메서드는 클래스 필드 사용할 수 있다.
클래스 메서드는 인스턴스 필드 사용하려고 하면 오류가 발생
클래스의 이름과 함께 도트(.) 연산자를 사용
Car.company = "Audi";
String companyName = Car.setCompany("Benz");
** 참조형 변수를 사용하여 클래스 멤버에 접근은 가능하지만 추천하지 않습니다. (클래스 이름으로 접근하는 것이 좋습니다.)
해당 메서드가 실행될 때마다 독립적인 값 저장,관리
메서드 내부에서 정의될 떄 생성, 메서드 종료될 때 소멸
final (최종적) : 프로그램 실행 도중에는 절대로 수정 불가, 공용으로 쓰이는 값, 반드시 초기값 지정
상수(static final): 반드시 한개 불변의 값
인스턴스마다 상수저장 할 필요 없음.
(보통 전체 대문자로 표시)
-객체 생성될 때 호출되며,객체 초기화
public class Car {
public Car(String model) {} // 생성자 선언
// 생성자가 한개 이상 선언되었기 때문에 기본 생성자를 추가하지 않음.
//기본생성자없이=>Car car =new Car(); 하면 오류 발생
//Car car = new Car("Benz");//로 생성해야함
}
-컴파일러에 의해 생성되는 기본 생성자는 해당 클래스의 접근 제어자(public, …)를 따릅니다.
public class Car {
public Car() {} // 컴파일러가 추가시켜줌
}
class Car {
Car() {} // 컴파일러가 추가시켜줌
}
생성자는 객체를 초기화 하는 역할
public Car(String modelName, String colorName, double priceValue) {
model = modelName;
color = colorName;
price = priceValue;
}
...
Car car1 = new Car("benz","white",2500.0);
Car car2 = new Car(); // 오류 발생->기본 생성자 만들지 않아서
public Car(String model, String color, double price) {
model = model;
color = color;
price = price;
}
=>해결
public Car(String model, String color, double price) {
this.model = model;
this.color = color;
this.price = price;
}
Car returnInstance() {
return this;
}
public Car(String model) {
System.out.println("model = " + model);//오루
this(model, "Blue", 50000000);
}
[제어자]
클래스, 변수, 메서드의 선언부에 모두 사용가능
지정되어 있지 않다면 default 입니다.
public : 접근 제한이 전혀 없습니다.protected : 같은 패키지 내에서, 다른 패키지의 자손클래스에서 접근이 가능합니다.default : 같은 패키지 내에서만 접근이 가능합니다.private : 같은 클래스 내에서만 접근이 가능합니다.(보수적->캡슐화)[사용가능한 접근 제어자]
public, defaultpublic, protected, default, private[접근 제어자를 이용한 캡슐화 (은닉성)]
[생성자의 접근 제어자]
생성자에 접근 제어자를 사용함으로 인스턴스의 생성을 제한할 수 있습니다.
일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치합니다.
** Getter와 Setter
객체의 무결성 즉, 변경이 없는 상태를 유지하기 위해 접근 제어자를 사용합니다.
이때 외부에서 필드에 직접 접근하는 것을 막기 위해 필드에 private, default 등의 접근 제어자를 사용할 수 있습니다.
객체의 private 필드를 읽고 쓰기 위해
=>Getter(저장) 와 Setter(저장/수정) 를 사용
인스턴스 메서드 호출과 동일
[제어자의 조합]
사용가능한 제어자
- 클래스 : public, default, final, abstract
- 메서드 : public, protected, default, private, final, abstract, static
- 멤버변수 : public, protected, default, private, final, static
- 지역변수 : final
제어자 사용시 주의 사항
메서드에 static과 abstract를 함께 사용할 수 없다.
클래스에 abstract와 final을 동시에 사용할 수 없다.
abstract메서드의 접근 제어자가 private일 수 없다.
메서드에 private와 final을 같이 사용할 필요는 없다.
클래스의 일부분이며, 하위 패키지를 도트(.)로 구분한다.
week03.packageExample.pk1.Car car1 = new week03.packageExample.pk1.Car();
week03.packageExample.pk2.Car car2 = new week03.packageExample.pk2.Car();
car1.horn();
car2.horn();
import week03.packageExample.pk1.Car;
public class Main {
public static void main(String[] args) {
//클래스의 일부분이며, 하위 패키지를 도트(.)로 구분한다.
Car car= new Car();
car.horn();
}
}
public class 자식클래스 extends 부모클래스 {
}
자칫하여 부모 클래스, 자식 클래스라는 용어에 현혹되어 ‘부모가 자식보다 큰 사람이니까 부모 클래스도 마찬가지로 자식 클래스 보다 큰 범위겠지?’ (X)

상속 관계(is) : 고래(자식)는 포유류(부모)/스포츠카는 자동차이다.
포함 관계(has) : 자동차는 타이어,차문,핸들을 가지고 있다. =>클래스 내에 객체 변수로 생성
Java는 다중상속 허용 하지 않음. 한 부모만 상속
한 부모가 여러개의 자식 가질수잇음(한 자식이 여러부모 가질수 없음=>복잡해짐)
** C++ 다중상속(재사용성) 지원 : 부모가 같은 이름 변수나 메서드가지면 어떤 부모 참조해야할지 모름!->에러 (class 자체 상속)
Ruby : c++의 문제 해결해 다중상속 class namespace조합
부모클래스에 final키워드 지정하면 상속할 수 없는 클래스가됨
메서드에 final 키워드 지정하면 오버라이딩 할수 없는 메서드
Object 클래스의 메서드
부모 클래스로부터 상속받은 메서드의 내용을 재정의 하는 것
부모 클래스의 메서드를 그대로 사용 가능하지만 자식 클래스의 상황에 맞게 변경을 해야하는 경우 오버라이딩을 사용합니다.
//에노테이션
@Override
super : 부모클래스의 멤버(필드, 메서드)를 참조할 수 있는 키워드
super() : 부모 클래스의 생성자를 호출할 수 있는 키워드
부모 클래스의 생성자는 가장 첫 줄에서 호출이 되어야합니다.
-자식 클래스 객체를 생성할 때 생성자 매개변수에 매개값을 받아와 super(…)를 사용해 부모 생성자의 매개변수에 매개값을 전달하여 호출하면서 부모 클래스의 멤버를 먼저 초기화합니다.
super(); 를 자식 클래스 생성자 첫 줄에 자동으로 추가해 줍니다.// 자식 클래스 SportsCar 생성자
public SportsCar(String model, String color, double price, String engine) {
// this.engine = engine; // 오류 발생
super(model, color, price);
this.engine = engine;
}
자동 타입변환
자식타입 변수 = new 부모();//오류발생
강제 타입변환
자식타입 변수 = (자식타입) 부모타입객체;
=>자식 메소드 실행가능
// 자식타입객체가 자동 타입변환된 부모타입의 변수
Mammal mammal = new Whale();
mammal.feeding();
// 자식객체 고래의 수영 기능을 사용하고 싶다면
// 다시 자식타입으로 강제 타입변환을 하면된다.
Whale whale = (Whale) mammal;
whale.swimming();
Mammal newMammal = new Mammal();
Whale newWhale = (Whale) newMammal; // ClassCastException 발생
여러가지 형태를 가질 수 있는 능력 => 참조변수 타입변환
ex) 자동차의 타이어교체, 바퀴교체
다형성 기능으로 인해 해당 클래스 객체의 원래 클래스명 체크하는 것 필요=>이를 위해 사룡하는 명령어
(대상 객체) instance of (클래스 이름) 응답값은 boolean
Object => true
부모클래스 => true
형변환 했어도 => 원래 생성된 클래스 => true
클래스가 설계도라면 추상 클래스는 미완성된 설계도입니다.
abstract 키워드를 사용하여 추상 클래스를 선언할 수 있습니다.
```java
public abstract class 추상클래스명 {
}
```
추상 클래스는 추상 메서드를 포함할 수 있습니다.
추상 메서드가 없어도 추상 클래스로 선언할 수 있습니다.
(일반 필드와 메서드도 가지고 있음 -> 그대로 사용)
abstract는 클래스와 메서드에서만 사용 가능!!
=>추상 클래스와 인터페이스(키워드 생략가능)에서 사용
추상 메서드는 아직 구현되지 않은 미완성된 메서드입니다.
abstract 키워드를 사용하여 추상 메서드를 선언할 수 있습니다.
```java
public abstract class 추상클래스명 {
abstract 리턴타입 메서드이름(매개변수, ...);
}
```
상속받은 클래스(자식)에서 추상 클래스의 추상 메서드는 반드시 오버라이딩 되어야 합니다.=>인터페이스랑 비슷
행위(메서드) 구현 해야할 때 인터페이스는 구현 클래스들의 동일한 사용방법과 행위 보장 public interface 인터페이스명 {
}
인터페이스의 접근제어자는 무조건 public!! (생략해도 public으로 인지)
모든 멤버 변수는 public static final (생략가능->컴파일러 자동추가)
=> 굳이 쓰지 않음! 차라리 추상클래스 사용!
모든 메서드 public abstrct(생략가능->컴파일러 자동추가)
but, static 메서드와 default메서드는 interface 내에 구현부분이 있어야함(추상 메서드 아님, public은 생략)
public interface 인터페이스명 {
public static final char A = 'A';
static char B = 'B';
final char C = 'C';
char D = 'D';
void turnOn(); // (public abstract) void turnOn();
}
public class 클래스명 implements 인터페이스명 {
// 추상 메서드 오버라이딩
@Override
public 리턴타입 메서드이름(매개변수, ...) {
// 실행문
}
}
인터페이스 변수 = 구현 객체;
public class Main {
public static void main(String[] args) {
// A 인터페이스에 구현체 B 대입
A a1 = new B();
// A 인터페이스에 구현체 B를 상속받은 C 대입
A a2 = new C();
}
}
interface A { }
class B implements A {}
class C extends B {}
구현 객체 변수 = (구현객체 타입) 인터페이스변수;
(인터페이스로 자동 타입 변환된 구현체 객체를) 다시 구현제로 변환할때만 강제타입변환 가능
=>인터페이스 변수 = new 구현체
같은 변수로 구현체 쉽게 변경!
** 추상클래스& 인터페이스 는 인스턴스화가 안된다.
추상 클래스=>자식메서드 생성자로 생성 후 형변환
인터 페이스=>구현체의 생성자로 생성 후 형변환

인터페이스는 행위의 일관성
추상클래스는 일반화된 개념을 묶어준다!