- abstract
- 생성자 -> 생략
- final
- instance of 연산자
- package 키워드 -> 생략
- interface & implements 키워드
- this 키워드
- super 키워드
public abstract class 개발자 { //-> 추상 클래스
abstract void 코딩하다(); // 추상메소드
}
class Naver extends 개발자 {
@Override
void 코딩하다() {
// 네이버 웹툰을
}
}
class 당근 extends 개발자 {
@Override
void 코딩하다() {
// 물건 판매 채팅을
}
}
class 배민 extends 개발자 {
@Override
void 코딩하다() {
// 티켓 판매 쿠폰을
}
}
장점은? 추상 클래스를 이용하면 하위 클래스(네이버, 당근, 배민)클래스에게 구현을 강제할 수 있다. (빠뜨릴수 있는 부분을 강제 적용)
정리를 하면 추상 클래스는 공통적으로 개발해야 할 부분을 적는 부분이라고 생각하면 된다.
질문? abstract클래스만 상속을 받아 사용할까?!
답은 NO
우리가 사용했던 BaseTimeEntity를 살펴보자@Getter @MappedSuperclass @EntityListeners(AuditingEntityListener.class) public class BaseTimeEntity { @CreatedDate // entity가 생성되어 저장될때 시간이 자동 저장 private LocalDateTime createdDate; @LastModifiedDate // entity 변경할때 시간이 자동 저장 private LocalDateTime modifiedDate; }
- 상속받아 사용가능하다
- 단 강제로 명시는 안해도 된다! 이유는?! 상속받은 클래스가 abstract 클래스가 아니기 때문에!
public class global {
public static String tcpIp = "192.168.1.101";
public static String port = 56;
public static String udpIP = "192.168.1.102";
public static int udpPort = 57;
}
public class global {
static {
int port=8080;
String ip="192.168.1.172";
}
}
객체에서 static (공통)으로 사용되는 부분을 건들일수 있을까?!
만약) 서비스 1, 서비스 2 -> static HashMap을 건들이면?!
Map에는 변경된 값이 들어가서 Error 발생!
이런 Lock을 방지할 수 있는 Map이 있는데 Concurrent HashMap
반대로 static에서 객체를 건들일 수 있을까?!
- 정답은 NO
static 블록에서 사용할 수 있는 속성과 메소드는 static 멤버 뿐
객체 멤버에 접근할 방법이 없음.
static 블록은 메모리에 이미 올라가있기 때문에 객체에서 접근이 가능
static 블록에서는 객체를 못찾기 때문에 접근 불가
public class 기밀문서 {
final void MAKED_1급비밀() {
// 절대 보안
}
}
class 공군 extends 기밀문서 {
void MAKED_1급비밀() { // **컴파일 에러 발생!**
}
}
public final class 기밀문서 { // 상속 허락 안함
}
public class 육군 extends 기밀문서 {} //상속 못함
class 동물 {
}
class 조류 extends 동물 {
}
class 펭귄 extends 조류 {
}
public class Test{
public static void main(String[] args) {
동물 동물객체=new 동물();
조류 동물객체=new 조류();
펭귄 펭귄객체=new 펭귄();
동물객체 instanceof 동물; // true
조류객체 instanceof 동물; //true
조류객체 instanceof 조류; //true
펭귄객체 instanceof 동물; //true
펭귄객체 instanceof 조류; //true
펭귄객체 instanceof 펭귄; //true
펭귄객체 instanceof Object // true
}
}
동물 동물객체=new 동물();
동물 동물객체=new 조류();
동물 펭귄객체=new 펭귄();
동물객체 instanceof 동물; // true
조류객체 instanceof 동물; //true
조류객체 instanceof 조류; //true
펭귄객체 instanceof 동물; //true
펭귄객체 instanceof 조류; //true
펭귄객체 instanceof 펭귄; //true
펭귄객체 instanceof Object // true
public int calucate(final Item item) {
return item.calcurate();
}
public int calucate(final Apple apple) {
return apple.calcurate();
}
public class Rectangle {
private int width;
private int height;
public void setWidth(final int width) {
this.width = width;
}
public void setHeight(final int height) {
this.height = height;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}
public class Square extends Rectangle {
@Override
public void setWidth(final int width) {
super.setWidth(width);
super.setHeight(width);
}
@Override
public void setHeight(final int height) {
super.setWidth(height);
super.setHeight(height);
}
}
public void increaseHeight(final Rectangle rectangle) {
if (rectangle.getHeight() <= rectangle.getWidth()) {
rectangle.setHeight(rectangle.getWidth() + 1);
}
}
public void increaseHeight(final Rectangle rectangle) {
if (rectangle instanceof Square) {
throw new IllegalStateException();
}
if (rectangle.getHeight() <= rectangle.getWidth()) {
rectangle.setHeight(rectangle.getWidth() + 1);
}
}
그럼 애초에 뭐가 잘못되었냐?!
- 상속을 잘못받음. Square 클래스는 Rectangle 클래스를 상속받으면 안 된다.
그럼 LSP를 지키기 위해서는 어떻게 설계를 해야 할까?!
상속을 사용할때는 계층도 /조직도에 따라 설계를 하는것이 아니라 a kind of ~에 따라 상속을 이용하자.
interface Speakable {
double PI=3.14;
double ZEROPOINT=-275.15;
void sayHello();
}
interface Speakable {
public static final double PI=3.14;
public static final double ZEROPOINT=-275.15;
public abstract void sayHello();
}
class TT {
int var=10;
void test() {
int var=20;
System.out.println(var); // 20
System.out.println(this.var); //10
}
}
class 사람 {
void method() {
System.out.println("사람");
}
}
class 네이버 extends 사람 {
void method() {
super.method(); // 사람
System.out.println("네이버"); //네이버
}
}
class 네이버_웹툰 extends 네이버 {
void method() {
super.method(); // 네이버
System.out.println("네이버_웹툰");
}
}
class 네이버_웹툰 extends 네이버 {
void method() {
super.super.method(); // 사람? NO 불가능
System.out.println("네이버_웹툰");
}
}
Class 펭귄 {
void test() {
// TEST
}
public class Driver {
public static void main(String[] args) {
펭귄 뽀로로 =new 펭귄();
뽀로로.test();
}
}
펭귄 뽀로로1=new 펭귄();
펭귄 뽀로로2=new 펭귄();
펭귄 뽀로로3=new 펭귄();
...
펭귄 뽀로로100=new 펭귄();