본문 바로가기
Java

Final , abstract(추상) , Interface(인터페이스)

by 임혁진 2023. 11. 23.

Final 

=> final이 변수에 붙으면 변경불가

=>final변수는 반드시 초기화가 진행되어야 한다

public class Person {

//final이 변수에 붙는경우 (변경금지)

//final변수는 반드시 초기화가 진행되어야 합니다.

public final String nation = "대한민국";

public final String ssn; //주민번호

public String name; //이름

 

public Person(String ssn, String name) {

this.ssn = ssn;

this.name = name;

}

}

public class Constant {

 

public static final double PI = 3.14;

public static final int O2 = 32;

public static final long EARTH_RADIUS = 6400L;

 

}

public class MainClass {

 

public static void main(String[] args) {

 

Person p1 = new Person("123123", "홍길동");

//p1.ssn = "234234"; //변경금지

 

Person p2 = new Person("345345", "이순신");

 

//객체마다 다른값을 가질수는 있음

System.out.println(p1.ssn); //123123

System.out.println(p2.ssn); //345345

 

final int a = 1;

 

 

System.out.println("------------------");

 

System.out.println( Constant.PI );

System.out.println( Math.PI );

}

}

=>객체 마다 다른 값을 가질 수는 있다 (static은 아님)

 

final 메소드와 클래스

public /*final*/ class Parent { //상속금지

 

public void method01() {

 

}

//오버라이딩 금지

public final void method02() {

 

}

 

}

 

final 이 메소드에 들어가면 오버라이딩 금지 

final 이 클래스에 들어가면 상속금지

 

 

abstract (추상)

-추상 메소드를 쓰지않는다면

public class Store {

 

//추상메소드를 쓰지 않는다면..?

 

public void apple() {

System.out.println("사과 가격은 지점에서 정합니다");

}

public void melon() {

System.out.println("멜론 가격은 지점에서 정합니다");

}

public void orange() {

System.out.println("오렌지 가격은 지점에서 정합니다");

}

}

public class SeoulStore extends Store {

 

//store는 어떤기능이 있는지 모른다면...

 

public void melon() {

System.out.println("서울에서 멜론가격은 500원 입니다");

}

 

public void orange() {

System.out.println("서울에서 오렌지가격은 600원 입니다");

}

//apple 오버라이딩을 해야하는데 , 빼먹었다면?

}

public class MainClass {

 

public static void main(String[] args) {

SeoulStore store = new SeoulStore(); //자식객체 생성

store.apple(); //apple은 반드시 오버라이딩 해야하는데,잘못된 메소드 호출로 연결될 수 있다

store.melon();

store.orange();

}

}

꼭 오버라이딩 해야되는데 하지않아서 잘못된  메소드가 호출되었다.

 

추상의 사용 --> 무조건 오버라이딩을 해야됨. 

 

=> 추상클래스 

 1. 클래스에 abstract를 붙이면 추상클래스가 됩니다
 
 2. 메서드에 abstract를 붙이면 추상메서드가 됩니다.

 3. 추상메서드는 {}가 없는 메서드의 선언 입니다.

 4. 추상메서드는 추상클래스에서만 선언이 가능합니다.(소울메이트)

 5. 추상클래스도 생성자, 일반메서드, 멤버변수 모두 가질 수 있습니다

 

 6. 마찬가지로 상속을 전제

public abstract class Store {

 

/*

* 추상클래스

* 1. 클래스에 abstract를 붙이면 추상클래스가 됩니다

* 2. 메서드에 abstract를 붙이면 추상메서드가 됩니다.

* 3. 추상메서드는 {}가 없는 메서드의 선언 입니다.

* 4. 추상메서드는 추상클래스에서만 선언이 가능합니다.(소울메이트)

* 5. 추상클래스도 생성자, 일반메서드, 멤버변수 모두 가질 수 있습니다

*/

 

private String name = "호식이 과일가게";

 

public Store() {

System.out.println("추상클래스의 생성자 호출됨");

}

 

public abstract void apple();

public abstract void melon();

public abstract void orange();

 

public final void mango() {//오버라이드 금지

System.out.println("본점에서 1000원 고정가격 입니다");

}

 

public String getName() {

return name;

}

}

public class SeoulStore extends Store {

 

@Override

public void apple() {

System.out.println("서울의 사과는 500원 입니다");

}

 

@Override

public void melon() {

System.out.println("서울의 멜론은 600원 입니다");

}

 

@Override

public void orange() {

System.out.println("서울의 오렌지는 700원 입니다");

}

}

public class BusanStore extends Store {

 

@Override

public void apple() {

System.out.println("부산지점 사과는 100원 입니다");

}

@Override

public void melon() {

System.out.println("부산지점 멜론은 200원 입니다");

}

@Override

public void orange() {

System.out.println("부산지점 오렌지는 300원 입니다");

}

}

public class MainClass {

 

public static void main(String[] args) {

 

/*

* 추상클래스를 사용하려면, 자식으로 생성해서 추상클래스 타입으로 구체화 시켜야됩니다.

*

* (객체의 추상화) 라고 부르기로 약속합시다.

*/

 

Store store = new SeoulStore();

 

store.apple();

store.melon();

store.orange();

store.mango();

System.out.println( store.getName() );

 

System.out.println("----------------------------------");

 

Store store2 = new BusanStore();

store2.apple();

store2.melon();

store2.orange();

store2.mango();

System.out.println( store2.getName() );

}

}

InterFace

public interface Inter1 {

 

//인터페이스는 상수, 추상메서드 +a(static, default)

int A = 1; //자동으로 상수로 선언됩니다.

void method01(); //자동으로 추상메서드가 됩니다.

 

//static메서드도 선언이 됩니다.

public static void method03() {

System.out.println("static메서드 선언 가능");

}

//인터페이스에서 몸체를 가진 메서드 default

public default void method04() {

System.out.println("default메서드 선언 가능");

}

}

public interface Inter2 {

 

double PI = 3.14;

void method02();

}

public class Basic implements Inter1, Inter2 {

 

//클래스가 인터페이스를 상속받을 때는 implements 키워드를 씁니다.

//클래스가 인터페이스를 구현한다(상속) 이라고 부릅니다.

//인터페이스에 선언된 추상메서드는 자식에서 반드시 오버라이딩 되야합니다.

 

@Override

public void method01() {

System.out.println("오버라이드 된 메서드 1번");

}

 

public void method03() {

System.out.println("basic의 메서드 3번");

}

 

@Override

public void method02() {

System.out.println("오버라이드 된 메서드 2번");

}

}

 

public class MainClass {

 

public static void main(String[] args) {

 

//인터페이스는 객체 생성을 할 수 없습니다.

//Inter1 i1 = new Inter1();

 

Basic b = new Basic();

b.method01(); //

 

//인터페이스는 부모 타입이 될 수 있습니다.

Inter1 i1 = b;

i1.method01(); //

 

System.out.println("------------------------------");

/*

* 인터페이스 타입으로 변환되면, 자식의 기능을 사용할 수 없습니다.

*

* 다시 자식의 기능을 사용하고 싶다면, 형변환이 가능합니다.

*/

Basic bb = (Basic)i1;

bb.method01();

bb.method03();

 

 

//default메서드

bb.method04();

Inter1.method03();

}

}

 

Interface 예제

public abstract class Animal {

 

public abstract void eat();

}

 

public class Tiger extends Animal {

 

@Override

public void eat() {

System.out.println("호랑이는 고기를 먹어요");

}

 

}

public interface IPet {

 

void play();

}

 

public class Cat extends Animal implements IPet {

 

@Override

public void eat() {

System.out.println("고양이는 생선을 먹어요");

}

 

@Override

public void play() {

System.out.println("고양이는 방에서 놀아요");

}

 

}

public class Dog extends Animal implements IPet{

 

@Override

public void eat() {

System.out.println("강아지는 사료를 먹어요");

}

 

@Override

public void play() {

System.out.println("강아쥐는 밖에서 놀아요");

}

 

}

public abstract class Fish {

 

public abstract void swim();

}

public class Shark extends Fish{

 

@Override

public void swim() {

System.out.println("상어는 바다에서 놀아요");

}

 

}

public class GoldFish extends Fish implements IPet{

 

@Override

public void swim() {

System.out.println("금붕어는 어항에서 헤엄쳐요");

}

 

@Override

public void play() {

System.out.println("금붕어는 어항에서 놀아요");

}

 

}

public class PetShop {

 

//각각의 펫들을 저장할 수 있는 클래스

 

//1. static carePet()

//매개변수는 펫타입을 받아서 원본 타입으로 캐스팅 하는기능

public static void carePet(IPet pet) {

 

if(pet instanceof GoldFish) {

GoldFish g = (GoldFish)pet;

 

g.play();

} else if(pet instanceof Dog) {

Dog d = (Dog)pet;

 

d.eat();

 

} else if(pet instanceof Cat) {

Cat c = (Cat)pet;

 

c.eat();

}

}

//2. static petInfo()

//매개변수로 펫배열 타입을 받아서 play() 출력.

public static void petInfo(IPet[] pets) {

for(IPet p : pets) {

p.play();

}

}

 

 

}