1. 프로젝트 생성

src?
소스코드

클래스 생성 방법

2. 객체지향의 핵심
객체는 상태와 행위를 가진다. 상태는 행위를 통해서만 변경한다
상태 = 변수(어떤 변수? 스택의 변수X 객체가 생성될 때 지니고 있는 변수)
상태만 가진 애를 객체라 안 한다 그냥 데이터 덩어리다(객체라 부르기는 하지만 엄밀히 말하면 아님)
1. 공간에 대해서

2. 예시
static이 안 붙어 있는 애들은 무조건 heap에 생성된다
메서드안에 들어가는 애가 stack에 들어간다 {} 중괄호가 끝나면 사라지는 애들
package ex00;
class 엘리스{
private int 목마름;//스테틱 없어서 동적으로 new 해서 heap에 띄워야 한다
//alt + insert로 만들 수 있다.
public 엘리스(int 목마름) {
this.목마름 = 목마름;
}
//setter 상태 변경하는 애 의도를 파악할 수 없는 행위기에 세터는 직접 만드는게 좋다
//이게 의도를 파악하기 쉽다
//메서드 물마시려면 내부 로직은 아주 복잡하다
//static에 안 붙어 있기에 무조건 heap에 뜬다 new 할 때 뜬다.@@@@@@@@@@@@
void 물마시기() {
목마름 = 0;
}
// 이 친구를 getter 상태를 확인하는애
int 목마름확인하기(){
return 목마름;
}
}
public class Mem01 {
public static void main(String[] args) {
엘리스 e = new 엘리스(100);// 이 라인에서 동적할당(heap)
// 1. 값 변경(행위) 의도한 값이 나온다 0
e.물마시기();
// 2. 값 확인
int 목마름 = e.목마름확인하기();
System.out.println(목마름);
// e.목마름 = 100;//상태는 행위로 들어가야 한다 그래서 틀렸다.
//private을 해줘서 마음대로 못 만든다
//객체 초기화는 태어날 때 해야함 태어날 때 아버지가 있는거지 20살때부터 아버지가 있는게 아님
//new 엘리스를 초기화 해줘야 함
}
}
3. 상속과 컴포지션
3.1 상속
기존의 클래스에 기능을 추가하거나 재정의하여 새로운 클래스를 정의하는 것을 의미합니다.
이러한 상속은 캡슐화, 추상화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.
is 관계다
Car클래스가 있고 Sonata extend Car 이라면
Car s1 = new Sonata();
이러면

Sonata s1 = new Sonata();


3.2 컴포지션
4. 추상화란?
다형성 is, has상속을 하면 여러가지 타입을 추상화 할 수 있다
추상화는 이 세상에 존재하는게 아니고 그냥 부르기 편하게 있기 위해 있는 것이다
class Car{
//상태 행위
void a (){
System.out.println("hi");
}
}
class Sonata extends Car{
//상태 행위
void b (){
System.out.println("sonata");
}
}
class Genesis extends Car{
// 상태 행위
void c (){
System.out.println("genesis");
}
}
public class Mem02 {
public static void main(String[] args) {
Sonata s1 = new Sonata();
Genesis g1 = new Genesis();
이때는
s1.a();
s1.b();
g1.a();
g1.c();
Car s1 = new Sonata(); // 메모리에 sonata, car
Car g1 = new Genesis();// genesis, car
s1.a();
g1.a();
}
}
Car는 sonata인가? 맞음 Car는 Genesis인가 맞음
public class Mem02 {
static void 레이싱(Sonata s1){
System.out.println("소나타 달림");
}
static void 레이싱(Genesis s1){
System.out.println("제네시스 달림");
}
}
이렇게 두 개를 다 만들 필요가 없다
static void 레이싱(Car s1){
System.out.println("제네시스 달림");
}
Car만 해주면 두 개 다 만들 필요가 없다 근데 sonata인지 genesis인지는 모르기에
static void 레이싱(Car s1){
if(s1 instanceof Sonata){
}else if (s1 instanceof Genesis){
}
}
해주는데 이러면 새로운 객체를 만들 때 마다 if해줘야 하는 번거로움이 생긴다 그래서
5. 동적 바인딩
재정의
(부모의 매서드 이름과 자식의 매서드 이름과 같다.)부모의 메서드 오브라이딩(무효화)한다 그래서 자식클래스 동적바인딩해서 재정의한다
abstract class Car{//자동차 달려주세요 하면 자동차 들이 다 달리기 시작한다)
//Car c = new Car()할 수 없다 추상화 시켰기 때문에 객체 못만듬
abstract void run(){} 통로의 역할로만 사용함
}
class Soanata extends Car{
void run(){
System.out.println("소타나 달린다");
}
}
public class Mem02{
//추상화 안하면 레이싱에 sonata, genesis 두개를 만들어야 한다
static void 레이싱(Car car){
car.run(); 하면 부모의 run 무효화하고 자식의 run사용가능(동적바인딩)
}
}
어떻게 달리는지 어떤 차가 달리는지 모르기 때문에 abstract를 추가해서 만든다.
클래스에 abstract하는 이유는 추상적인 것이기에 객체가 있으면 안되기 때문
메서드에 abstract하는 이유는 상속 받는 객체가 반드시 Override해줘야 하기 때문(동적바인딩)
package ex00;
abstract class Car {
// car 상태
// car 행위
abstract void run(); // 무효화
}
class 티코 extends Car{
void run() {
System.out.println("티코 달린다.");
}
}
class Sonata extends Car{ // 다형성
// Sonata 상태
// Sonata 행위
void run(){ // 재정의
System.out.println("소나타 달린다");
}
}
class Genesis extends Car{ // 다형성
// Genesis 상태
// Genesis 행위
void run(){
System.out.println("제네시스 달린다");
}
}
class 페라리 extends Car{
@OVerride
void run(){System.out.println("페라리 달린다");}
}
이게 생긴다면 elseif 기존 코드 손봐야 한다
public class Mem02 {
static void 레이싱(Car car){ //이게 dip 티고 car하면 구체적인 것에 의존하게 된다
car.run();
}
public static void main(String[] args) {
Car s1 = new Sonata(); // Sonata, Car
Car g1 = new Genesis(); // Genesis, Car
Car t1 = new 티코();
레이싱(t1);
}
}
정리?
선생님이 여러명 있는데 나가라 할 때 누구 선생님 나가세요, 누구 선생님 나가세요 안하고
선생님 나가세요 만 하면 모든 선생님들 나간다. 즉 선생님이라는 추상화를 묶는 것
Share article