From 51998c2d0701f0014955f944733f26e18db447db Mon Sep 17 00:00:00 2001 From: MyungJune Shin <64180930+go-the-extra-mile@users.noreply.github.com> Date: Fri, 7 Jul 2023 10:56:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?=EA=B0=9D=EC=B2=B4=EC=A7=80=ED=96=A5,=20?= =?UTF-8?q?=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC=20=EB=85=B8=ED=8A=B8=20?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...35\354\262\264\354\247\200\355\226\245.md" | 215 ++++++++++++++++++ ...10\354\231\270\354\262\230\353\246\254.md" | 126 ++++++++++ 2 files changed, 341 insertions(+) create mode 100644 "Ch 11 \352\260\235\354\262\264\354\247\200\355\226\245.md" create mode 100644 "Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" diff --git "a/Ch 11 \352\260\235\354\262\264\354\247\200\355\226\245.md" "b/Ch 11 \352\260\235\354\262\264\354\247\200\355\226\245.md" new file mode 100644 index 0000000..878e720 --- /dev/null +++ "b/Ch 11 \352\260\235\354\262\264\354\247\200\355\226\245.md" @@ -0,0 +1,215 @@ +# Ch. 11 객체지향 + +# 생성자 + +내가 코드 안 치면 비어있는 디폴트 생성자 만들어줌 + +내가 생성자 만들면 디폴트 생성자 만들어지지 않음 + +객체 변수에 값을 무조건 설정해야만 객체가 생성될 수 있게 강제하는 방법으로 생성자를 쓸 수 있다. + +생성자는 클래스명과 메소드명이 같으며 리턴타입을 쓰지 않는다. + +생성자도 오버로딩이 가능하다. + +# 상속 + +단일 상속만 가능 + +`extends` 키워드를 사용 + +# 오버로딩 + +한 클래스에서 매개변수가 다른, 같은 이름의 메소드 여러 개를 정의할 수 있는 것을 말한다. + +매개변수의 개수나 타입이 다르면 서로 다른 메소드로 본다. 하지만, 리턴타입만 다른 경우는 모호하기 때문에 허용되지 않는다. + +같은 기능을 하는 메소드를 하나의 이름으로 지정해 가독성을 높이는 장점이 있다. + +```java +public class OverloadingTest { + public static void main(String[] args) { + Calculator calc = new Calculator(); + + **System.out.println(calc.add(1, 2)); + System.out.println(calc.add(1, 2, 3));** + } +} + +class Calculator { + public int add(int a, int b){ + return a + b; + } + public int add(int a, int b, int c){ + return a + b + c; + } +} +``` + +# 오버라이딩 + +부모 클래스에서 상속받은 메소드의 내용을 자식 클래스의 상황에 맞게 변경하는 것으로, 메소드 이름, 매개변수, 리턴타입이 모두 같아야 오버라이딩된다. 오버라이딩 메소드는 오버리든 메소드 리턴타입의 서브타입을 리턴해도 된다. + +오버라이딩할 때는 `@Override` 애노테이션을 쓸 수 있다. 컴파일러가 정말 오버라이드를 하는지 확인하고 그렇지 않다면 에러를 던진다. + +오버라이딩 메소드는 오버리든 메소드의 접근제어자를 더 넓게 설정할 수는 있어도, 더 좁게 설정할 수는 없다. + +예를 들어 오버리든 메소드가 `default` 접근제어를 한다면, 오버라이딩 메소드는 더 넓은 `default`, `protected`, `public`으로 설정 가능하다. 하지만 `private`으로 설정할 수는 없다. + +오버라이딩 메소드는 오버리든 메소드가 throw하는 exception보다 작은 범위의 exception만 throw할 수 있다. + +```java +public class OverridingTest { + public static void main(String args[]){ + Person person = new Person(); + Child child = new Child(); + Senior senior = new Senior(); + + person.cry(); + child.cry(); + senior.cry(); + } +} + +class Person { + void cry() { + System.out.println("흑흑"); + } +} + +class Child extends Person { + @Override + protected void cry() { + System.out.println("응애"); + } +} + +class Senior extends Person { + public void cry() { + System.out.println("훌쩍훌쩍"); + } +} +``` + +## static 메소드 오버라이딩 + +static 메소드도 같은 메소드 이름, 매개변수, 리턴타입의 메소드를 서브클래스에 적어줄 수 있다. 단, 이 경우는 오버라이딩의 방식이 아닌 숨기는 방식으로 작동한다. 무슨 말인지 예시를 통해 설명한다. + +### 예시 + +```java +public class StaticHideTest { + public static void main(String[] args){ + Cat myCat = new Cat(); + Animal myAnimal = myCat; + myCat.testClassMethod(); // The static method in Cat + myAnimal.testClassMethod(); // The static method in Animal + + myCat.testInstanceMethod(); // The instance method in Cat + myAnimal.testInstanceMethod(); // The instance method in Cat + } +} + +class Animal { + public static void testClassMethod() { + System.out.println("The static method in Animal"); + } + public void testInstanceMethod() { + System.out.println("The instance method in Animal"); + } +} + +class Cat extends Animal { + public static void testClassMethod() { + System.out.println("The static method in Cat"); + } + public void testInstanceMethod() { + System.out.println("The instance method in Cat"); + } +} +``` + +사실 같은 객체를 가리키는 myCat과 myAnimal에서 각각 static 메소드를 호출하면, 각자 다른 함수를 호출하는 것을 볼 수 있다. myCat은 Cat 클래스의 static 메소드를 호출하고, myAnimal은 Animal 클래스의 static 메소드를 호출한다. + +반면 myCat과 myAnimal에서 인스턴스 메소드를 호출하면, Cat 객체이므로 Cat 클래스의 인스턴스 메소드가 호출되는 것을 볼 수 있다. + +### 오버라이딩으로 static 여부가 바뀔 수는 없다 + +static 메소드를 인스턴스 메소드로 오버라이드할 수 없다. + +인스턴스 메소드를 static 메소드로 오버라이드할 수 없다. + +# 인터페이스 + +클래스와 유사한데, 요구하는 메소드를 반드시 구현해야 함. (클래스는 오버라이드하는 것이 선택) + +인터페이스에는 보통 메소드 몸통을 정의하지 않음 + +```java +interface Predator { + String getFood(); +} +``` + +인터페이스를 구현하는 클래스들이 정의함. 정의하지 않으면 컴파일 에러 + +`class` 키워드 자리에 `interface` 키워드를 사용 + +`extends` 키워드 자리에 `implements` 키워드를 사용 + +한 클래스는 하나의 클래스만 extend할 수 있는 반면, 여러 개의 인터페이스를 implement할 수 있음 + +인터페이스는 클래스처럼 자료형처럼 사용할 수 있음 + +```java +class ZooKeeper { + void feed(Tiger tiger) { + System.out.println("feed apple"); + } + + void feed(Lion lion) { + System.out.println("feed banana"); + } +} +``` + +```java +class ZooKeeper { + void feed(Predator predator) { + System.out.println("feed apple"); + } +} +``` + +## 디폴트 메소드 + +디폴트 메소드로 메소드 몸통을 구현한 인터페이스 메소드를 만들 수도 있음. 클래스의 인스턴스 메소드와 매우 유사 + +```java +interface Predator { + **default** void printFood() { + System.out.printf("my food is %s\n", getFood()); + } +} +``` + +## 스태틱 메소드 + +클래스의 스태틱 메소드와 매우 유사 + +```java +interface Predator { + int LEG_COUNT = 4; // 인터페이스 상수 + + static int speed() { + return LEG_COUNT * 30; + } +} +``` + +인터페이스 상수는 자동으로 `public static final`이 적용된다. + +```java +Predator.speed(); // 120 +Predator.LEG_COUNT; // 4 +``` \ No newline at end of file diff --git "a/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" "b/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" new file mode 100644 index 0000000..63d3d36 --- /dev/null +++ "b/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" @@ -0,0 +1,126 @@ +# Ch. 12 예외처리 + +자바에서는 예외처리와 관련해 `try... catch, finally, throw` 구문을 사용한다. + +# 예외는 언제 발생하는가 + +예외는 크게 프로그램 작성 순간에 예측가능한 예외인 Exception, 발생할 수 있고 안할 수도 있는 Runtime Exception으로 구분할 수 있다. + +이와 관련한 클래스로 Exception과 RuntimeException이 있다. 구분과 완전히 일치하지는 않는게 Exception은 모든 예외의 부모 클래스이며 RuntimeException도 Exception을 상속받는다. + +# 예외 처리하기 + +다음과 같이 생긴 try, catch문을 사용해 예외를 처리한다. + +```java +try { + ... +} catch(예외1) { + ... +} catch(예외2) { + ... +} +``` + +try 문 안에 예외가 발생할 수 있는 문장을 넣는다. + +try 문 안에서 예외가 발생하면 예외 종류에 해당하는 catch문이 수행된다. 여러 catch문에 해당되어도 가장 위에 것만 실행된다. 예외 발생 문장 뒤에 있는 문장들은 무시된다. + +try 문 안에서 예외가 발생하지 않으면 어떤 catch문도 수행되지 않는다. + +## 예시 + +```java +int c; +try { + c = 4 / 0; +} catch(ArithmeticException e) { + c = -1; // 예외가 발생하여 이 문장이 수행된다. +} +``` + +## finally + +예외 발생 여부와 상관없이 마지막에 반드시 실행되어야 하는 문장은 finally에 넣는다. + +# 예외 정의하고 발생시키기 + +```java +**class FoolException extends RuntimeException { +}** + +class FoolException extends RuntimeException { +} + +public class Sample { + public void sayNick(String nick) { + if("fool".equals(nick)) { + **throw new FoolException();** + } + System.out.println("당신의 별명은 "+nick+" 입니다."); + } + + public static void main(String[] args) { + Sample sample = new Sample(); + sample.sayNick("fool"); + sample.sayNick("genious"); + } +} +``` + +# 예외 던지기(미루기) + +```java +class FoolException extends Exception { +} +``` + +Runtime이 아닌 Exception을 정의했다. + +```java +public class Sample { + public void sayNick(String nick) { + try { + if("fool".equals(nick)) { + throw new FoolException(); + } + System.out.println("당신의 별명은 "+nick+" 입니다."); + }catch(FoolException e) { + System.err.println("FoolException이 발생했습니다."); + } + } + + public static void main(String[] args) { + Sample sample = new Sample(); + sample.sayNick("fool"); + sample.sayNick("genious"); + } +} +``` + +반드시 예외처리를 해야하기 때문에 해주었다. FoolException이 발생한 곳에서 예외처리를 하는 것이 아니라 sayNick을 호출한 곳에서 예외처리 하도록 예외처리를 던지는(미루는) 방법이 있다. + +```java +public class Sample { + public void sayNick(String nick) throws FoolException { + ~~try {~~ // try .. catch 문을 삭제할수 있다. + if("fool".equals(nick)) { + throw new FoolException(); + } + System.out.println("당신의 별명은 "+nick+" 입니다."); + }~~catch(FoolException e) { + System.err.println("FoolException이 발생했습니다."); + }~~ + } + + public static void main(String[] args) { + Sample sample = new Sample(); + **try { // 이제 sayNick을 호출하는 main에서 예외처리 해주어야 한다** + sample.sayNick("fool"); + sample.sayNick("genious"); + **} catch (FoolException e) { + System.err.println("FoolException이 발생했습니다."); + }** + } +} +``` \ No newline at end of file From 4e8c00b2c55ad70b3bd070276915639d3df861b4 Mon Sep 17 00:00:00 2001 From: MyungJune Shin <64180930+go-the-extra-mile@users.noreply.github.com> Date: Fri, 7 Jul 2023 11:07:08 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Ch=2012=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC.md=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...2 \354\230\210\354\231\270\354\262\230\353\246\254.md" | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git "a/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" "b/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" index 63d3d36..ad3667c 100644 --- "a/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" +++ "b/Ch 12 \354\230\210\354\231\270\354\262\230\353\246\254.md" @@ -103,14 +103,14 @@ public class Sample { ```java public class Sample { public void sayNick(String nick) throws FoolException { - ~~try {~~ // try .. catch 문을 삭제할수 있다. + ~try {~ // try .. catch 문을 삭제할수 있다. if("fool".equals(nick)) { throw new FoolException(); } System.out.println("당신의 별명은 "+nick+" 입니다."); - }~~catch(FoolException e) { + }~catch(FoolException e) { System.err.println("FoolException이 발생했습니다."); - }~~ + }~ } public static void main(String[] args) { @@ -123,4 +123,4 @@ public class Sample { }** } } -``` \ No newline at end of file +```