일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- etf
- FCF
- 다형성
- 무디스
- 그리디 알고리즘
- 배당성장
- 현금흐름표
- 접근제어자
- 금리인하
- 객체지향
- 인플레이션
- 미국주식
- javascript
- 주식
- 금리인상
- 제태크
- 백준
- mco
- 프로그래머스
- 자바
- 오버라이딩
- Java
- 주린이
- 기업분석
- S&P500
- XLF
- 잉여현금흐름
- StringBuffer
- object
- 알고리즘
- Today
- Total
오늘의하루
[Java Note] 객체지향 개념 기초 요약본 본문
객체지향
객체지향은 코드의 재사용성을 높이고 관리를 수월하게 해서 신뢰성 높은 프로그램의 개발이 가능하다.
객체지향 - 클래스, 객체
클래스란 객체를 정의해 놓은 것이며 객체는 실제로 존재하는 개념이다.
객체와 인스턴스
객체(Object)는 인스턴스(Instance)를 포함하는 일반적인 의미이다.
인스턴스화(Instantiate)
클래스로부터 인스턴스를 생성하는 것을 말한다.
클래스명 참조 변수명; // 객체를 다루기 위한 참조 변수 선언
클래스명 참조 변수명 = new 클래스명( ); // 객체 생성 후 해당 객체의 주소를 참조 변수에 저장
하나의 인스턴스 주소를 여러 개의 참조 변수들이 가지는 것은 가능
여러 개의 인스턴스 주소를 하나의 참조 변수가 가지는 것은 불가능
객체의 구성요소 - 속성과 기능
객체는 변수(속성)와 메서드(기능)로 이루어져 있습니다.
객체지향 - 변수와 메서드
변수는 선언 위치에 따라 종류와 범위(Scope)를 결정한다.
class Test {
클래스 영역 시작
int iv; = 인스턴스 변수
static int cv; = 클래스 변수(static 변수, 공유 변수)
메서드 영역 시작
void method(){
int lv; = 지역 변수
}
메서드 영역 종료
클래스 영역 종료
}
변수의 종류 | 선언 위치 | 생성시기 |
클래스 변수 | 클래스 영역 | 클래스가 메모리에 올라갈때 |
인스턴스 변수 | 인스턴스 생성시 | |
지역 변수 | 메서드 영역 | 메서드 호출 후 변수 선언문 수행시 |
변수들의 특징
변수의 종류 | 특징 |
인스턴스 변수 | 인스턴스 생성 후 "참조변수.인스턴스변수명"으로 접근 참조변수가 없으면 GC(가비지 컬렉터)에 의해 소멸된다. |
클래스 변수 | 인스턴스 생성 없이 "클래스명.클래스변수명"으로 접근 클래스 로딩시 생성되며 프로그램 종료 시 소멸된다. |
지역 변수 | 메서드 호출 시 생성되며 메서드 종료시 소멸된다. |
메서드(Method)
작업을 수행하기 위한 명령문의 집합을 의미하며 클래스 영역에서만 정의할 수 있고 선언부와 구현부로 나뉩니다.
리턴 타입 메서드명 ( 타입 변수명.... ) = 선언부
{ 구현부 }
JVM의 메모리 구조
명칭 | 특징 |
Method Area (메서드 영역) | 클래스 정보와 클래스 멤버가 저장되는 공간 |
Call Stack (호출 스택) | 메서드의 작업공간 메서드가 호출되면 메모리 공간을 할당 받고 메서드 종료되면 사용하던 메모리 공간 소멸 |
Heap (힙) | 인스턴스가 생성되는 공간 new 연산자에 의해서 생성되는 배열과 객체는 모두 여기에 생성 |
Call Stack - 호출 스택
메서드가 호출되면 수행에 필요한 메모리를 스택에 할당되며 수행을 마치면 메모리를 반환한다.
Call Stack 이해하기
아래 있는 메서드가 바로 위에 있는 메서드를 호출한 메서드이며 호출 스택의 제일
- 가장 처음 main 메서드가 실행된다.
- main 메서드 안에서 FirstMethod가 호출되면 위에 쌓인다.
- FristMethod가 종료되면 Call Stack에서 소멸된다.
기본형, 참조형 매개변수
종류 | 특징 |
기본형 매개변수 | 변수의 값을 읽기만 가능하다. (Read Only) 종류 : boolean, char, byte, short, int, float, long, double |
참조형 매개변수 | 변수의 값을 읽고 변경할 수 있다. (Read & Write) 종류 : 기본형 매개변수 외에 모든 것 |
클래스 메서드와 인스턴스 메서드
인스턴스 메서드(Instance Method)
- 인스턴스 생성 후 " 참조 변수명. 메서드명() "으로 호출할 수 있다.
- 메서드 내에서 인스턴스 변수를 사용할 수 있다.
- 메서드 내에서 클래스 메서드를 사용할 수 있다.
클래스 메서드(static Method)
- 인스턴스 생성 없이 " 클래스명. 메서드명() "으로 호출할 수 있다.
- 메서드 내에서 인스턴스 멤버를 사용할 수 없다.
class Test{
long a, b;
long add() {return a+b;} // 인스턴스 메서드
static long add(long a, long b) {return a+b;} // 클래스 메서드
}
System.out.println(Test.add(20L,10L)); // 30L 클래스 메서드 호출
Test t = new Test(); // 인스턴스 생성
t.a = 20L;
t.b = 10L;
System.out.println(t.add()); // 30L 인스턴스 메서드 호출
메서드 오버 로딩(Method Overloading)
하나의 클래스에 같은 이름의 메서드를 여러 개 정의하는 것을 의미합니다.
- 기존에 없는 새로운 메서드를 정의하는 것
오버 로딩의 조건
- 메서드 이름이 같아야 한다.
- 매개변수의 개수 또는 타입이 달라야 한다.
- 매개변수는 같고 리턴 타입이 다른 경우는 성립되지 않는다.
생성자(constructor)
- 모든 클래스에는 반드시 하나 이상의 생성자가 있어야 한다!
인스턴스가 생성될 때마다 호출되는 인스턴스 초기화 메서드를 의미합니다.
Test t = new Test();
- new 연산자에 의해서 메모리(heap)에 Test 클래스의 인스턴스가 생성된다.
- 생성자 Test()가 호출되어 수행된다.
- new 연산자의 결과로 생성된 Test 인스턴스의 주소가 참조 변수 t에 저장된다.
생성자의 조건
- 생성자의 이름은 클래스의 이름과 같아야 한다.
- 생성자는 리턴 값이 없다.
기본 생성자(default constructor)
매개변수가 없는 생성자를 말하며, 만약 클래스에 생성자가 하나도 없다면 컴파일러가 기본 생성자를 추가한다.
class Test1{
int value;
// Test1(){} -> 컴파일러가 생성자가 없기 때문에 추가해준다.
}
class Test2{
int value;
Test2(int x){ // 매개변수가 있는 생성자
value = x;
}
}
Test1 t1 = new Test1(); // OK
// Test1() 생성자를 호출한다.
Test t2 = new Test2(); // Error!
// Test2() 생성자를 호출하는데 Test2 클래스에는 Test2() 생성자가 없다.
Test t2 = new Test2(10); // OK
다른 생성자 호출하는 this( )
같은 클래스의 다른 생성자를 호출할 때 사용하며 다른 생성자 호출은 생성자의 첫 문장에서만 가능하다.
class Test{
String color;
int door;
Test(){
this("Red", 4);
// Test("Red", 4); 와 같다.
}
Test(String c, int d){
color = c;
door = d;
}
}
참조 변수 this
인스턴스 자신을 가리키는 참조 변수이며 인스턴스 주소가 저장되어있다.
class Test{
String color;
int door;
Test(String color, int door){
this.color = color;
this.door = door;
// 인스턴스 변수와 지역 변수를 구별하기 위해 참조변수 this를 사용
}
}
변수의 초기화
변수를 선언하고 처음으로 값을 저장하는 것을 말한다.
- 지역 변수의 경우는 사용 전에 꼭 초기화를 해주어야 한다.
자료형 | 기본값 | 자료형 | 기본값 |
boolean | false | int | 0 |
char | '\u0000' | long | 0L |
byte | 0 | float | 0.0f |
short | 0 | double | 0.0 |
참조형 변수 | null |
멤버 변수의 초기화
1. 명시적 초기화 (explicit initialization)
class Test{
int door = 4; // 기본형 변수의 초기화
Engine e = new Engine(); // 참조형 변수의 초기화
}
2. 생성자 (constructor)
Test(String color, int door){
this.color = color;
this.door = door;
}
3. 초기화 블록 (initialization block)
{} // 인스턴스 초기화 블록 (생성자 보다 먼저 실행된다.)
static {} // 클래스 초기화 블록 (클래스가 로딩될 때 실행된다.)
멤버 변수의 초기화 시기와 순서
class InitTest{
static int cv = 1;
int iv = 2;
static { cv = 3; }
{ iv = 4; }
InitTest(){ iv = 5; }
}
- 클래스 변수 cv 기본값 0
- 클래스 변수 cv 명시적 초기화 1
- 클래스 변수 cv 초기화 블록 3
- 인스턴스 변수 iv 기본값 0
- 인스턴스 변수 iv 명시적 초기화 2
- 인스턴스 변수 iv 초기화 블록 4
- 인스턴스 변수 iv 생성자 5
상속 (inheritance)
- Java에서는 단일 상속만을 허용한다!
기존의 클래스를 재사용해서 새로운 클래스를 작성하는 것이며 두 클래스는 부모와 자식으로 관계를 맺게 된다.
- 자식 클래스는 부모 클래스의 모든 멤버를 상속받는다.
- 단, 생성자와 초기화 블록은 상속되지 않는다.
클래스 간의 상속 관계
상속은 " extends "로 만들 수 있으며 부모 클래스의 변경은 자식 클래스에게 영향을 미치지만 자식 클래스의 변경은 부모 클래스에게 아무런 영향을 미치지 못합니다.
class Parent{}
class Child1 extends Parent{}
class Child2 extends Parent{}
상속 관계 | " ~은 ~이다 " (is ~a) |
포함(composite)
한 클래스의 멤버 변수로 다른 클래스를 선언하는 것이다.
class Point{
int x;
int y;
}
class Circle{
Point p = new Point(); // 포함 관계
int r;
}
포함 관계 | " ~은 ~을 가지고 있다. " (has ~a) |
Object 클래스
조상이 없는 클래스는 자동적으로 Object 클래스를 상속받게 된다.
- Object 클래스는 11개의 메서드를 상속한다.
- toString(), equals(Object obj), hashCode() 등등
오버 라이딩(overriding)
부모 클래스로부터 상속받은 메서드의 내용을 상속받는 클래스에 맞게 변경하는 것을 오버 라이딩이라고 한다.
- 상속받은 메서드의 내용을 변경하는 것
class Point{
int x;
int y;
String getLocation(){
return "x = " + x + "y = " + y;
}
}
class Point3D extends Point{
int z;
String getLocation(){ // 오버라이딩
return "x = " + x + "y = " + y + "z = " + z;
}
}
오버 라이딩의 조건
- 선언부(메서드명, 매개변수, 리턴 타입)가 같아야 한다.
- 접근제어자를 좁은 범위로 변경할 수 없다.
- 범위 순서 : public > protected > default > private
- 부모 클래스의 메서드보다 많은 수의 예외를 선언할 수 없다.
class Parent{
default void parentMethod() throws IOException, SQLException{/* ... */}
}
class Child extends Parent{
private void parentMethod() throws IOException{/* ... */}
// Error! 접근제어자는 좁은범위로 변경 불가능
public void parentMethod() throws Exception{/* ... */} // OK
}
참조 변수 super
참조 변수 super는 부모의 멤버와 자신의 멤버를 구별하는 데 사용된다.
부모의 변수를 참조
class Parent{
int x = 10;
}
class Child extends Parent{
int x = 20;
void method(){
System.out.println("x = " + x); // 20 (가까운 x -> Child 클래스에 x가 없다면 부모의 x를 가리킨다.)
System.out.println("this.x = " + this.x); // 20 (자신의 x)
System.out.println("super.x = " + super.x); // 10 (부모의 x)
}
}
부모의 메서드를 참조
class Point{
int x;
int y;
String getLocation(){
return "x : " + x + ", y : " + y;
}
}
class Point3D extends Point{
int z;
String getLocation(){
return super.getLocation() + ", z : " + z; // 부모 메서드 호출
}
}
class Point3D extends Point{
int z;
String getLocation(){ // 오버라이딩
return "x : " + x + ", y : " + y + ", z : " + z;
}
}
부모의 생성자 super( )
부모의 멤버들을 초기화해야 하기 때문에 자식의 생성자의 첫 문장에서는 부모의 생성자를 호출해야 한다.
- Object클래스를 제외한 모든 클래스의 생성자 첫 줄에는 (1) 생성자를 호출해야 한다.
- (1) : 같은 클래스의 다른 생성자 또는 부모의 생성자
- 생성자를 호출하지 않으면 컴파일러가 자동적으로 " super( ); "를 생성자의 첫 줄에 삽입한다.
class Point{
int x;
int y;
Point(){this(0,0);}
Point(int x, int y){
// super(); 컴파일러가 자동 삽입한다.
this.x = x;
this.y = y;
}
}
상속에서 super( ) 사용
class Parent{
int x;
Parent(int x){
//super();
this.x = x;
}
}
class Child extends Parent{
int y;
Child(int x, int y){
super(x);
//super(); // Error! 부모의 생성자에 기본 생성자가 없다!
this.y = y;
}
}
제어자(modifiers)
제어자는 크게 접근 제어자와 그 외 제어자로 나뉜다.
구분 | 종류 |
접근 제어자 | public, protected, default, private |
그 외 제어자 | static, final, abstract, native, transient, synchronized, volatile, strictfp |
그 외 제어자 알아보기
static(공통적인)
static이 사용될 수 있는 곳은 멤버 변수, 메서드, 초기화 블록이다.
class StaticTest{
static int width = 100;
staitc int height = 200;
static{}
static int max(int a, int b){return a > b ? a : b;}
}
final(마지막의)
final이 사용될 수 있는 곳은 클래스, 메서드, 멤버 변수, 지역변수이다.
final class FinalTest{
final int MAX_SIZE = 10;
final void getMaxSize(){
final LV = MAX_SIZE;
return MAX_SIZE;
}
}
구분 | 의미 |
클래스 | 부모가 될 수 없는 클래스 |
메서드 | 오버라이딩을 할 수 없는 메서드 ( 오버로딩과 상관 없음 ) |
멤버변수 | 값을 변경할 수 없는 상수 ※ 상수는 선언과 초기화를 동시에 하는게 좋다. |
지역변수 |
abstract(추상의)
abstract가 사용될 수 있는 곳은 클래스, 메서드이다.
abstract class AbstractTest{
abstract void move();
}
구분 | 의미 |
클래스 | 클래스 내부에 추상 메서드가 있다는 의미 |
메서드 | 선언부만 있고 구현부가 없는 미완성된 메서드 |
접근 제어자 알아보기
멤버 또는 클래스에 사용되며 외부로부터의 접근을 제한하는 역할을 합니다.
구분 | 특징 |
public | 접근 제한이 없다. (사용가능한 곳 : 클래스, 멤버) |
protected | 같은 패키지, 다른 패키지의 자식 클래스에서 접근 가능 (사용가능한 곳 : 멤버) |
default (생략 가능) | 같은 패키지에서만 접근 가능 (사용가능한 곳 : 클래스, 멤버) |
private | 같은 클래스에서만 접근 가능 (사용가능한 곳 : 멤버) |
// 캡슐화
class Time{
private int hour; // 외부에서 직접 접근하는것이 불가능하다.
Time(int hour){
setHour(hour); // 메서드를 통해서 초기화 된다.
}
public int setHour(int hour){
if(hour < 0 || hour > 23){
return;
}
this. hour = hour;
}
public int getHour(){ // 메서드를 통해 값을 불러온다.
return hour;
}
}
Time t = new Time(12);
t.get(); // 12
생성자의 접근 제어자
일반적으로 생성자의 접근 제어자는 클래스의 접근 제어자와 일치하며 생성자에 접근 제어자를 사용함으로써 인스턴스 생성을 제한할 수 있다.
class Test{
private int x;
private static Test t = null;
private Test(int x){this.x = x;}
public static Test getInstance(int a){
if(t == null){
t = new Test(a);
}
return t;
}
public int getX(){
return this.x;
}
}
Test t = Test.getInstance(1);
System.out.println(t.getX()); // 1
다형성(Polymorphism)
부모의 참조 변수로 자식 타입의 객체를 다룰 수 있는 것을 다형성이라고 부른다.
- 반대로 자식의 참조 변수는 부모의 객체를 다룰 수 없다!
class Tv{
int channel;
Tv(int x){
channel = x;
}
void channelUp(){++channel;}
}
class SmartTv extends Tv{
String Text;
SmartTv(int x, String str){
super(x);
Text = str;
}
void caption(){
System.out.println(Text);
}
}
Tv t = new SmartTv(1, "wow");
t.channelUp(); // OK 2
t.caption(); // Error! Tv타입의 참조변수 t에는 caption이 없다.
참조 변수의 형 변환
서로 상속관계에 있는 타입 간의 형 변환만 가능하다.
class Car{
String color;
void drive(){System.out.println("rrrrr~");}
}
class FireEngine extends Car{
void water(){System.out.println("water!!");}
}
class Ambulance extends Car{
void siren(){System.out.println("siren!!");}
}
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = new FireEngine();
fe.water(); // water!!
car = fe; // Car car = (Car)fe;
car.water(); // Error!! Car타입에는 water메서드가 없다.
fe2 = (FireEngine)car; // FireEngine fe2 = (FireEngine)car;
fe2.water(); // water!!
부모 타입의 참조 변수에서 자식 타입의 참조 변수로 형 변환을 할 때는 (자식 타입)을 생략할 수 없으며 자식 타입의 참조 변수에서 부모 타입의 참조 변수로 형 변환할 때는 (부모 타입)을 생략할 수 있다.
구분 | 특징 |
자식 타입에서 부모 타입으로 | 형변환 생략가능 |
부모 타입에서 자식 타입으로 | 형변환 생략불가 |
instanceof 연산자
참조 변수 형 변환을 하기 전에 형 변환이 가능한지 확인하는 연산자이다.
- 참조 변수가 참조하는 인스턴스의 실제 타입을 체크한다.
class Car{}
class FireEngine extends Car{}
FireEngine fe = new FireEngine();
Car c = new FireEngine(); // 다형성
if (fe instanceof FireEngine){ // True
System.out.println("this is a fireEngine instance");
}
if (fe instanceof Car){ // True
System.out.println("this is a car instance");
}
if (fe instanceof Object){ // True
System.out.println("this is a Object instance");
}
System.out.println(c instanceof FireEngine); // true
A instanceof B = A 인스턴스의 실제 타입이 B의 자식 타입이면 true를 반환하고 아니라면 에러가 발생한다.
참조 변수와 인스턴스 변수의 연결
구분 | 특징 |
멤버 변수 중복 | 참조 변수 타입에 따라 멤버 변수가 달라진다. |
메서드 중복 | 참조 변수 타입과 상관없이 실제 인스턴스의 타입에 메서드가 호출된다. |
class Parent{
int x = 100;
void method(){ System.out.println("Parent Method"); }
}
class Child{
int x = 200;
void method(){ System.out.println("Child Method"); }
}
Parent p = new Child(); // 다형성
Child c = new Child();
System.out.println("p.x = " + p.x); // 100
System.out.println("c.x = " + c.x); // 200
p.method(); // Child Method
c.method(); // Child Method
매개변수의 다형성
참조형 매개변수는 메서드 호출 시 자신과 같은 타입 또는 자식 타입의 인스턴스를 넘겨줄 수 있다.
class Product{
int price;
}
class Tv extends Product{}
class Audio extends Product{}
// 매개변수 다형성 사용하지 않았을 경우
class Buyer{
int money = 100;
void Buy(Tv t){
this.money = this.money - t.price;
}
void Buy(Audio a){ // 오버로딩
this.money = this.money - a.price;
}
}
// 매개변수 다형성 사용하는 경우
class Buyer{
int money = 100;
void Buy(Product p){
this.money = this.money - p.price;
}
}
Buyer b = new Buyer();
Tv t = new Tv();
Audio a = new Audio();
b.buy(t); // Product p = (Product)t 참조변수 형변환
b.buy(a); // Product p = (Product)a 참조변수 형변환
여러 종류의 객체를 하나의 배열로 다루기
부모 타입의 배열에 자식 타입의 객체들을 담을 수 있다.
class Product{}
class Tv extends Product{}
class Audio extends Product{}
class Computer extends Product{}
Product[] p = new Product[3];
p[0] = new Tv(); // Product p = new Tv(); 다형성
p[1] = new Audio(); // Product p = new Audio(); 다형성
p[2] = new Computer(); // Product p = new Computer(); 다형성
추상 클래스 (abstract class)
클래스 내부에 추상 메서드를 가진 클래스를 의미하며 미완성된 클래스이기 때문에 인스턴스를 생성할 수 없다.
- 추상 클래스를 상속받는 자식 클래스에서는 모든 추상 메서드의 구현부를 완성해서 사용한다.
abstract class Player{
int currentPos;
Player(){ // 추상 클래스에도 생성자가 있어야 한다.
currentPos = 0;
}
abstract void play(int pos); // 추상 메서드
void stop(){
play(currentPos); // 일반 메서드에서 추상 메서드를 사용할 수 있다.
}
}
추상 클래스를 사용하는 이유
여러 클래스에 공통적으로 사용되는 메서드명이지만 각기 다른 구현부를 가질 때 그 부분을 뽑아서 만든다.
class Marine{
int x, y;
void move(int x, int y){System.out.println("Marine move = " + x + ", " + y);}
}
class Tank{
int x, y;
void move(int x, int y){System.out.println("Tank move = " + x + ", " + y);}
}
// 추상 클래스를 만들어서 사용
abstract class Unit{
int x, y;
abstract void move(int x, int y); // 추상 메서드
}
class Marine extends Unit{
void move(int x, int y){System.out.println("Marine move = " + x + ", " + y);}
}
class Tank extneds Unit{
void move(int x, int y){System.out.println("Tank move = " + x + ", " + y);}
}
Unit[] group new Unit[2];
group[0] = new Marine();
group[1] = new Tank();
for(int i = 0; i < group.length; i++){
group[i].move(100,200);
}
// Marine move = 100, 200
// Tank move = 100, 200
인터페이스 (interface)
실제 구현된 것이 없는 기본 설계도이며 추상 메서드와 상수, 디폴트 메서드만을 멤버로 가질 수 있다.
- 인스턴스를 생성할 수 없으며 표준을 제시하는 데 사용된다.
interface interfaceName{
public static final int NUM = 1; // 상수
public abstract void method(); // 추상 메서드
default void Hello(){System.out.println("Hello Im default Method~");};
}
// interface는 implements로 받을 수 있으면 이는 " 구현 "이라고 부른다.
class Car inplements interfaceName{
void method(){System.out.println("추상 메서드 구현부 완성");}
}
// 인터페이스에 있는 추상 메서드를 모두 구현하지 않으면 추상 클래스가 된다.
class Child extends Parent implements Interface{} // 상속과 구현을 동시에 할 수 있다.
구분 | interface의 특징 |
멤버 변수 | 모든 멤버 변수가 public static final이기 때문에 생략 가능 |
추상 메서드 | 모든 추상 메서드가 public abstract이기 때문에 생략가능 |
인터페이스의 상속
인터페이스는 메서드가 선언 부만 있기 때문에 클래스와 다르게 다중 상속이 가능하다.
interface A{
void move();
}
interface B{
void attack();
}
interface C extends A, B{}
인터페이스를 이용한 다형성
인터페이스 타입의 변수로 인터페이스를 구현한 클래스의 인스턴스를 참조할 수 있다.
class Fighter extends Unit implements Fightable{
public void move(int x, int y){System.out.println("Move = " + x + ", " + y);}
public void attack(Fightable f){/* 내용생략 */}
// 매개변수로 인터페이스를 지정할 수 있다.
// Fightable을 구현한 클래스만 들어오게 된다.
// 인터페이스를 메서드의 리턴타입으로 지정할 수 있다.
Fightable method(){ // Fightable 인스턴스를 구현한 클래스의 인스턴스를 반환한다.
return new Fighter();
}
}
Fighter f = new Fighter();
Fightable f2 = new Fighter();
디폴트 메서드
JDK 1.8 이후 인터페이스에서 디폴트 메서드(일반 메서드), static 메서드를 사용할 수 있게 되었다.
- 디폴트 메서드가 기존의 메서드와 충돌하는 경우 아래와 같이 해결된다.
- 여러 인터페이스의 디폴트 메서드 간의 충돌
- 인터페이스를 구현한 클래스에서 디폴트 메서드를 오버 라이딩해야 한다.
- 디폴트 메서드와 부모 클래스의 메서드 간의 충돌
- 부모 클래스의 메서드가 상속되고 디폴트 메서드는 무시된다.
- 여러 인터페이스의 디폴트 메서드 간의 충돌
interface Test{
void method();
default void get(){System.out.println("interface");}
}
class Parent{
public void get(){System.out.println("Parent");}
}
class Child extends Parent implements Test{
public void method(){System.out.println("hi");}
}
Child c = new Child();
c.get(); // Parent
'JAVA' 카테고리의 다른 글
[Java] Enum (열거형), Annotation (애너테이션) (0) | 2022.08.31 |
---|---|
[Java] 비트 연산자(AND)로 홀수 짝수 구분하기 (0) | 2022.08.30 |
[Java] 제네릭(Generics) 정의 선언 사용 제한 메서드 형변환 (0) | 2022.08.26 |
[Java]제한된 Generic 클래스 (0) | 2022.08.25 |
Java로 만든 RPG 게임 (0) | 2022.08.23 |