JAVA 기초문법(3)
👉 상속 inheritance
- 1) 클래스와 클래스 사이(1:1)의 부모자식 관계를 만듬.
- 2) 자바 다중상속 x
- 3) 상속은 부모의 변수, 메서드들을 물려받는것.
- 4) 상속시, 생성자와 초기화 블럭은 제외
- 5) 상속 키워드 : extends
- 6) 필요한 이유 : 코드 중복 제거 -> 클래스를 간격하게 구현,
유지보수가 편함, SW생성산 향상.
부모클래스 = super = parent = base
자식클래스 = sub child derived
class Object{} // 조상님 (자동으로 상속받는 *자바 기능들)
class Parent{} // 할아버지 할머니 : x
class Child extends Parent{} //아빠 엄마 : x, y
class Child2 exnteds Parent{} //삼촌?..남 : x, z
class GrandChild extends Child{} //아들 딸 : x,y ,a ,b
class Animal {
String name;
public void cry() {
System.out.println(name + " is crying.");
}
}
class Dog extends Animal {
Dog(String name) {
this.name = name;
}
public void swim() {
System.out.println(name + " is swimming!");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog("코코");
dog.cry();
dog.swim();
Animal dog2 = dog;
dog2.cry();
// dog2.swim(); // compile error
}
}
-7) Object 클래스 : 모든클래스의 조상
자바에서는 모든 클래스가 자동으로 Object 클래스를 상속받는다.
모든 클래스는 object 클래스의 맴버를 모두 사용할 수 있다.
object 클래스는 11개의 메서드만 가지고 있다.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/Object.html
👉 상속과 접근자
- 1) 부모 클래스의 private 맴버
(오직 부모안에서만 사용가능, 자식 클래스 포함해서 다른 모든 클래스에서 접근x)
- 2) 부모 클래스의 default 맴버
(같은 패키지라면 가능, 자식이라도 다른 패키지라면 접근 x)
- 3) 부모 클래스의 public 멤버
(모든 곳에서 접근 허용)
- 4) 부모 클래스의 protected 멤버
(같은 패키지의 속한 모든 클래스에서 접근 가능, 패키지 상관없이 자식이라면 어디서든 접근 가능)
👉 final
- 1) final 클래스 :
클래스 앞에 붙으면, 상속할 수 없다 (부모가 될 수 없다)
final class FinalClass{}
class A extends FinalClass{} X
- 2) final 매서드
메서드 앞에 붙으면, 오버라이딩 할 수 없음 선언함.
class Super {
final void test(){AAA}
class Sub extends Sup[ // test
@override
void test(){BBB---> x
- 3) final 변수 : 상수
변수 앞에 붙으면, 상수가 된다.
상수는 한번 초기화(값대입) 되면 값을 변경할 수 없다.
final int ROW = 10;
ROW = 20; ---> X 수정안됨!!!
final 키워드를 public static과 함께 선언하면
프로그램 전체에서 사용할 수 있는 상수가 된다.
ex) public static final double PI = 3.14.....;
👉 상속과 생성자
-1) 서브와 수퍼클래스의 생성자 호출 및 실행
서브클래스가 생성될때, 서브클래의 생성자와 수퍼클래스 생성자 둘다 생성
-> 생성자의 목적은 객체의 초기화, 완성된 객체를 만들기 위해서 둘다 필요.
생성자 실행 순서 : 수퍼 -> 서브
-2) 서브클래스에서 수퍼 클래스 생성자 선택
부모 클래스의 생성자가 여러개 있는 경우,
개발자가 부모생성자를 명시적으로 지정하지 않는 경우
컴파일러가 부모의 기본 생성자를 호출하도록 실행시킴.
#1. 부모클래스의 기본생성자가 자동으로 선택되는 경우
자식 클래스에서 부모 생성자를 명시적으로 부르지 않은 경우
이때, 부모에 기본 생성자가 없고, 매개변수있는 생성자만 명시되어있는 경우
에러발생
#2. 부모 생성자를 명시적으로 부르는 방법
super()를 이용하여 부모의 생성자를 명시적으로 선택해야함.
자식 생성자 안에서 super() 명령이 첫번째 명령이 되어야함
소괄호 안에 매게변수 넣어서 부모 생성자 선택가능
👉 접근제어자 (access modifier)
private : 같은 클래스 내에서만 접근이 가능.
default(nothing) : 같은 패키지 내에서만 접근이 가능.
protected : 같은 패키지 내에서, 그리고 다른 패키지의 자손클래스에서 접근이 가능.
public : 접근 제한이 전혀 없음.
👉 **오버라이드** override (**중요함 **)
-1) 상속관계에서 성립
-2) 재작성, 덮어씌우기, 재정의 한다~~
: 부모로부터 물려받은 메서드의 기능이 마음에 안들어
내용물만 변경해서 사용하는 것.
-3) 메서드 선언부는 똑같이, 중괄호 영역 안의 내용물만 바꾸는 것.
void int ~~~~(){
-4) 오버로딩과는 완전히 다름
# 오버로딩 : 기존에 없는 새로운 메소드를 정의하는 것
int add(int x, int y, int z) {
int result = x + y + z;
return result;
}
long add(int a, int b, long c) {
long result = a + b + c;
return result;
}
int add(int a, int b) {
int result = a + b;
return result;
}
# 오버라이딩: 상속받은 메소드의 내용을 변경하는 것
class Animal {
String name;
String color;
public void cry() {
System.out.println(name + " is crying.");
}
}
class Dog extends Animal {
Dog(String name) {
this.name = name;
}
public void cry() {
System.out.println(name + " is barking!");
}
}
public class Main {
public static void main(String[] args) {
Animal dog = new Dog("코코");
dog.cry();
}
}
(Object 클래스로부터 물려받은 equals(), toString() 같은 메서드는 실제로
오버라이딩해서 주로 사용함)
-5) 동적바인딩 : 자식 클래스에 오버라딩된 메서드가 있으면,
부모가 만든 형태는 무시하고, 자식이 오버라이딩한 메서드가 무조건 실행된다.
-6) @Override : 어노테이션(annotation)이라 부르며,
메서드 바로 위에 붙혀서 컴파일러에게
오버라이딩이 정확한지 확인하도록 지시하는 것.
가독성 Up/ 개발자가 실수로 잘못작성하거나 오타를 방지할 수 있다.
-7) 부모메서드의 접근 지정자보다 접근의 범위를 좁혀서 오버라이딩 불가
public > protected > default > private
부모 protected -> 자식 오버라이딩 protected / public
부모 public -> 자식 오버라이딩 public
-8) super : = 부모클래스. 부모 클래스의 레퍼런스를 가르킴.
자식클래스에서 메서드 오버라이딩시,
동적바인딩으로 오버라이딩된 메서드가 무조건 실행되는데,
부모의 맴버를 호출하고자 할때 사용하는 키워드
#this. super. this(). super()
this : 현재 객체 (내가 가진~)
super : 부모 객체
this() : 보무 생성자에서 내 클래스의 다른 생성자 호출
super() : 자식 생성자에서 부모 생성자 호출
👉 **** 다형성 **** polymorphism [****자바의 화룡점정****]
여러가지 형태를 가질 수 있는 능력
상속관계에서 성립가능!
참조형의 형변환
👉 instanceof 연산자
참조하는 변수가 다르키는 실제 객체의 타입을 체크하는데 사용
참조변수 instanceof 클래스명 ---> true/ false 로 결과 돌려줌
👉 instanceof 추상클래스
-1) 설계와 구현을 분리한다면, 설계부분에 해당
-2) 키워드 : abstract
-3) 추상메서드 : abstract 키워드를 붙혀 메서드의 선언분(원형)만 있고
구현은 되어있지 않은 형태 (중괄호 부분 없음)
public String getNAme(){} 이지만
->로 표현 public abstract String getName();
-4) 추상클래스 : 일반 맴버 (변수, 메서드)들과 함께 추상 메서드를 포함하는 클래스
추상 메서드가 하나라도 있으면 무조건 추상 클래스
추상 클래스가에는 abstract 키워드를 붙혀야 한다.
abstract class Sharpe{ // 추상클래스
int a ;
abstract void draw(); //추상 메서드
}
-5) 추상 클래스로는 객체 생성 불가!! 불완전한 / 미완성인 클래스이므로 메모리에 올릴 수 없다
Shape s = new Shape (); -----> (X)
Shape s; ----> (O) 변수 선언만은 괜찮다.
-6) 상속에서 수퍼클래스로 사용된다. 부모 클래스 될 수 있음. extends 키워드로 상속시킬수 있다.
-7) 추상클래스를 물려받은 자식클래스를 완성시키려면 추상메서드를 오버라이딩(내용물 구현)해야한다.
추상클래스를 단순히 상속만 받은 자식클래스는 그 또한 추상클래스가 된다.
# 추상 클래스 단순 상속 : 상속받은 추상 메서드 구현 안하면,
abstract class Rect extends Shape {
int width
}
# 추상 클래스를 상속 + 구현
class Rect extends Shape {
int width;
@override
void draw(){....
}
}
8) 추상클래스를 상속받은 자식클래스는 개발자들이 추상메서드를 모두 구현해야함.
-> 추상 클래스를 가이드라인,
자식 클래스는 가이드를 따른 구현된 사용가능한 실제 클래스
abstract class Bird {
private int x, y, z;
void fly(int x, int y, int z) {
printLocation();
System.out.println("이동합니다.");
this.x = x;
this.y = y;
if (flyable(z)) {
this.z = z;
} else {
System.out.println("그 높이로는 날 수 없습니다");
}
printLocation();
}
abstract boolean flyable(int z);
public void printLocation() {
System.out.println("현재 위치 (" + x + ", " + y + ", " + z + ")");
}
}
class Pigeon extends Bird {
@Override
boolean flyable(int z) {
return z < 10000;
}
}
class Peacock extends Bird {
@Override
boolean flyable(int z) {
return false;
}
}
public class Main {
public static void main(String[] args) {
Bird pigeon = new Pigeon();
Bird peacock = new Peacock();
System.out.println("-- 비둘기 --");
pigeon.fly(1, 1, 3);
System.out.println("-- 공작새 --");
peacock.fly(1, 1, 3);
System.out.println("-- 비둘기 --");
pigeon.fly(3, 3, 30000);
}
}
👉 인터페이스 interface : 규격 / 골격제작
-1) 키워드 : interface //클래스 대신 사용
키워드 사용해서 클래스를 선언하듯이 인터페이스를 선언
-2) 인터페이스 멤버는 추상메서드와 상수만으로 구성된다.
interface Phone {
public static final 타입 변수명; //상수
public abstract 리턴타입 메서드명(); //추상 메서드
}
interface Phone {
public static final int BUTTONS = 20; int BUTTONS = 20;
public abstract void sendCall(); void senCall();
public abstrcat void receiveCall(); receiveCall();
}
* 인터페이스 멤버는 어디서라도 접근 가능하게 모두 public으로 만듬
-3) 모든 메서드는 public abstract 이며 생략 가능하다.
-4) 상수는 public static final 타입이며 생략 가능하다.
-5) 인터페이스는 객체 생성 불가!
메서드는 모두 구현안된 추상메서드이므로 미완성/불완전해 객체 생성 불가능
Phone p = new Phone(); ----> X
-6) 인터페이스 타입의 변수 선안만은 가능
Phone p; ---> O
-7) 인터페이스 상속
인터페이스는 다른 인터페이스를 상속 받을 수 있다.
인터페이스는 규격과 같은 것으로, 상속을 통해
기존 인터페이스에 새로운 규격을 추가한 새로운 인터페이스를 만들 수 있다.
extends 키워드 사용
interface Mobile extends Phone {
void sendSMS(); // 상수, 추상메서드
void receiveSMS(); 규격추가
}
### 인터페이스는 다중 상속 허용 ### (구현이 안되니 충돌날일이 없으니깐)
interface DualcameraPhone extends Mobile, Camera {
void makeVideo();
}
-8) 인터페이스 구현
인터페이스의 추상 메서드를 모두 구현한 클래스를 작성하는 것
키워드 : implements
class Iphone Implementes Mobile{
// 추상메서드 모두 구현
public void senCall(){.....}
public void receiveCall(){.....}
public void sendSMS(){...}
public voiud receiveSMS(){...}
//추가적으로 일반 메서드 , 변수선언
public int doubleFingerTouch(){...}
}
* 추상메서드중 하나라도 구현안하면 에러!!
키워드 implements는 객체생성가능
Mobile m = new Iphone();
-9) 인터페이스의 목적
-10) 인터페이스의 다중 구현
클래스는 하나 이상의 인터페이스 구현 가능.,
class Iphone Implementes Mobile, Camera,
interface Bird {
void fly(int x, int y, int z);
}
class Pigeon implements Bird{
private int x,y,z;
@Override
public void fly(int x, int y, int z) {
printLocation();
System.out.println("날아갑니다.");
this.x = x;
this.y = y;
this.z = z;
printLocation();
}
public void printLocation() {
System.out.println("현재 위치 (" + x + ", " + y + ", " + z + ")");
}
}
public class Main {
public static void main(String[] args) {
Bird bird = new Pigeon();
bird.fly(1, 2, 3);
// bird.printLocation(); // compile error
}
}
👉 예외 처리 Exception handling
: 코드로 발생할수있는 에러를 미리 진단하고, 해결방안을 처리해 놓는것.
- 컴파일 에러 : 컴파일할때 발생(실행조차X) : 문법 오류 등
- 런터임 에러 : 실행하다 발생 : 문법적으로는 맞아 컴파일은 되는데 실행하다 발생
-1) 예외는 메서드에서 처리.
-2) try-catch 구문 (****api쓰면서 정말 많이 쓸꺼다*****)
try {
// 예외가 발생할 가능성이 있는 코드를 구현.
} catch (FileNotFoundException e) {
// FileNotFoundException이 발생했을 경우,이를 처리하기 위한 코드를 구현.
} catch (IOException e) {
// FileNotFoundException이 아닌 IOException이 발생했을 경우,이를 처리하기 위한 코드를 구현.
} finally {
// 예외의 발생여부에 관계없이 항상 수행되어야하는 코드를 구현 (필수는 아님)
// 메서드안에서 return을 만나도 finally 블럭이 있으면 실행하고 return됨.
}
-3) 대표적인 예외
ArrayIndexOutOfBoundsException : 배열 인덱스번호 잘못 쓰면
ArithmeticException : 0으로 나눌려고 할때
NullPointerException : 객체 생성안하고 내용물 사용하려고 할때
NumberFormatException : 문자열이 나타내는 숫자와 일치하지 않는 타입의 숫자로 변환시 발생
ClassCastException : 클래스 형변환 에러
ClassNotFoundException : 찾는 클래스가 없을 경우
IOException : 입출력 동작 실패 또는 인터럽트 시 발생
IllegarArgumentException : 인자 전달 실패시
-4) 예외 발생시키는 키워드
throw 예외객체;
Exception e = new Exception();
throw e; // 예외 발생이야~~~~~~~~
🙋♂️ 소감 :
알고리즘 듣다가 자바 기초문법 보니까 그나마 숨통이 트인다...😮💨
시스템 처리에 있어 예외처리가 정말 중요한 작업이라고 들었다.
신뢰를 줄 수 있는 개발자가 되기 위해 예외처리를 이해하고 효율적으로
적용할 수 있는 능력을 갖추기 위해 노력해야겠다.
😈 아는 내용이라고 그냥 넘어가지 않기! 😈
'❤️🔥TIL (Today I Learned)' 카테고리의 다른 글
[TIL] 2022-11-16(13day) (0) | 2022.11.16 |
---|---|
[TIL] 2022-11-15(12day) (0) | 2022.11.15 |
[TIL] 2022-11-11(10day) (0) | 2022.11.11 |
[TIL] 2022-11-10(9day) (1) | 2022.11.10 |
[TIL] 2022-11-09(8day) (0) | 2022.11.09 |
댓글