Java_상속 및 클래스 && 람다

ChoRong0824·2023년 5월 2일
0

Java

목록 보기
12/31
post-thumbnail

자바를 JAVA🥸,, 필자가 이해한 내용을 토대로
상속 및 클래스부터 람다까지 제대로 정리하겠습니다.
(이해를 돕고자, 코드 및 그림 추가하였습니다)

상속

상속이란 ?

  • 상속은 부모클래스를 상속받은 자식 클래스는 부모 클래스의 캡슐화(속성+기능) 이용가능합니다.

상속의 필요성

  • 기존의 검증된 class를 이용해서 빠르고 쉽게 새로운 class를 만들 수 있습니다.

Ex)
G_Food : 할아버지 운영, 10개 메뉴
P_Food : 아버지 운영,(할아버지 메뉴 10개 + 아버지의 독특한 메뉴 2개), 총 12개
C_Food : 아들 운영, (할아버지 메뉴 10개 + 아버지의 메뉴 2개, 아들 메뉴 3개) 총 15개

즉, 검증된 메뉴를 이용해서 쉽고 빠르게 개업할 수 있습니다.

상속 구현

참고 , 자바의 상속은 다중 상속을 지원하지 않고, 단일 상속만 지원합니다.
(1개의 클래스가 1개의 클래스만 상속가능. 1 : 1 반응)

private 접근자

자식 클래스는 부모 클래스의 모든 자원을 사용할 수 있지만, private 접근자의 속성과 메서드는 사용할 수 없습니다.


상속의 특징

메서드 오버라이드(override)

  • 부모의 클래스의 기능을 자식 클래스에서 재정의 해서 사용
  • @어노테이션은 추가해주는것이 구별하기 좋으며 가독성이 증가하기 때문에, 웬만해선 어노테이션을 추가해줍니다.
  • cc 의 데이터 타입은 ChildClass 입니다.
    이렇게, 기본자료형처럼 클래스도 자료형이 되는 것입니다.

super 클래스

  • 상위 클래스를 호출할 때, super 키워드 사용

내부클래스 && 익명클래스

내부 클래스

  • 클래스 안에 또 다른 클래스를 선언하는 방법을 말합니다.
    이렇게 하면, 두 클래스의 멤버에 쉽게 접근할 수 있다는 장점이 있습니다.
    BUT, 가독성이 떨어져서, 요즘은 사용하지 않습니다.

익명클래스

  • 이름이 없는 클래스를 선언하는 방법이며, (이름이 없는 클래스임)
    주로 메서드를 재정의 하는 목적으로 사용합니다.

    즉,
    Anonymouseclass ac = new Anonymouseclass();
    이름 없이 new Anonymouseclass(); 객체 생성만 하여 사용합니다.

  • 이름이 없어서, 생성된 객체를 호출할 방법이 없기때문에, 한번만 사용하고 버릴것입니다.
    BUT, 이를 살리려면 도트접근자. 를 사용해서 필요한 메서드를 접근하면 됨.

익명 클래스는 주로 인터페이스나 추상클래스에 사용됩니다.


인터페이스

인터페이스란 ?

  • 클래스와 달리 객체를 생성할 수는 없으며, 클래스에서 구현해야 하는 작업 명세서 입니다.

인터페이스를 사용하는 이유 ?

  • 가장 큰 이유는 객체가 다양한 자료형(타입)을 가질 수 있기 때문입니다.

인터페이스 구현

  • (주석처리 읽기), implements 클래스에서 구현함.

예시

interface를 이용하면 객체가 다양한 자료형(타입)을 가질 수 있습니다.
-> 객체 타입이 다형성을 가지는 것이라고 보면됨

  • main 클래스
  • 클래스 list

추상클래스

인터페이스와 비슷한 형태로, 구체화되지 않은 멤버를 이용해서 클래스를 만드는 방법입니다.
abstract 을 사용해서 (메서드 || 클래스) 구현 가능.

추상클래스란 ?

  • 클래스의 공통된 부븐을 뽑아서 별도의 클래스 (추상클래스)로 만들어 놓고, 이것을 상속해서 사용합니다.

abstract 클래스의 특징

• 멤버변수를 가진다.
• abstract 클래스를 상속하기 위해서는 extends 를 이용한다.
• abstract 메서드를 가지며, 상속한 클래스에서 반드시 구현해야 한다.
• 일반메서드도 가질 수 있다.
• 일반 클래스와 마찬가지로 생성자도 있다.

추상클래스 구현

public abstract class AbstractClassEx {

// 멤버
int num;
String str;

// 생성자
public AbstractClassEx() { 
System.out.println("AbstractClassEx constructor"); 
}

// 생성자
public AbstractClassEx(int i, String s) {
System.out.println("AbstractClassEx constructor");

this.num = i; 
this.str = s; 
}

//메서드
public void fun1() {
System.out.println(" -- fun1() START -- "); 
}

public abstract void fun2(); 
}

인터페이스 VS 추상클래스

  • 공통점
  1. 추상 메서드를 가진다.
  2. 객체 생성이 불가하며, 자료형(타입)으로 사용된다
  • 차이점

    인터페이스
    1, 상수, 추상메서드만 가진다.
    2, 추상메스드를 구현만 하도록 한다.
    3, 다형성을 지원한다.

    추상클래스
    1, 클래스가 가지는 모든 속성과 기능을 가진다.
    2, 추상 메서드 구현 및 상속의 기능을 가진다.
    3, 단일 상속만 지원한다.


람다식

람다식이란 ?

  • 익명 함수를 이용해서, 익명 객체를 생성하기 위한 식입니다.

    다시 말해, 람다 함수는 익명 함수를 지칭하는 용어이며, 함수를 보다 단순하게 표현하는 방법입니다.

람다식 구현

  • 람다식은 기본적으로 함수를 만들어 사용한다고 생각하면 됩니다.

    메서드를 이용하고 싶으면, 해당 메서드에 가장 핵심적인 파라미터, 실행문을 만들어주고,
    앞서 말한것을 바로 이용해서, 원하는 값을 빨리 빨리 도출할 수 있기 때문에 람다식을 사용함.

//1
public interface LambdaInterface1 {
    public void method(String s1, String s2, String s3);
}
//2
public interface LambdaInterface2 {

    public void method(String s1);

}
//3
public interface LambdaInterface4 {

    public int method(int x, int y);

}
//4
public interface LambdaInterface3 {

    public void method();

}

즉, 함수를 내 마음대로 진행가능함.
다시 말해, 인터페이스는 껍데기만 제공해주고, 개발자 마음대로 개발 및 사용 가능함.

람다의 장단점

장점
1. 코드의 간결성 : 람다를 사용하면 불필요한 반복문의 삭제가 가능하며, 복잡한 식을 단순하게 표현가능합니다.
2. 자연연산 수행 : 람다는 지연연상을 수행 함으로써, 불필요한 연산을 최소화 할 수 있습니다.
3. 병렬처리 가능 : 멀티 쓰레디를 활용하여, 병렬처리를 사용할 수 있습니다.

단점
1. 람다식의 호출이 까다롭습니다.
2. 람다 stream 사용 시, 단순 for문 혹은 while문 사용 시 성능이 떨어집니다.
3. 불필요하게 너무 사용하게 되면, 오히려 가독성이 떨어질 수 있습니다.

람다 표현식

1. 람다는 매개변수 화살표 `->` 함수 몸체로 이용하여 사용할 수 있습니다.
2. 함수몸체가 단일 실행문이면 괄호`{ }`를 생략할 수 있습니다.
3. 함수몸체가 return 문으로만 구성되어 있는 경우 괄호 `{}`를 생략할 수 없습니다.

람다 예제

  • java
new Thread(new Runnable(){
	@Override
    public void run(){
    	System.out.println("Welcome SjMun09 Velog");
        }
}).start();
  • 람다
new Thread(() -> {
	System.out.println("Welcome SjMun09 Velog");
}).start();

예제를 통해, 람다식을 사용하면, 코드가 간결해지고 가독성이 좋아짐을 확인할 수 있습니다.

필자의 내용으로도 이해가 안된다면,해당 블로그를 참고 하시면 좋을 것 같습니다.


문자열 클래스

String 객체와 메모리 관계

  • 문자열을 다루는 String 클래스(객체)는 데이터가 변하면 메모리상의 변화가 많아 속도가 느립니다.
    또한, 문자열이 변경되면 기존의 객체를 버리고, 새로운 객체를 메모리에 생성합니다.
    이때, 기존 객체는 가비지 컬렉터에 의해서 메모리 회수가 이루어집니다.

StringBuffer, String Builder

StringBuffer sf = new StringBuffer(“JAVA");
sf.append(" _8");

  • String 클래스의 단점을 보완한 클래스로 데이터가 변경되면 메모리에서 기존 객체를 재활용합니다.
    • 문자열이 변경되면 기존의 객체를 재활용합니다.
    • 속도는 StringBuilder가 조금 더 빠르며,
    데이터 안정성은 StringBuffer가 조금 더 좋습니다

Collections || 자료형

배열과 같이 자료(데이터)를 효율적으로 관리하기 위한방법입니다.

List

List는 인턴페이스이며, 이를 구현한 클래스는 인덱스를 이용해서 데이터를 관리한다.

  • 데이터는 다 지워도, 객체는 살아있습니다. (말 그대로, 데이터만 지우는거임)

Map

Map은 인터페이스이며, 이를 구현한 클래스는 key를 이용해서 데이터를 관리한다.

  • 각 데이터마다의 키값이라는 것이 있음.(데이터를 찾는)
    키를 개발자가 만들어야함. -> 키 값이라는 것은 유일한 값이어야함. (key중복 불가능 but 데이터 중복가능)

import java.util.ArrayList;
import java.util.HashMap;

public class MainClass {

	public static void main(String[] args) {
		
		// ArrayList 객체 생성
		ArrayList<String> list = new ArrayList<String>();
		
		System.out.println("list.size : " + list.size());
		
		// 데이터 추가
		list.add("Hello");
		list.add("Java");
		list.add("World");
		System.out.println("list.size : " + list.size());
		System.out.println("list : " + list);
		
		list.add(2, "Programing");	// 데이터 추가, 인덱스는 하나씩 밀림
		System.out.println("list : " + list);
		
		list.set(1, "C");			// 해당하는 인덱스의 데이터 변경
		System.out.println("list : " + list);
		
		// 데이터 추출
		String str = list.get(2);
		System.out.println("list.get(2) : " + str);
		System.out.println("list : " + list);
		
		// 데이터 제거
		str = list.remove(2);
		System.out.println("list.remove(2) : " + str);
		System.out.println("list : " + list);
		
		// 데이터 전체 제거
		list.clear(); // 이걸 통해서 제거함.
		System.out.println("list : " + list);
		
		// 데이터 유무
		boolean b = list.isEmpty();
		System.out.println("list.isEmpty() : " + b);
		
		System.out.println(" ==================================== ");
		System.out.println(" ===============여기서터는 HashMap 내용임===================== ");
        
		// HashMap 객체 생성
		HashMap<Integer, String> map = new HashMap<Integer, String>();
		System.out.println("map.size() : " + map.size());
		
		// 데이터 추가
		map.put(5, "Hello"); // 앞에는 키값, 뒤에는 벨류가 들어감. 
		map.put(6, "Java"); // 데이터 추가시엔 put 메서드 사용함.
		map.put(7, "World");
		System.out.println("map : " + map);
		System.out.println("map.size() : " + map.size()); // 맵 사이즈는 위에 3개 추가했으니, 3개가 됨.
		
		map.put(8, "!!");
		System.out.println("map : " + map);
		
		// 데이터 교체
		map.put(6, "C");
		System.out.println("map : " + map);
		
		// 데이터 추출
		str = map.get(5); //get을 써서 해당하는 데이터 출력함
		System.out.println("map.get(5) : " + str);  
		
		// 데이터 제거
		map.remove(8);
		System.out.println("map : " + map);
		
		// 특정 데이터 포함 유무
		b = map.containsKey(7);
		System.out.println("map.containsKey(7) : " + b);
		
		b = map.containsValue("World");
		System.out.println("map.containsValue(\"World\") : " + b);
		
		// 데이터 전체 제거
		map.clear();
		System.out.println("map : " + map);
		
		// 데이터 유무
		b = map.isEmpty(); // 1개 이상 있는지 없는지 확인
		System.out.println("map.isEmpty() : " + b);
	}
	
}
profile
컴퓨터공학과에 재학중이며, 백엔드를 지향하고 있습니다. 많이 부족하지만 열심히 노력해서 실력을 갈고 닦겠습니다. 부족하고 틀린 부분이 있을 수도 있지만 이쁘게 봐주시면 감사하겠습니다. 틀린 부분은 댓글 남겨주시면 제가 따로 학습 및 자료를 찾아봐서 제 것으로 만들도록 하겠습니다. 귀중한 시간 방문해주셔서 감사합니다.

0개의 댓글