출처 : https://bamdule.tistory.com/51

인터페이스

인터페이스의 메소드는 메소드의 이름과 입출력에 대한 정의만 있고 그 내용은 없다. 그 이유는 인터페이스는 규칙이기 때문이다.

예를들면, USB포트의 규격만 알면 어떤 기기도 만들 수 있다. 또 컴퓨터는 USB 포트만 제공하고 어떤 기기가 만들어지는 지 신경쓸 필요가 없다. 바로 이 점이 인터페이스와 매우 비슷하다.

 

인터페이스 상수와 스태틱 메서드를 활용하여 클래스에서 사용하던 스태틱 메서드와 유사한 목적으로 사용 가능하다.

 

※ 인터페이스의 메소드는 항상 public으로 구현해야 한다.

인터페이스는 인터페이스의 메소드를 반드시 구현해야 하는 "강제성"을 갖는다는 점을 반드시 기억하자.

interface Predator {
		// = public static final
		int sampleCnt = 4;
		void bark();
		// static method in interface
		static int get() {
			return sampleCnt;
		}
}

상속

기존 클래스(base or super)와 새로 만드는 클래스(sub, child)의 관계를 설정하여 코드를 재사용할 수 있다. 베이스 클래스로부터 상속받아서 서브 클래스를 생성하면, 생성된 서브 클래스에서는 베이스 클래스의 모든 멤버를 갖게되고 동일한 인터페이스를 갖는다. 모든 서브 클래스는 베이스 클래스와 같은 타입이 된다.

class Animal {
		protected String name;
		private int age;
	}
	
class Cat extends Animal {
    void sleep() {
        System.out.println(this.name + " zzz");
    }
}
	
class HouseCat extends Cat {
    // method overriding.
    void sleep() {
        System.out.println(this.name + " zzz in house");
    }
}
Cat cat = new Cat();
cat.setName("cat");
cat.setAge(20);
cat.sleep();
System.out.println(cat.getName());

Animal animal = cat;
System.out.println(animal.getName());
// 불가 -> System.out.println(animal.sleep());
HouseCat hCat = new HouseCat();
hCat.setName("hcat");
hCat.sleep();

단, 자바는 다중상속을 지원하지 않는 점에 유의하자!

 

다형성

void barkAnimal(Animal animal) {
      if (animal instanceof Tiger) {
            System.out.println("어흥");
        } else if (animal instanceof Lion) {
            System.out.println("으르렁");
        } else if (animal instanceof Crocodile) {
          System.out.println("쩝쩝");
        } else if (animal instanceof Leopard) {
          System.out.println("캬옹");
        }
    }

위와 같은 메소드는 Animal 클래스를 상속받는 클래스가 증가함에 따라 분기처리가 늘어날 것이다. 이런 경우에 아래처럼 다형성을 활용하면 분기처리를 없앨 수 있고, 보다 명확하게 의미를 전달 할 수 있다.

class Animal {
    protected String name;
    private int age;

    void barkAnimal(Predator pre) {
        pre.bark();
    }
} 

class Cat extends Animal implements Predator{
    void sleep() {
        System.out.println(this.name + " zzz");
    }

    @Override
    public void bark() {
        System.out.println("==== Cat bark");
    }
}

class Dog extends Animal implements Predator {
    @Override
    public void bark() {
        System.out.println("==== Dog bark");
    }
}

참고로 인터페이스는 다중상속을 지원한다.

 

 

추상클래스

추상클래스(Abstract Class)는 인터페이스의 역할도 하면서 클래스의 기능도 가지고 있는 자바의 돌연변이 같은 클래스이다. 추상 클래스에는 abstract 메소드 외에 실제 메소드도 사용할수 있다. 추상클래스는 인터페이스로 대체하는것이 좋은 디자인이라고도 얘기한다.

 

추상 클래스는 인터페이스와는 달리 일반 클래스처럼 객체변수, 생성자, private 메서드 등을 가질 수 있다.

 

※ 추상 클래스는 일반 클래스와는 달리 단독으로 객체를 생성할 수 없다. 반드시 추상 클래스를 상속한 실제 클래스를 통해서만 객체를 생성할 수 있다.

abstract class Animal {
		private int age;
		protected String name;
		
		abstract void printName();
		void print() {
			System.out.println("print " + name);
		}
}
class Cat extends Animal {

    @Override
    void printName() {
        System.out.println("Cat!");
    }
    void print() {
        System.out.println("print child " + name);
    }

}
//불가 -> 구현체가 있어야한다.
//Animal animal = new Animal();

// 추상클래스로도 다형성을 구현가능.
Animal animal = new Cat();

animal.setName("jds");
animal.printName();
// 오버라이딩된다.
animal.print();

Cat cat = new Cat();
cat.setName("jds2");
cat.print();

출처

- https://wikidocs.net/280

 

'프로그래밍 > Java' 카테고리의 다른 글

Java Collection  (0) 2022.01.13

Entity에 다른 entity와 lazy loaded relationship이 있을 경우 hibernateLazyInitializer가 아래와 같이 포함된다.

"xx": {
        "id": 1,
        "hibernateLazyInitializer": {}
}

 

참조. https://stackoverflow.com/questions/18470438/exception-thrown-when-serializing-hibernate-object-to-json

When Hibernate loads objects from the DB, 
it returns proxied objects which look like your Advertisment or SessionT 
but have more "stuff" in them (to handle their relationship to the session, 
the internal state of lazy loaded collections etc.).

This throws off the Jackson serializer since it relies on introspection to find our the properties of the objects.

이때 jackson.serialization.FAIL_ON_EMPTY_BEANS가 true로 되어 있다면 에러가 발생한다.

No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

 

hibernateLazyInitializer를 무시한다던지 jackson.serialization.FAIL_ON_EMPTY_BEANS를 false로 설정하여 에러를 제거하는 방법도 있지만 근본적인 문제에 대해서 살펴보자.

 

Entity를 API에 노출하는 것이 과연 옳은 것일까?

한가지 장점이 있다. 매우 편하다..

 

하지만 그로인해 발생할 수 있는 문제점이 무엇이 있을까?

- 프레젠테이션 계층을 위한 로직이 Entity에 지속적으로 추가된다.(with @Transient)

고객이 항상 하는 이야기가 있다. 이것 추가해주세요.. 저것도 추가해주세요.. 

- API 검증을 위한 로직이 Entity에 지속적으로 추가된다.(@NotNull 등)

- 하나의 Entity가 다양한 API의 요구사항을 담기 어렵다.

- Entity가 변경되면 API도 변경되어야한다. 

 

결론은 프레젠테이션 영역으로 부터 전달받는 Request,
프레젠테이션으로 전달하는 Response를 따로 정의하자.

- https://stackoverflow.com/questions/18470438/exception-thrown-when-serializing-hibernate-object-to-json

Collection Framework란?

데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래수로 구현해 놓은 것

Collection Framework는 자바의 인터페이스(interface)를 사용하여 구현된다.

 

Collection Framework 주요 인터페이스

http://www.tcpschool.com/java/java_collectionFramework_concept

인터페이스 설명 구현 클래스
List<E> 순서가 있는 데이터의 집합으로, 데이터의 중복을 허용 Vector, ArrayList, LinkedList, Stack, Queue
Set<E> 순서가 없는 데이터의 집합으로, 데이터의 중복을 허용하지 않음. HashSet, TreeSet
Map<K, V> 키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음.
키는 중복을 허용하지 않지만, 값은 중복 허용
HashMap, TreeMap, HashTable, Properties

 

 

Collection 인터페이스

List와 Set 인터페이스의 많은 공통된 부분을 Collection 인터페이스에서 정의하고, 두 인터페이스는 그것을 상속받는다.

제공하는 주요 메소드는 아래와 같다.

메소드설명

boolean add(E e) 해당 컬렉션(collection)에 전달된 요소를 추가함. (선택적 기능)
void clear() 해당 컬렉션의 모든 요소를 제거함. (선택적 기능)
boolean contains(Object o) 해당 컬렉션이 전달된 객체를 포함하고 있는지를 확인함.
boolean equals(Object o) 해당 컬렉션과 전달된 객체가 같은지를 확인함.
boolean isEmpty() 해당 컬렉션이 비어있는지를 확인함.
Iterator<E> iterator() 해당 컬렉션의 반복자(iterator)를 반환함.
boolean remove(Object o) 해당 컬렉션에서 전달된 객체를 제거함. (선택적 기능)
int size() 해당 컬렉션의 요소의 총 개수를 반환함.
Object[] toArray() 해당 컬렉션의 모든 요소를 Object 타입의 배열로 반환함.

 


Stack 메소드

메소드 설명
boolean empty() 비어있는지 확인
Object peek() Stack의 맨 위에 저장된 객체를 반환
pop()과 달리 Stack에서 객체를 꺼내지 않음
비었을 때는 EmptyStackException 발생
Object pop() Stack의 맨 위에 저장된 객체를 꺼냄
비었을 때는 EmptyStackException 발생
Object push(Object item) Stack에 객체를 저장
int search(Object o) Stack에서 주어진 객체를 찾아서 그 위치를 반환, 못 찾으면 -1을 반환
배열과 달리 위치가 1부터 시작

 

Queue 메소드

메소드 설명
boolean add(Object o) 지정된 객체를 Queue에 추가
성공하면 true를 반환, 저장공간이 부족하면 illegalStateException 발생
Object peek() 삭제없이 요소를 읽어온다.
Queue가 비어있으면 null을 반환
Object remove() Queue에서 객체를 꺼내 반환
비어있으면 NoSuchElementException 발생
Object element() 삭제없이 요소를 읽어옴
peek와 달리 Queue가 비었을 때 NoSuchElementException 발생
boolean offer(Object o) Queue에 객체를 저장
성공하면 true, 실패하면 false를 반환
Object poll() Queue에서 객체를 꺼내서 반환.

 

Stack<Integer> st = new Stack<>();
st.push(1);
st.push(2);
System.out.println(st.peek()); // 2
st.pop();
System.out.println(st.peek()); // 1
st.pop();
System.out.println(st.empty());

System.out.println("===========");

Queue<Integer> q = new LinkedList<>();
q.add(1);
q.add(2);
System.out.println(q.peek()); // 1
q.remove();
System.out.println(q.peek()); // 2

- http://www.tcpschool.com/java/java_collectionFramework_concept

- https://www.javatpoint.com/collections-in-java

'프로그래밍 > Java' 카테고리의 다른 글

객체지향 프로그래밍(OOP) 기본  (0) 2022.02.28

+ Recent posts