티스토리 뷰
반응형
- 학습 목표 달성 확인 목록
- [] 제네릭 문법이 적용된 경우 인스턴스와 레퍼런스의 사용법을 이해하는가?
public class Member {
String name;
int age;
public Member(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Member [name=" + name + ", age=" + age + "]";
}
}
public class r {
public static void main(String[] args) {
//<>안에 객체를 넣어서 해당 객체만 삽입할 수 있게 해준다.
ArrayList<Member> list = new ArrayList<//Member *생략 가능//>();
list.add(new Member("오은석", 29));//Member객체만 넣을 수 있다.
list.add(new Member("이중섭", 41));
list.add(new Member("이순신", 44));
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
- [] 제네릭의 wildcard(?) 문법을 사용할 수 있는가?
ArrayList<?> list1;//해당 List를 타입상관없이 다루고 싶다면 <?>로 선언하면!
list1 = new ArrayList<>();
list1 = new ArrayList<Object>();//슈퍼 클래스도 넣을 수 있고
list1 = new ArrayList<String>();//서브 클래스들도 넣을 수 있다
list1 = new ArrayList<Integer>();
list1 = new ArrayList<Member>();
//단 이경우에는 제네릭의 타입이 명확하게 선언되지 않았기 때문에 제네릭 검사가 필요한 코드를 컴파일 불가하다
// list1.add(new String("오은석"));//컴파일 불가
- [] wildcard 문법에서 extends와 super 차이점을 이해하는가?
<? extends 상위타입>:상위 클래스 제한
매개변수의 자료형을 특정 클래스를 상속받은 클래스로만 제한한다.
class Person {
String name;
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
class Man extends Person {
// 생성자
Man(String name) {
super(name);
}
@Override
public String toString() {
return "Man{" +
"name='" + name + '\'' +
'}';
}
}
class Woman extends Person {
Woman(String name) {
super(name);
}
@Override
public String toString() {
return "Woman{" +
"name='" + name + '\'' +
'}';
}
}
public class sam {
public static void main(String[] args) {
ArrayList<Person> list1 = new ArrayList<>();
list1.add(new Person("아인슈타인"));
printData(list1);
System.out.println("------------------");
ArrayList<Man> list2 = new ArrayList<>();
list2.add(new Man("게이브 뉴웰"));
printData(list2);
System.out.println("------------------");
ArrayList<Woman> list3 = new ArrayList<>();
list3.add(new Woman("퀴리 부인"));
printData(list3);
}
//Person 클래스와 그 하위 클래소 생성된 인스턴스만 매개변수로 전달 가능하다
public static void printData(ArrayList<? extends Person> list) {
for (Person p : list) {
System.out.println(p);
}
}
}
//결과
Person{name='아인슈타인'}
------------------
Man{name='게이브 뉴웰'}
------------------
Woman{name='퀴리 부인'}
<? super 하위타입>:하위 클래스 제한
매개변수의 자료형을 특정 클래스와 그 클래스의 상위 클래스로만 제한한다.
class Person_1 {
String name;
public Person_1(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person_1{" +
"name='" + name + '\'' +
'}';
}
}
class Man_1 extends Person_1 {
public Man_1(String name) {
super(name);
}
@Override
public String toString() {
return "Man_1{" +
"name='" + name + '\'' +
'}';
}
}
class Woman_1 extends Person_1 {
public Woman_1(String name) {
super(name);
}
@Override
public String toString() {
return "Woman_1{" +
"name='" + name + '\'' +
'}';
}
}
public class sam111 {
public static void main(String[] args) {
ArrayList<Person_1> list1 = new ArrayList<>();
list1.add(new Person_1("인류"));
printData(list1);
System.out.println("------------------");
ArrayList<Man_1> list2 = new ArrayList<>();
list2.add(new Man_1("오펜하이머"));
printData(list2);
System.out.println("------------------");
ArrayList<Woman_1> list3 = new ArrayList<>();
list3.add(new Woman_1("빅토리아"));
// printData(list3);//Man 클래스의 사우이 클래스가 아니기때문에 메소드 호출 불가
}
//Person 클래스와 그 하위 클래소 생성된 인스턴스만 매개변수로 전달 가능하다
public static void printData(ArrayList<? super Man_1> list) {
for (Object o : list) {
System.out.println(o);
}
}
}
//결과
Person_1{name='인류'}
------------------
Man_1{name='오펜하이머'}
------------------
- [] 'funtional interface' 를 설명할 수 있는가?
추상 메서드가 한 개 있는 인터페이스를 'funtional interface'라고 부른다.
interface MP3 {
void playMusic();
}
- [] 람다(lambda) 문법을 사용할 수 있는가?
public class test {
public interface MP3 {//1.먼저 인터페이스를 만든다
void playMusic();//2.단 한개의 추상 매서드만 선언한다
}
public static void main(String[] args) {
MP3 mp3 = new MP3() {//3.익명 클래스로 인터페이스를 구현한다
@Override
public void playMusic() {
System.out.println("익명 클래스로 생성된 MP3이다.");
}
};
mp3.playMusic();
//여기서 람다문법으로 바꿔준다
/*
4.이렇게된 구간은 삭제한다
*/
MP3 mp31 = /*new MP3*/ () -> {
/*@Override
public void playMusic() */{
System.out.println("익명 클래스를 람다 문법으로 바꿔준 MP3이다.");
}
};//5.새미콜론 필수
mp31.playMusic();
//람다 완성
//매서드 한 개짜리 인터페이스를 구현한 익명 클래스를 좀 더 간단히 표현하기 위해 만든 문법이다
//즉 뻔한 코드를 생략하는 것이다
MP3 mp311 =() -> { System.out.println("익명 클래스를 람다 문법으로 바꿔준 MP3이다.");};//새미콜론 필수
mp311.playMusic();
/*
람다와 .class 파일
람다는 해당 클래스의 멤버 메서드로 정의된다
즉 별도의 .class 파일을 생성하지 않는다
람다 문법이 초기에 등장했을 때는 익명 클래스로 변환되었다.
하지만 최근에는 그냥 멤버 메서드로 변환된다.
->람다를 호출하는 코드는 자동 생성된 메서드를 호출하는 코드로 변환된다
*/
}
}
public class test {
public interface PMP {
void PlayMovie(String fileName);
}
public static void main(String[] args) {
PMP pmp = new PMP() {//인터페이스 구현
@Override
public void PlayMovie(String fileName) {
System.out.println(fileName + "영화 시청중...");
}
};
//1.파라미터는 괄호() 안에 선언한다
PMP pmp1 = (String fileName) ->System.out.println(fileName + "영화 시청중...");
pmp1.PlayMovie("터미네이터2");
System.out.println("===============================");
//2.파라미터 타입을 생략할 수 있다
PMP pmp2 = (fileName) ->System.out.println(fileName + "영화 시청중...");
pmp2.PlayMovie("백투더 퓨쳐2");
System.out.println("===============================");
//2.파라미터가 한 개일 때는 괄호도 생략할 수 있다
PMP pmp3 = fileName -> System.out.println(fileName + "영화 시청중...");
pmp3.PlayMovie("캐치미 이프 유캔");
System.out.println("===============================");
}
}
public class test_02 {
public interface IPAD {
void use(String gameName, double version);
}
public static void main(String[] args) {
IPAD ipad = new IPAD() {//1.인터페이스 구현
@Override
public void use(String gameName, double version) {
System.out.printf("%s %.1f version 게임을 하고있습니다.\n", gameName, version);
}
};
ipad.use("앵그리버드", 2.5);
System.out.println("===============================");
//1.파라미터는 괄호() 안에 선언한다
IPAD ipad1 = (String gameName, double version) -> System.out.printf("%s %.1f version 게임을 하고있습니다.\n", gameName, version);
ipad.use("모두의 마블", 5.0);
System.out.println("===============================");
//2.파라미터 타입을 생략할 수 있다
IPAD ipad2 = (gameName, version) -> System.out.printf("%s %.1f version 게임을 하고있습니다.\n", gameName, version);
ipad.use("리니지", 3.1);
System.out.println("===============================");
//3.파라미터가 여러 개일 때는 괄호를 생략할 수 없다
// IPAD ipad3 = gameName, version -> System.out.printf("%s %d.version 게임을 하고있습니다.", gameName, version);
}
}
- [] 로컬 클래스를 익명 클래스로 바꿀 수 있는가?
public class test_03 {
static interface Player {
void play();
}
static void testPlayer(Player player) {
player.play();
}
public static void main(String[] args) {
//로컬 클래스
class MyPlayer implements Player {
@Override
public void play() {
System.out.println("플레이!");
}
}
MyPlayer myPlayer = new MyPlayer();
testPlayer(myPlayer);
//위의 로컬 클래스를 익명클래스로 바꾼다
testPlayer(() -> System.out.println("플레이!"));
}
}
- [] 익명 클래스를 람다 코드로 바꿀 수 있는가?
public class test_04 {
static interface Calculator {
int compute(int a, int b);
}
static void test(Calculator c) {
System.out.println(c.compute(100, 200));
}
public static void main(String[] args) {
test(new Calculator() {
@Override
public int compute(int a, int b) {
return a + b;
}
});
//위의 익명클래스를 람다로 바꿀수 있다
test((a, b) -> a + b);
}
}
- [] 스태틱 메서드를 '메서드 레퍼런스'로 활용할 수 있는가?
public class test {
static class MyCalculator {
public static int plus(int a, int b) {
return a + b;
}
public static int minus(int a, int b) {
return a - b;
}
public static int multiple(int a, int b) {
return a * b;
}
public static int divide(int a, int b) {
return a / b;
}
interface Calculator {
int compute(int x, int y);
}
public static void main(String[] args) {
/*
메서드 한 개짜리 인터페이스의 구현체를 만들 때
기존 스태틱 메서드를 람다 구현체로 사용할 수 있다
단 인터페이스에 선언된 메서드의 규격과 일치해야 한다
규격?파라미터 타입 및 개수,리턴 타입
문법:
클래스명.메서드명
*/
Calculator c1 = MyCalculator::plus;
Calculator c2 = MyCalculator::minus;
Calculator c3 = MyCalculator::multiple;
Calculator c4 = MyCalculator::divide;
System.out.println(c1.compute(200,17));
System.out.println(c2.compute(200,17));
System.out.println(c3.compute(200,17));
System.out.println(c4.compute(200,17));
}
}
}
//결과
217
183
3400
11
//상위의 코드의 내부는 다음과 같다
Calculator cc = new Calculator() {
@Override
public int compute(int x, int y) {
return MyCalculator.plus(x, y);
}
};
System.out.println(cc.compute(200, 17));
- [] 인스턴스 메서드를 '메서드 레퍼런스'로 활용할 수 있는가?
public class test_05 {
static class Calculator {
double rate;
public Calculator(double rate) {
this.rate = rate;
}
public double year(int money) {
return money * rate / 100;
}
public double month(int money) {
return money * rate / 100 / 12;
}
public double day(int moeny) {
return moeny * rate / 100 / 365;
}
}
static interface Interest {
double compute(int money);
}
public static void main(String[] args) {
Calculator 보통예금 = new Calculator(0.5);
Calculator 정기예금 = new Calculator(1.5);
Calculator 청년행복예금 = new Calculator(10);
System.out.println("보통예금");
Interest i1 = 보통예금::year;
//코드의 내부
// Interest i1 = new Interest() {
// @Override
// public double compute(int money) {
// return 보통예금.year(money);
// }
// };
System.out.printf("년 이자: %.1f\n", i1.compute(10_0000_0000));
i1 = 보통예금::month;
System.out.printf("월 이자: %.1f\n", i1.compute(10_0000_0000));
i1 = 보통예금::day;
System.out.printf("일 이자: %.1f\n", i1.compute(10_0000_0000));
System.out.println("------------------------------");
System.out.println("정기예금");
Interest i2 = 정기예금::year;
System.out.printf("년 이자: %.1f\n", i1.compute(10_0000_0000));
i2 = 정기예금::month;
System.out.printf("월 이자: %.1f\n", i1.compute(10_0000_0000));
i2 = 정기예금::day;
System.out.printf("일 이자: %.1f\n", i1.compute(10_0000_0000));
}
}
- [] 생성자를 '메서드 레퍼런스'로 활용할 수 있는가?
public class test_06 {
static class Message {
String name;
int age;
public Message() {
this.name = "이름없음";
}
public Message(String name) {
this.name = name;
}
public Message(String name, int age) {
this.name = name;
this.age = age;
}
public static void print(Message message) {
if (message.name.equals("이름없음")) {
System.out.println("이름없음");
} else {
System.out.printf("%s님 반갑습니다.\n", message.name);
}
}
}
static interface Factory1 {
Message get();
}
static interface Factory2 {
Message get(String name);
}
static interface Factory3 {
Message get(String name, int age);
}
public static void main(String[] args) {
Factory1 f1 = Message::new;//public Message() 생성자
Message.print(f1.get());
Factory2 f2 = Message::new;//public Message(String name) 생성자
Message.print(f2.get("고든 프리맨"));
Factory3 f3 = Message::new;//public Message(String name, int age) 생성자
Message.print(f3.get("G맨", 100));
}
}
- [] List의 forEach() 메서드를 활용하여 목록을 조회할 수 있는가?
public class test_07 {
public static void main(String[] args) {
ArrayList<String> names = new ArrayList<>();
names.add("브루스웨인");
names.add("조커");
names.add("제임스고든");
names.add("하비덴트");
names.add("알프레드");
//forEach() 사용 전
// for (String name : names) {
// System.out.println(name);
// }
//forEach() 사용 후
class MyConsumer<T> implements Consumer<T> {
@Override
public void accept(T t) {
System.out.println(t);
}
}
names.forEach(new MyConsumer<String>());
}
}
반응형
'Academy' 카테고리의 다른 글
| [210224]File I/O API (0) | 2021.03.01 |
|---|---|
| [210222]예외 (0) | 2021.02.28 |
| [210218]Command Design Pattern (0) | 2021.02.24 |
| [210217]자바 API (0) | 2021.02.24 |
| [210216]제네릭 (0) | 2021.02.23 |
