인터페이스 (Interface) :
여러 클래스가 같은 규칙을 따르게 하여 일관성있게 만드는 설계도
- interface와 class는 각각 한 파일씩 만들어야하는게 정석임 (편의상 하나의 파일안에 같이 만들 수 있음)
- 자료형.변수 = X일 땐, public static fianl(=상수)가 생략됨.
- 추상클래스 의 일종 / 정의만 있고 구현은 자식 클래스에서 해야함
- 변수 : static fianl(=상수)만 정의할 수 있음
- 하나 이상의 Interface를 implements한 클래스는 인터페이스의 모든 메소드를 Override(재정의)해야함. (강제성 - 무조건 부모꺼 메소드 다 Override해야함)
- Interface가 다른 Interface를 상속받을 수 있음. (이때, extends를 사용)
- 클래스와는 다르게다중구현이 가능함 (ex, class FruitImpl implements Fruits, bucket, person)
- 인터페이스 내 변수,메서드는 자동으로 특정한 접근 제어자들이 할당- (public static final)
- 인터페이스 내 선언된 메서드는 자동으로 public abstract이 생략되어있음
- 자식이 독자적으로 가지고 있는 메서드는 부모는 못씀
자료형?
: 데이터 종류 분리 (기본형 / 참조형)
- 기본형 : (int,boolean,double...) 메모리에 직접 값 저장 / 값에 대해서 직접적인 접근 가능
- 참조형 : (class, Interface, array[], instance, Sting...) Object 객체를 다루기 위한 데이터 타입 -> 객체가 어딘가 메모리에 저장되어 있는데, 이 객체를 활용해서 값을 변경할 때는 저장된 주소를 통해 변경 / 실제 값이 저장된 *메모리 주소
Java의 모든 클래스는 암묵적으로 가장 큰 부모인 Object 클래스를 상속받음.
=> 모든 객체는 Object 클래스의 멤버를 상속받을 수 있음.
이 중에서 equals 메서드도 Object클래스임.
if 어떤 클래스에 다른 클래스를 상속받지 않아보이면 -> 컴파일러는 자동으로 Object를 상속받도록 함. (생략가능)
ex) public class Test1 { = ublic class Test1 extends Object{
📌 Note Code
Test1
💻 입력
class Test {
class TestA{
public void print() {
System.out.println("A 클래스");
}
}
class TestB{
public void print() {
System.out.println("B 클래스");
}
}
public class Test1 {
public static void main(String[] args) {
TestA a = new TestA();
TestB b;
TestA c;
c=a;
//b=a; , X
//b = (TestB)a; , TestA,B는 서로 남남이기때문에 대입 X
}
}
📌 Note Code
Test2
💻 입력
class SuperTest{
public int a = 10, b = 20;
public void write() {
System.out.println("부모클래스 write()");
}
public int hap() {
return a + b ;
}
}
class SubTest extends SuperTest {
public int b = 100, c = 200;
public void print() {
System.out.println("자식클래스 print()");
}
@Override
public int hap() {
return a + b + c;
}
}
public class Test2 {
public static void main(String[] args) {
SubTest ob1 = new SubTest();
System.out.println(ob1.b);
SuperTest ob2 = ob1; //부모화, upcast (암시적형변환)
System.out.println(ob2.b);
System.out.println("합: "+ob2.hap()); //부모화했더라도 메서드는 (오버라이드한)자식꺼 씀
ob2.write();
//ob2.print(); 부모.자식이라서 에러
((SubTest)ob2).print(); // (자식화)print(); = downcast
}
}
100
20
합: 310
부모클래스 write()
자식클래스 print()
📌 Note Code
Test3
💻 입력
interface Fruits{
String Won = "원"; // (public static final - 생략) String Won = "원";
//public abstract 생략
int getPrice();
public String getName();
}
class FruitImpl implements Fruits { //FruitImpl = 가독성을 위해 클래스 이름 => implements 구현 했다는 뜻
@Override
public int getPrice() {//오버라이드시 무조건 public이 붙음 (자식꺼)
return 1000;
}
@Override
public String getName() {
return "사과";
}
public String getItems() {//독자적 (자식만 사용)
return "과일";
}
}
public class Test3 {
public static void main(String[] args) {
FruitImpl ob1 = new FruitImpl();
System.out.println(ob1.getItems());
System.out.println(ob1.getName());
System.out.println(ob1.getPrice()+Fruits.Won); // won = static변수를 부를때 class이름을 붙인다!!!
Fruits ob2 = ob1; //upcast (부모 <- 자식)
System.out.println(ob2.getName()); //원랜 부모지만 무조건 자식꺼 출력
//System.out.println(ob2.getItem()); 불가능 - 자식클래스에서 독자적으로 사용하므로
}
}
100
20
합: 310
부모클래스 write()
자식클래스 print()
📌 Note Code
기본생성자 + 오버로딩 생성자 둘다 꺼내면 둘 중 하나로 객체생성하겠음 / 오버로딩 생성자만 꺼내놓으면 오버로딩생성자로만 객체 생성하겠음
기본 생성자
public TestImpl() {
}
public TestImpl (String hak,String name,int kor,int eng) {
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
public void set(String hak,String name,int kor,int eng) {
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
Test4
💻 입력
interface Test{
//instance(전역변수) 초기값 = 0,null - 기본적으로 각각의 초기값을 갖음
//abstract 무조건 생략
public int total(); // - int 타입이므로 아래 오버라이드도 int타입으로 입력해야함
public void write();
}
class TestImpl implements Test{
private String hak,name;
private int kor,eng;
//기본생성자
public TestImpl() {
}
//우회도로
//생성자 오버로딩 : 생성 즉시 값을 초기화 함
public TestImpl(String hak,String name,int kor,int eng) {
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
//우회도로
//기본 생성자 + set메서드 : 나중에 데이터 값 초기화 하기 위함
public void set(String hak,String name,int kor,int eng) {
this.hak = hak;
this.name = name;
this.kor = kor;
this.eng = eng;
}
@Override
public int total() {
return kor+eng;
}
@Override
public void write() {
System.out.println(hak+","+name+","+total());
}
//Object ob=ob2 (부모 = 자식 , upcast)
//주변에 반드시 object 있음
@Override
public boolean equals(Object ob) { //Object의 메서드를 오버라이딩 함
boolean flag = false; // boolean의 초기값 = false , 지역변수 초기값 = 쓰레기값
if(ob instanceof TestImpl) {// instanceof = ob가 쓰고있는 순수 태생이 TestImpl이니?
TestImpl t = (TestImpl)ob; //자식으로 바꿔서 넣어라 = downcast= 형변환해서 넣어
// ob1.hak과 (string타입 =>equals로 비교- 주소비교)(ob2.hak) 데이터값이 같냐 = 같다
// && t = ob2. / this = ob1
//equals = [hak과 name]string의 equals
if(this.hak.equals(t.hak) && t.name.equals(this.name)) {
flag = true;
}
}
return flag;
}
// = public boolean equals(Object ob) { }
}
public class Test4 {
public static void main(String[] args) {
TestImpl ob1 = new TestImpl("2015105","배수지",80,90); //생성자 오버라이드
TestImpl ob2 = new TestImpl("2015105", "배수지", 100, 100);
//ob1 안에 있는 equals 위로 찾아가서 매개변수 ob2를 넣으라는 뜻 equals(Object ob2가 되므로 upcast)
if(ob1.equals(ob2)) { //true
System.out.println("ob1과 ob2는 동일인물임");
}else {
System.out.println("ob1과 ob2는 동일인물이 아님");
}
ob1.write();
ob2.write();
}
}
ob1과 ob2는 동일인물임
2015105,배수지,170
2015105,배수지,200
📌 Note Code
Test5
💻 입력
import java.util.Scanner;
interface FruitA{
String Won = "원"; // public static abstract가 생략이 되어있음
public int getPrice();
public String getName();
}
interface ItemFruit extends FruitA{
public String getItems();
}
class Orange implements ItemFruit{ //일반 class가 interface를 구현하려면 implements //상속되면 다 누적되니까~ Itemfruit는 위에 fruitA를 상속받기때문에
@Override
public int getPrice() {
return 1000;
}
@Override
public String getName() {
return "오렌지";
}
@Override
public String getItems() {
return "과일";
}
}
class Apple implements ItemFruit{
@Override
public int getPrice() {
return 2000;
}
@Override
public String getName() {
return "사과";
}
@Override
public String getItems() {
return "과일";
}
}
public class Test5 {
//인스턴스메서드
public void packing(ItemFruit ob) { // 이유? 아래 86-89 코딩이 똑같으므로 한메서드 만들고 거기서 빼서 쓰게끔
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice()+FruitA.Won);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Test5 t = new Test5(); //인스턴스메서드라 객체생성해야함
//주소를 대입연산자로 넣어놓기만 함
System.out.println("1.사과 2.오렌지?");
int n = sc.nextInt();
if(n==1) {
t.packing(new Apple()); //new 주소를 올려놓음 -> ob.getItems()에서 찾아서 씀 / 메모리에 올려놓고 10번지 = ob에 넣어놓게됨
}else if (n==2) {
t.packing(new Orange());
}
//Orange ob2 = new Orange();
//ItemFruit ob1; //부모
//ob1 = ob2; //부모<-자식 (upcast)
/*---------------------------------------
ItemFruit ob;
ob= new Orange();//upcast를 통해 객체 생성 - 부모의 이름으로 객체 생성할때
//부모 메서드 = 자식 메서드 똑같아야함 (자식이 독자적으로 하나 더 있어도 에러남)
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice()+FruitA.Won);
System.out.println("----------------------------");
//Apple ob2 = new Apple();
ob = new Apple(); //변수의 이름은 중요치않음
System.out.println(ob.getItems());
System.out.println(ob.getName());
System.out.println(ob.getPrice()+FruitA.Won);
System.out.println("----------------------------");
//--------------line 91부터와 똑같은 구조
int a;
a=10;
System.out.println(a);//a출력하고나면 보존할 필요 없음
a=20;//덮어씀
System.out.println(a);
*/
}
}
1.사과 2.오렌지?
2
과일
오렌지
1000원