본문 바로가기
자바 , 기타 공부/자바 기초.1.04까지만

기초 2장 -> 객체 지향

by 임지혁코딩 2023. 12. 26.

6장. 클래스란? 객체를 정의한 것. 객체는 실제로 존재하는 것. 

class- > 인스턴스화 인스턴스(객체). 각 객체의 string color(내부에 있는 변수) or void power() (내부 메서드)

이들을 멤버라고 한다. TVCLASS tv = new TV(); TV.CHANNEL = 7; TV.CHANNELDOWN() //내부 메서드 사용

SOUT(간단하게표현) (TV.CHANNEL); 

 

변수

-해당 사진은, 상업적 이용이 아닐시 사용의 허용이 명시된 자료를 사용하였습니다.

인스턴스변수 -> 각 인스턴스마다 개별적인 저장공간, 생성후 Variables.iv로 접근 가능 

class 변수 (static) -> 같은 class의 모든 인스턴스가 공유. class loading시(가장 먼저 생성).

지역변수 -> 지역 블럭을 벗어나면 소멸 .

 

Method 

main도 class로, class영역에만 정의할 수 있음 

void power() { power = !power;} 과 같이. int max(int a , int b ) { if (a>b) return a; } 

 

Mymath안의, long add라는 method를 쓰고싶으면, 해당 method를 일반 long으로 지정하고 

Mymath mm = new Mymath() ; long value = mm. add(1L,2L); ->CLASS 내부의 METHOD만을 사용. 

 

메서드는 생성과 소멸하며, 메모리를 할당받고 반환하고 이 LAYER를 CALL STACK.

가장 위에있는 메소드가 현재 실행중인 메서드가 된다. 

NEW연산자로 생성되는 INSTANCE는 HEAP에서 이루어진다. 

 

재귀 호출-> 어렵고 성능이 나쁨. 하지만 이해하기 쉽고 간결 코드 작성 가능. 

복잡도 계산식이 존재 (후에 알고리즘시간에 배웠던 내용을 활용하여 코딩테스트 진행할때 첨부하겠음)

 

CLASS(STATIC)METHOD-> 객체 생성 없이 호출 가능할때. 

메서드에서 인스턴스 변수,메소드 사용이 불가능하다 .

 

인스턴스 메서드. INSTANCE생성후 참조변수.메서드 이름으로 호출하며, 인스턴스 변수 사용 가능.

 

OVERLOADING-> 하나의 CLASS에 같은 메서드르 여러개 정의 . (과적)

매소드 이름이 같고, 매개변수 TYPE이 다르다. 주의할것, 매개변수 TYPE이 같고 RETURN만 다른경우는 오버로딩이 성립되지 않음 주의! 매개변수가 INTA,B인것과 X,Y는 성립되지 않음 주의 

 

생성자 

인스턴스 생성시 호출되는 초기화 메서드. 모든 CLASS에는 반드시 생성자가 필요! 

Card c = new Card();에서, Card()가 생성자의 역할을 담당한다. 

생성자엔 return이 없고,void를 쓰지 않는다. class의 이름 EX)Card와 같아야 한다. 

아무것도 작성하지 않으면, 모든 클래스는 반드시 한개 이상의 생성자가 필요하여 card(){}가 자동 생성된다.

 

this는 인스턴스 자신을 가리키는 참조 변수가 된다 

주로 SetCar(String color,String geartype int door) { this. color = color ;~~ 등등 } 

 

즉 , Card의 생성자를 내부에 정의하고 public class Card

{ private int value1; private int value2; private int value3;

public Card(int v1, int v2, int v3) {

this.value1 = v1; this.value2 = v2; this.value3 = v3;

} // 다른 멤버 및 메서드들... }

이후  Card mycard = new Card(1,2,3); 

 

이렇게 진행하거나 혹은 SetCard를 별도로 생성하여, new card로 공간만을 할당하고 실제 값을 대입한다.

 

변수의 초기화 -> 가장 처음 값을 지정해줄떄. 

instance변수, class변수는 초기화를 생략할 수 있다. 

지역변수(메소드 내부의) 는 반드시 초기화가 필요하다. 

 

직접 int door =4; 와같이 초기화 (class내부에 class를 불러오면 BasicClass basic = new BasicClass();와 같이 명시적 초기화 가능! or 생성자 입장에선 this.color =color;와 같은 행위가 초기화가 될 것이다. 

초기화 블럭으로 초기화를 진행할 수도 있따. 

 

 

7장 

 

상속

기존 class를 활용하는 새로운 class의 작성

자손은 조상의 모든 멤버를 상속받는다 . class Point3D extends Point와 같은 방식 

즉, 자손은 조상 + @이다. 

 

Circle 안에 Point c = new Point () ; 개발에서 젤 자주 사용하는 형태 . 

이는 포함관계라고 한다. 작은 단위 class가 먼저 만들어지고 그 이후 조합된다. 

가지고 있을때는 포함관계. a는 b일떄는 둘을 상속관계로 이어준다. 

 

Java는 , 단일 상속만을 허용한다. 나머지는 어쩔수없이 포함으로 해야한다. 

Object Class는 자동적으로 조상이 없는 class들이 상속받게 된다. 

 

Overriding  -> 조상클래스로부터 상속받은 메서드를 상속받은 class에 맞게 변경하는 것. //조상님 올라타겠습니다!

 

1. 선언부가 같아야하고 2. 접근제어자를 변경할수 없고 -> protected는 protected나 public

3. 조상 class보다 많은 예외 선언이 불가하다 (해당 내용은 후에 공부한다. ) 

 

Super -> this와 같으나, 조상과 자신의 멤버를 구별. 해당 x가 조상의 x인지, 자신의 x인지 구별 

 

package -> class와 인터페이스의 묶음. 패키지는 폴더이며 , 모든 class는 하나의 패키지에 속한다. 

classpath. class를 찾는 경로가 된다. 

import -> 사용한 class가 속한 package가 어디있고, 이것을 사용하겠다는 선언 

 

public(기본) 접근 제한이 없음

protected -> 동일한 패키지 혹은 파생 에서만  -> 같은 패키지 혹은 자식이 해당을 접근할 수 있음. 

즉) ex) main에서 One을 상속받으면, 

one의 protected인 a에 접근할 수 있다.  -> protected or public으로 변경하여 overridding한다 .

private- > 아무도 불가 , 클래스 내부에서만 접근 가능. -> private로 overridding 

default -> 같은 패키지 내에서 접근 가능하다 .

생성자에 접근제어자를 사용, 스스로 private로 생성하여 인스턴스 생성을 제한.

 

final? -> class는 확장될수없고(조상이될수) , method는 재정의 될수 없으며, (overridding을 통해) 

변수시는 상수가 된다. final void getmax() , final class mainclass 

class Card안에 final int NUMBER가 있다면. 최초 Card c = new Card(10)시는 가능하지만,

c.NUMBER= 5;와 같인 진행할 수 없다. 

 

Abstract -> class 내에 추상메서드가 선언되어있다(class ver) 메서드시는 선언부만 작성하고 구현부는 작성되지 않은 형태의 추상 메서드이다. 즉( 상속받아서 완성된다)-> 자손이 구현해달라. (class시)

 

1. static과 abstract동시 사용 메소드 x 2. class에 abstract와 final 동시 사용 x 

3. abstract 메서드의 접근제어자가 private일수 없다. 

 

다형성 

조상타입의 참조변수로 , 자손타입의 객체를 다룰 수 있다.

 자손이 조상을 받을땐, 형변환을 반드시 해줘야하며, 그것이 (FireEngine)으로 표현되었다. 

 

ArrayList list = new ArrayList();

System.out.println(list instanceof ArrayList);
System.out.println(list instanceof List);

이와 같이, array list가 list로 부터 상속받았다면, 지금 생성된 이 인스턴스는 해당 목표에 대해 상속받았는지를 true of false로 표현해준다. 

 

자식 class에도 매개변수 x가 있고, 부모에도 x가있을 수 없다. 

자식 class에도 method x가 있고, 부모에도 있다면, 생성된 인스턴스에 맞는 내용을 불러온다. 

 

잠깐. 참조형 매개변수? 

 c++에서 그렇게 배웠던 &와 같은 개념( 실제 그 주소를 가져온다) . (변화가 저장된다) 

즉. 저 이후에는 (NAME이 static public이라면) Person.name또한 Bob이 된다. 허나 이는 회피해야될 기법! 

 

추상 class -> 미완성 설계도. 

abstract class Player { abstract void play(int pos); abstract void stop() void play에서 play(currentpos)}사용 할 수 있따. 

허나 , 인스턴스를 생성할수는 없다. 추상 메서드는, 몸통이 없다 ( 구현부가 없다) 

자손마다 다르게 구현될 것으로 예측될때 사용한다. 

play에 대한 구현을, 각 자손들이 진행한다. 

 

인터페이스 

정의 자체를, 추상클래스보다 더 추상적인 추상클래스라고 생각해야한다. 

instnace를 생성할 수 없다. interface 인터페이스 이름 으로 생성하지만, 구성요소가 추상메서드와 static 변수만 가능하다. 

이도 상속받을 수 있으나, 그 때 extends 대신 implements를 사용한다.

 

인터페이스가 returntype이 될수도, 매개변수가 될수도 있다.

인터페이스는 개발시간을 단축 -> 이를 활용하여 프로그램을 작성한다. 

표준화도 가능하다. interface로 기본 틀을 작성하고, 거기에 추가하여 작성하게 한다. 

상속관계가아닌 class간에도 이어줄 수 있다 .

클래스의 선언과 구현이 분리되어, 독립적인 프로그램 작성이 가능하다.

mock 사용에도 유용하고, 계층이 좀더 유기적이 된다.

 

**초 중요 * * 

혼자서 생긴 질문. INTERFACE는 추상 메소드만을 가질 수 있다고??

어? 맨날 SPRING 쓸때 INTERFACE로 JPARESPOTIROY를 EXTENDS해서 받으면 내부적인 FINDBYID같은 메소드들을 쓸 수 있었는데, JPA RESPOTIROY는 인터페이스인데 어떻게 가능하지 ?

 

-> 자바 8부터는, INTERFACE내부에서 STATIC METHOD같은 것들을 정의할수 있게 변화하였다. 

그렇기 때문에 JPAREPOSITORY라는 INTERFACE를 상속받더라도, JPAREPOSITORY 내부의 METHOD를 사용할 수 있다. 

 

default void BasicRespository기능 {}  -> default는 항상 public이다. 

or static void BasicRespository기능 {}과 같이 표현. 

class ChildClass extends ParentClass

interface ChildInterface extends ParentInterface

class MyClass implements MyInterface

interface ChildInterface extends ParentInterface 

 

implements는, 완성하다는 뜻이다. class가 interface를 받을때는 확장이 아니라 완성해야하기 떄문에 

implements가 추가되어야 한다. 

 

 

interface를 상속받고, 이를 활용하여 다른 두 객체간의 연결이 가능하게끔 돕는 예시. 

 

즉 interface는 소통,연결의 중간역할을 한다. (시멘이라 생각할 수도 있다) 

(spring처럼 추가 기능이되면. 기본을 이 시멘으로 깔수도 있는 것이고.) 

 

캡슐화 -> 수 많이 봤지만, 외부에서 내부 허용 기능 외에 접근하지 못하게 돕는 것.

 

내부 class 

클래스안에 ㅓㅅㄴ언된 클래스 . 코드 복잡성을 줄이고, 접근도 용이 

사용에 따라 instance, static, 지역, 익명 (일회용) class로 쓰인다. 

public class ClassA { private int x; public ClassA(int x) { this.x = x; } public int getX() { return x; }

 

가능한 형태이다. class 내부 class는, 같은 이름의 변수를 가질 수 있다. (Shadowing)

 

... 근데 왜 이렇게 복잡하게 할까?

캡슐화에 큰 도움이 되기 때문에. 내부를 외부 안에 숨겨서, 필요한 기능만을 제공할 수 있게 하기 위하여.

 

외부 class의 지역변수는 final이 붙은 변수만 접근 가능. 

외부 class a의 private x , static y, final c가 있을때. 

일반 class b는 x, y,z모두 접근 가능 * 공부하다 보니 1.8부터 바뀌었다 .

static class는 외부 class instace에 접근 불가(x). y엔 접근 가능 ,z도 가능.  static은 독립적인 class라고 생각해야한다. 

(생성 순서 때문에 ) 

 

Outer 내부에 Insatnce inner class, StaticInnerclass, MyMethod 함수가 있다면. 

main 에선 Outer cc = new Outer(); Outer.Innerclass ii = cc.new InstanceInner()로 생성한다. 

다만 sattaic 내부 class시에는 Outer.StaticInner si = new Outer.StaticInner(); 로 생성할 수 있다. 

 

 

갑자기 헷갈려서 돌아왔다 .

class에 private int x는, private는 class 내부에서만 사용 가능하다는 뜻이므로 public setx를 만들어, 
새로운 객체를 만들어서 걔는 x에 넣을수있게 해서 사용한다 

즉 myclass라는 인스턴스를 생성하면 myclass->setx->x는 되고 myclass->x는 안된다는 것 ! 

.. 그래서 set get이 생겼구나 

protected는 직접 접근은 여전히 막혀있지만, 내 자식은 접근 가능하다 

parent의 x를 child가 상속받아 만질순있지만, parent2.x는 안됨