⚙️ backend/☕️ java
Day04. 자바 프로그래밍 기본
dev!n
2023. 7. 7. 08:57
목차
Object Oriented Programming
Encapulattion(캡슐화-은닉)
- 외부에서 사용자가 속성을 직접 조회, 수정할 수 없도록 제한
- 개발자가 만들어 주는 대로만 사용할 수 있도록 메소드 제공 → setXxx, getXxx
- 관례) 생성자 밑에 작성
setXxx
- 필드를 수정한다
작성법
- modefier ⇒ public
- returntype ⇒ void
- methodName ⇒ setXxx()
- parameter ⇒ Exist!
왜 쓰지?
메소드이니까 기능을 만들 수 있다! 유저의 예상치 못한 상황을 제어.
⇒ 예외 처리해서 프로그램의 라이프 사이클이 원하는 방향으로 흘러가도록.
public void setAge(int age) {
if (age > 18) this.age = age;
}
getXxx
- 필드를 조회한다
작성법
- modefier ⇒ public
- returntype ⇒ 원하는 데이터 타입
- methodName ⇒ getXxx()
- parameter ⇒ null
왜 쓰지?
기능을 넣을 수 있다. 원하는 대로 데이터를 가공하여 데이터를 제공할 수 있다!
public int getAge() {
if(생일 지남) return age-1;
else return age-2;
}
Singleton Pattern
- 외부에서 객체를 직접 생성하지 못하도록 함
- 현재 객체를 직접 생성해서 리턴해주는 메소드 제공
왜 쓰지?
개발자가 직접 객체를 만들어 주기 때문에 개발자가 의도한대로만 생성된다
작성 방법
- private 기본 생성자
- 멤버필드로 static 자기 자신 타입 선언
- public static method를 제공하여 객체를 사용할 수 있도록 반환
public class Test {
private static Test instance = new Test();
// 생성자
private Test() {}
// 메소드
public static Test getInstance([parameter]) {
return instance;
}
}
/* 외부 서비스 */
Test t1 = Test.getInstance(); // singleton!
Test t2 = Test.getInstance(); // singleton!
Test t3 = Test.getInstance(); // singleton!
/* 출력결과 */
t1 = day04.constructor.Test@6aaa5eb0
t2 = day04.constructor.Test@6aaa5eb0
t3 = day04.constructor.Test@6aaa5eb0
cf) Calendar 객체는 싱글톤이 아님! 시간은 계속 달라지니까.
Calendar c1 = new Calendar // 불가
Calendar c2 = Calendar.getInstance(); // 다른게 나오긴 함
Inheritance(상속)
객체지향의 🌸
- 상속이란 부모(Super) class의 속성(전역변수 = Field)과 method를 상속 받는 것.
- 부모 class의 생성자와 private 요소를 제외한 모든 것을 상속받는다.
- 부모 class의 method와 속성을 별도의 선언 없이 내안에 있는 것처럼 접근하여 사용.
- 단일상속만 가능(부모는 단 하나. 하지만 대물림은 가능.)
- extends 키워드 사용
- ex) class A extends B { } ~> A가 B를 상속 받는다. A는 B의 것들을 다 사용한다.
- java의 모든 class는 Object(class)를 상속받는다. (java의 최고 조상. 부모가 없는 객체는 없다.)
- 자기만의 속성, 기능도 추가로 만들 수 있다.
- 부모타입으로는 자식의 속성, 메소드를 사용할 수 없다.
- 자식을 만들면 부모도 하나의 객체로 함께 생성된다. 힙 영역에 객체가 만들어진다.
왜 필요할까?
시나리오 안의 객체가 가져야 하는 공통의 속성(필드), 기능(메소드)를 만들어 두고 재사용하기 위해
Overriding
재정의
상속관계에서 Super(부모)class에 정의되어 있는 method를 Sub(자식) class에서 재정의 하는 것.
재정의 방법
- modifier의 접근제한자는 반드시 부모 class의 제한자 보다 크거나 같아야 한다. ⇨ 접근제한자 이외의 modifier(abstract)는 같아도 달라도 상관없다.
- returnType 무조건 같다.
- method이름, 인수 무조건 같다.
- 기능을 다르게 만든다. (기능이 다르지 않으면 만들 필요가 없다) ⇨ 즉, 부모 class의 method 기능이 마음에 들지 않아 다른 기능으로 재정의.
상속 관계일 때 생성자의 개념
- 자식 class가 생성 될 때 부모 class의 기본 생성자 호출된다.
- 자식 class가 인수가 있는 생성자를 호출하더라도 부모 class의 기본 생성자가 필요하다.⇨ 자식 생성자의 구현부 첫 번째 줄에서 super(); 생략된 것과 같다.
- ex) new Sub(5); 처럼 호출하더라도 super(); (기본생성자)가 호출된다.
- 자식 class에서 인위적으로 super(값, 값, ... ); 호출하면 부모의 기본생성자 필요없다.
- ⇨ 단, 모든 자식생성자에서 super(값, 값, ... ); 호출되어 있어야 문법에 오류가 없다.
- 자식 생성자 구현부 첫 번째 줄에서 this(값, 값, ... );은 호출하면 먼저 호출된 자식 생성자에 가서 이동한 자식 생성자 구현부 첫 번째 줄에서 super(); 호출된다.
ex) toString(Object obj)
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/String.html#toString()
Object에 있는데 String에서 재정의
@Override
@Override
Indicates that a method declaration is intended to override a method declaration in a supertype.
If a method is annotated with this annotation type compilers are required to generate an error message unless at least one of the following conditions hold:
The method does override or implement a method declared in a supertype.
The method has a signature that is override-equivalent to that of any public method declared in Object.
Since: 1.5
super
super의 사용법 3가지 (자식 클래스에서 부모를 칭함)
- super.변수이름 ⇨ 자식class에서 부모 class의 전역변수 호출 자식class의 변수이름과 부모class의 변수이름 같을 때 구분
- super.method이름( [값, 값, ...] ); ⇨ 자식class에서 부모class의 method호출
- super( [값, 값, ... ] ); ⇨ 자식 class의 생성자구현부 첫 번째 줄에서 부모 class의 생성자 호출
super, this 생성자에서만 사용!
Polymorphsim(다형성)
상속관계여야 한다
- class A extends B{ } 일 때 A를 A라 부를 수 있고 A를 B라 부를 수 있다. => class A extends B{ }일 때
- ㉠ A a = new A(); ⇨ O ㉡ B b = new A(); ⇨ O // polymorphism! ㉢ B c = new B(); ⇨ O ㉣ A d = new B(); ⇨ X
- 객체 자체가 바뀌는 것이 아니라 뭐라고 부르냐에 따라 접근할 수 있는 범위가 제한된다
방식
- 매개변수를 이용한 다형성
- class Sonata extends Car {/*소나타만의 속성, 기능이 있다.*/} class Example { public void engineer(Car cd){ System.out.println(cd + " 수리를 시작합니다."); } public static void main(String[] args) { // main Sonata sonata = new Sonata(); engineer(sonata); // polymorphism! } }
- 필드를 이용한 다형성 부모타입 변수 = 자식객체;
- class Example { public static void main(String[] args) { Car car1 = new Car(); Car car2 = new Sonata(); // polymorphism! } }
제약
- Car을 부모로 하는 여러가지 차가 들어와야 한다 → 무분별한 캐스팅 금지. 조건 걸기.
if (car instanceof EfSonata) { // 변수 instanceof 타입 System.out.println("car instanceof Sonata is true"); } else { System.out.println("car instanceof Sonata is false"); }
- Exception in thread "main" java.lang.ClassCastException: class day04.inheritance.Car cannot be cast to class day04.inheritance.Excel (day04.inheritance.Car and day04.inheritance.Excel are in unnamed module of loader 'app') at day04.inheritance.CarCenter.engineer(PolymorphismExam.java:18) at day04.inheritance.PolymorphismExam.main(PolymorphismExam.java:34)
- 유연해졌지만 접근에 제한이 있지 ⇒ 자식타입으로 만들면 접근 가능
- 실제적으로 정보를 사용하기 위해서는 Object Down Casting이 필요하다
- 의미적으로 부모>자식
instanceof
연산자. 결과값은 boolean.
- 반드시 상속관계일 때만 사용한다. (아니면 컴파일 오류)
- variable instanceof ObjectType
- ⇨ 왼쪽의 변수가 오른쪽의 Type이 될 수 있느냐?
- 왼쪽의 변수형이 오른쪽의 Type과 같거나 서브 class일 때 true이다. (왼쪽 <= 오른쪽)
- 캐스팅 할 때 매우 권장.
if (cd instanceof Excel) {
// Object Down Casting
Excel ex = (Excel) cd;
System.out.println("ex = " + ex);
System.out.println("ex.color = " + ex.color);
}