본문 바로가기
코딩/수업 정리

20.12.14 Mon [016]

by 6^6 2020. 12. 14.
728x90
  • [015]복습
  • 자식 instanceof 부모
  • 다형성 예제(두 클래스 상속관계로 묶기)
  • 컴파일러가 우리 모르게 하는것. println, extends
  • extends Objectclass{} 의 원리
  • 클래스 이름앞에 final이 왔을때
  • @Override의 의미
  • 인터페이스(객체,다형성80%. 나머지20%가 인터페이스임)
  • 인터페이스의 implements
  • implements 상속과 구현
  • 인터페이스 예제
  • 오늘의 문제

 

 

 

단일상속만 지원하는 자바

 

함수오버라이딩은 자식거!

 

 

instanceof

if(안에있는내용은) true false이다.

    ↑

Cake의 인스턴스이냐.

 

인스턴스변수명(객체) intstanceof 클래스명

참조 변수 cake가 Object 클래스로 형 변환이 가능한지 조건문으로 나타냈습니다

 

 

instanceof 

1. 형변환 되는지 안되는지. 

자식 instanceof 부모      → 무조건 TRUE.

객체 instanceof 클래스

 

package java_1214;

class Box {
	public void simpleWrap() {//조부모
		System.out.println("SimpleWrapping");
	}
}

class PaperBox extends Box { // Box=조부모
	public void paperWrap() {
		System.out.println("Paper Wrapping");
	}
}

class GoldPaperBox extends PaperBox {// PaperBox=부모
	public void goldWrap() {
		System.out.println("Gold Wrapping");
	}
}

public class BoxMain { //자식
	public static void main(String[] args) {
		Box box1 = new Box();
		PaperBox box2 = new PaperBox();
		GoldPaperBox box3 = new GoldPaperBox();

		wrapBox(box1);//결과값 SimpleWrapping
		wrapBox(box2);//결과값 Paper Wrapping
		wrapBox(box3);//결과값 Gold Wrapping
	}

	public static void wrapBox(Box box) {
		//instanceof- 가끔사용- 형변환관계 따지는것임-가장대표적
		//파라미터타입으로(Box box)가장 부모걸로 만듦.(뭘로 들어올지모르니까)
		//바로밑에 ((GoldPaperBox) box).goldWrap(); 형변환 되는지.
		//goldWrap이 ((GoldPaperBox) box). 이걸로 형변환 되는지.
		//자식 instanceof 부모 
		if (box instanceof GoldPaperBox) {  //앞에 부모여서x
			((GoldPaperBox) box).goldWrap();
		} else if (box instanceof PaperBox) { //앞에 부모여서x
			((PaperBox) box).paperWrap();
		} else { //앞에 자식이어서 o
			box.simpleWrap(); 
		}
	}
}

 

 

 

 

 

 

다형성 예제(두 클래스 상속관계로 묶기)

↑private String name; 과 private String phone; 은 공통된것이다.

공통된것은 부모로 빼주기↓ 걍외우기

package java_1214;

class Friend { // 부모클래스
	protected String name;
	protected String phone;

	public Friend(String na, String ph) {
		name = na;
		phone = ph;
	}

	public void showInfo() {
		System.out.println("이름: " + name);
		System.out.println("전화: " + phone);
	}
}

class CompFriend extends Friend {
	private String department;

	public CompFriend(String na, String de, String ph) {
		super(na, ph);
		department = de;
	}

	public void showInfo() {
		super.showInfo();
		System.out.println("부서: " + department);
	}
}

class UnivFriend extends Friend {
	private String major;

	public UnivFriend(String na, String ma, String ph) {
		super(na, ph);
		major = ma;
	}

	public void showInfo() {
		super.showInfo();
		System.out.println("전공: " + major);
	}
}
//메인함수1
package java_1214;

public class FriendMain {
	public static void main(String[] args) {
		UnivFriend[] ufrns = new UnivFriend[5];
		int ucnt = 0;

		CompFriend[] cfrns = new CompFriend[5];
		int ccnt = 0;

		ufrns[ucnt++] = new UnivFriend("LEE", "Computer", " 010-333-555");
		ufrns[ucnt++] = new UnivFriend("SED", "Electronics", " 010-222-444");

		for (int i = 0; i < ucnt; i++) {
			ufrns[i].showInfo();
			System.out.println();
		}

		for (int i = 0; i < ccnt; i++) {
			System.out.println();
		}
	}
}/*이름: LEE
전화:  010-333-555
전공: Computer

이름: SED
전화:  010-222-444
전공: Electronics*/
//또다른 메인함수2

package java_1214;

public class FriendMain {
	public static void main(String[] args) {
		Friend[] frns = new Friend[10];
		int cnt = 0;


		frns[cnt++] = new UnivFriend("LEE", "Computer", " 010-333-555");
		frns[cnt++] = new UnivFriend("SED", "Electronics", " 010-222-444");
		frns[cnt++] = new UnivFriend("YOON", "R&D 1", " 010-333-444");
		frns[cnt++] = new UnivFriend("PARK", "R&D 2", " 010-555-666");
		
		for (int i = 0; i < cnt; i++) {
			frns[i].showInfo();
			System.out.println();
		}
	}
}
/*이름: LEE
전화:  010-333-555
전공: Computer

이름: SED
전화:  010-222-444
전공: Electronics

이름: YOON
전화:  010-333-444
전공: R&D 1

이름: PARK
전화:  010-555-666
전공: R&D 2*/

 

컴파일러가 우리 모르게 하는것..

또다른거.

디폴트 생성자 : 생성자를 안적고 프로그래밍 하게 되면 컴파일러가 디폴트생성자 하나 알아서 넣어줌.

디폴트 생성자란? 파라미터도없고 내용도없는것. 빈껍데기.

 

extends Objectclass{ } : Object 클래스(최고의 부모)를 상속한다. 상속 두번 못받는 이유는 Object가 이미 직간접으로 상속 하고있기 때문

따라서 우리는 이걸 사용할 수 있다. 얘도 데이터멤버와 함수(11개)가 있다. 3-4개만 꼭 알것. 반드시 기억할것.

	Shape[] shape = new Shape[2];
	shape[0]= new Circle(10.0);
	shape[1]= new Rectangle(10, 4);

	double area =0;	
		for(int i =0; i<shape.length; i++) {
			area = area + shape[i].getArea();
		}	
	System.out.println(area);
    
    Shape circle = new Circle(10);
  //↑shape든 뭐든 받아낼수있는건 다형성때문  
    System.out.println(circle);	//위의 사진참조
              //↑println f3치고들어가면 (Object X)뜸
              //얘도 다형성(Polymerphism)
              
              //public void println(String x) {
      		//String v = (String.valueOf(x)); //valueOf는 다 String으로 바꿔줌.오버로딩임
            						//↑ f3
                          		 //obj

println 은 Object x로 받음 다형성임 / 원리 무조건 깨우치기

Object클래스는 멤버없음

 

 

extends Objectclass{ } 의 원리

↓갖다쓰는게 중요! 

 

http://www.tcpschool.com/java/java_api_object

String toString() 알고가기!

 

class A { // = class A extends Object{} 임
}

public class TestMain {
	public static void main(String[] args) {
		A a = new A();
		System.out.println(a);
	}

}//@28a418fc -출력값 이렇게 주소로 나옴
//why? 이렇게 나오도록 println 을 만들어놨기때문

  ↓F3

  ↓F3

  ↓F3

//문자열 호출하고싶으면?

class A {
	//이 과정 무조건 외우기
	//★↓오브젝트에있는걸 함수오버라이딩한다. = 자식것이 호출됨★
	@Override
	public String toString() {
		return "@주소를 →문자열로 바꾸기";
	}

}

public class TestMain {
	public static void main(String[] args) {
		A a = new A();
		System.out.println(a);
	}

}

 

클래스 이름앞에 final이 왔을때

final의 의미는 = 상속이 안된다는 의미. 상속하지 마라.

 

*메소드앞에 final이 왔을때 의미 : 오버라이딩이 안된다. 

 

 

 

@Override

위에 두 클래스는 오버라이딩이 아니다(타입이 다르기때문에 오버로딩임)

@Override 을 위에 써주게 되면 오버라이딩아니면 오류내라고 바로 알려주는 역할임!

 

 

 

인터페이스 

얘도 .java임

interface = class랑 같음

뒤에오는것 interface명

class안에 오는것은 함수와 데이터멤버

interface안에 오는것은 함수선언(추상메소드)만 옴.( {메소드의 부연부분(=바디) 가 없다.}

interface에는 상수(final)(변수x), 추상메소드 만 올 수 있다.

 

package java_1214;

interface Printable { //추상화 / abstract=추상

	// 이게 생략"public abstract" void printLine(String str);
	// 인터페이스에서는 무조건"public abstract"이거 앞에 넣어줘야함
	// 구현부분없으면 abstract붙어야하는데 컴파일러가 알아서 넣어줌
	void printLine(String str); // =추상메소드
}

class A{}

class Print {
	A a = new A();
	//Printable p = new Printable(); - 객체생성불가, 생성자 불가
	Printable p; // 선언은 가능
	void print(String str) {
	};

}

<인터페이스 특징>

abstract가 붙는다. (=추상 메소드가 온다.)

(abstract 는? = 자손이 구현하라.)

몸체가 없어서 객체생성이 불가하다. (Printable p = new Printable(); )

but, 함수 선언은 가능하다. Printable p;

implements 

implements = 구현하다. (함수임) (위 사진 참조)

-인터페이스는 반드시 implements한다.

→ class 클래스명 implements 인터페이스명{ }  - 오버라이드 @Override

여기 클래스명이 자손임

∴ 자손(=클래스)로 객체 생성 가능

Printable prn = new Printer(); 인터페이스명 변수명 = new 클래스명();

prn.print("Hello")

 

implements의 상속과 구현

-implements는 다중상속이 가능하다.

대표적 이유와 예 : 디바이스 설치

↓반드시 외우기

package java_1214;

interface Printable { // MS가 제공한 인터페이스
	public void print(String doc);
}

class SPrinterDriver implements Printable {

	@Override
	public void print(String doc) {
		System.out.println("From Samsung printer");
		System.out.println(doc);
	}
}

class LPrinterDriver implements Printable {
	@Override
	public void print(String doc) {
		System.out.println("From LG printer");
		System.out.println(doc);
	}
}

 

package java_1214;

public class DriverMain {

	public static void main(String[] args) {
		String myDoc = "This is a report about...";

		// 삼성프린트 출력
		Printable prn = new SPrinterDriver();
		prn.print(myDoc);
		System.out.println();

		prn = new LPrinterDriver();
		prn.print(myDoc);

	}

}

 

 

**기본상식 interface명은 I+대문자~ 로 시작하거나 뒤에가 able로 끝나는게 기본적이다.

**기본상식 한클래스 내에선 public 하나밖에 못쓴다. public은 진입점이다. 

 

인터페이스 예제

package java_1214;

public class ICalMain {
	public static void main(String[] args) {
		// calculator 구현하는 프로그램
		
		ICalculate cal = new Calculator();//인터페이스 생성자.다형성
		System.out.println(cal.add(3, 2));
		
		Calculator calcul = new Calculator();//다이렉트 생성
		System.out.println(calcul.add(3, 2));


	}
}
package java_1214;

public interface ICalculate {
	int add(int x, int y);

	int sub(int x, int y);

	int mul(int x, int y);

	int div(int x, int y);

}// 22명에게 외주줌.
//Calculator 클래스만들어서 자손부여

class Calculator implements ICalculate {
	public void cal(int x, int y) {

	}

	@Override
	public int add(int x, int y) {

		return x + y;
	}

	@Override
	public int sub(int x, int y) {

		return x - y;
	}

	@Override
	public int mul(int x, int y) {

		return x * y;
	}

	@Override
	public int div(int x, int y) {

		return x / y;
	}

}

 

zimt.tk/201214_-_116_instanceof-Object-class-final-Override-interface-8bf4265c27174cc4b20f59f375f8b7f9

오늘의 문제

1.Object 클래스에 대하여 설명하시오.

자바에서 모든 클래스는 사실 Object를 암시적으로 상속받고 있다. 따라서 Object는 모든 클래스가 상속하는 최고의 부모 클래스이다.  그 이유는 모든 클래스가 공통으로 포함하고 있어야 하는 기능을 제공하기 위해서다.

 


2.아래와 같이 출력되는 이유를 하시오.

class A {
	
	 @Override
	 public String toString() {
		
		 return "이것은 A 클래스 입니다.";
	 }	
}

public class TestMain {
	public static void main(String[] args) {
		A a  = new A();
		System.out.println(a);
		
	   }		
}
===============
이것은 A 클래스 입니다.

 

toString 없이 출력하게 되면 println(a);를 그대로 출력하게 되면 출력값이  @2768234 이런식으로 주소로 나온다. (자바가 이렇게 나오도록 println을 
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }//이렇게 만들어놨기 때문)
toString메소드는 String클래스의 객체이고 자신이 가진 값을 그대로 리턴해주는 성질을 가지고있다. 따라서 a값을 오버라이드 하여 String값으로 재정의 하여 "이것은 A클래스 입니다"라는 문자열이 그대로 출력되는 것이다

 

 

3. class 이름 및 함수 에서 final 의 의미는?

클래스 이름에서의 final의 의미는 = 상속이 안된다는 의미. 상속하지 마라.

메소드앞에 final이 왔을때 의미 : 오버라이딩이 안된다. 

 

 

6. interface 와 class 의 차이는

클래스는 크게 일반 클래스와 추상 클래스로 나뉘는데 추상 클래스 클래스 내 '추상 메소드'가 하나 이상 포함되거나 abstract로 정의된 경우를 말합니다.

반면 인터페이스는 모든 메소드가 추상 메소드인 경우입니다.

interface

  • interface + interface명 (); → 함수 선언부(정의), body없음 (당연히 생성자 만들 수 없음)
  • implements 키워드로 인터페이스를 구현할 (자손)클래스 표시
  • 둘 이상의 다중 인터페이스 구현 가능 (implements A, B 쉼표로 구분)
  • body가 없으므로 객체 생성 불가, 선언 혹은 구현만 가능함
  • 무조건 public 이어야 한다.
  • 이름은 -able 혹은 I+이름으로 짓는 것이 관례

class

  • class + class명 () {body} → body 있음(함수, 변수 모두 올 수 있다.)
  • extends 키워드로 상속 표시함
  • 단일 상속만 가능함 (자식이 상속) / 다중 상속 안됨
  • 객체 생성 가능

→ interface와 class를 동시에 상속, 구현 가능

//abstract 생략 가능(컴파일러가 자동생성)
public interface Printable {
	abstract public void print(String doc); 
}

class A {

}

class Printablei implements Printable extends A{    
	A a = new A();     
	//클래스끼리는 객체생성이 됨

	Printable p = new Printable(); //(x)
	//incterface는 객체 생성 안됨 왜? 구현부분이 없어서 써먹을수 없으니까

	Printable p;   
	//선언은 가능(4바이트 방잡기는 가능) → 참조변수 선언이 가능하다.
	
	//interface 함수의 구현부분(overriding)
	@OVerride
	public void print(String doc){구현 내용};  //중괄호가 있다.
}

 


7. 다음을 프로그램 하시오.[필수]

interface Printable { // MS가 정의하고 제공한 인터페이스
   public void print(String doc);
}
 SPrinterDriver 와 LPrinterDriver를 만드시오
======================

public static void main(String[] args) {
   String myDoc = "This is a report about...";
   
   // 삼성 프린터로 출력
   Printable prn = new SPrinterDriver();
   prn.print(myDoc);
   System.out.println();

   // LG 프린터로 출력
   prn = new LPrinterDriver();
   prn.print(myDoc);
}
================================================
출력: From Samsung printer
This is a report about ...

From LG printer
This is a report about ...
==================================
package java_1214_prac;

public class aaaaMain {
	public static void main(String[] args) {
		String myDoc = "This is a report about...";

		// 삼성 프린터로 출력
		Printable prn = new SPrinterDriver();
		prn.print(myDoc);
		System.out.println();

		// LG 프린터로 출력
		prn = new LPrinterDriver();
		prn.print(myDoc);
	}

}

package java_1214_prac;

interface Printable { // MS가 정의하고 제공한 인터페이스
	public void print(String doc);

}

class SPrinterDriver implements Printable {
	@Override
	public void print(String doc) {
		System.out.println("From Samsung printer");
		System.out.println(doc);
	}

}

class LPrinterDriver implements Printable {
	@Override
	public void print(String doc) {
		System.out.println("From LG printer");
		System.out.println(doc);
	}

}

 

 

8.@Override 에 대하여 설명하시오.

@Override 을 위에 써주게 되면 오버라이딩아니면 오류내라고 알려주는 역할이다.

오버라이딩 - 똑같은 함수와 변수를 쓰는것.

오버로딩 - 같은 함수명에 변수나 타입이 다른 것.


9.interface 에 대하여 설명하시오.

<인터페이스 특징>

abstract가 붙는다. (=추상 메소드가 온다.)

몸체가 없어서 객체생성이 불가하다. (Printable p = new Printable(); → X )

but, 함수 선언은 가능하다. Printable p;

 

----블로그 설명----

Java에서 abstract, final과 함께 대표적인 규제이며 Java가 추상화를 위해 제공하는 가장 유용한 도구이다.

어떤 클래스가 있고 그 클래스가 특정한 인터페이스를 사용한다면 그 클래스는 반드시 사용한 인터페이스의 메소드들을 구현해야 한다.(=오버라이딩)

만약 인터페이스에서 강제하고 있는 메소드들을 구현하지 않으면 컴파일 조차 되지 않는다.

 

interface 규칙

- 인터페이스에 정의되는 멤버들의 접근제어자는 public이다.

- 하나의 클래스는 복수개의 인터페이스를 구현할 수 있다.

- 인터페이스 상속이 가능하다.

- 인터페이스는 어떤 일을 하겠다는 기능만 정의해 놓는다. 인터페이스에는 어떻게 하겠다는 구현 방법은 나타나 있지 않다. 그것은 인터페이스를 구현한 클래스들이 알아서 결정할 일이다.

----------------------


10.interface에 올수 있는 두가지는?

함수선언()(=추상메소드) 와 상수(변수x)


11.abstract 키워드에 대하여 설명하시오.

abstract = 자손이 구현하라.

abstract가 class앞에 붙으면 추상클래스(인터페이스도 추상클래스), 메소드 앞에 붙으면 추상메소드가 된다.

abstract 키워드가 붙은 메소드는 몸체를 가질 수 없다.

 

추상화 키워드이다.

<인터페이스 특징>

abstract가 붙는다. (=추상 메소드가 온다.)

(abstract 는? = 자손이 구현하라.)

몸체가 없어서 객체생성이 불가하다. (Printable p = new Printable(); )

but, 함수 선언은 가능하다. Printable p;

 

// 이게 생략"public abstract" void printLine(String str); 
// 인터페이스에서는 무조건"public abstract"이거 앞에 넣어줘야함 
// 구현부분없으면 abstract붙어야하는데 컴파일러가 알아서 넣어줌 
void printLine(String str); // =추상메소드

 

12. 아래의 출력 결과가 아래와 같이 나오도록 프로그래밍 하시오.

Object obj = new Circle(10);
System.out.println(obj);
=================
출력: 넓이는 100 입니다.
package java_1214_prac;

public class CircleMain {
	public static void main(String[] args) {
		Object obj = new Circle(10);
		System.out.println(obj);
	}

}
package java_1214_prac;

class Circle {

	private double r;

	public Circle(double r) {
		this.r=r;
	}

	@Override
	public String toString() {
		return "출력: 넓이는 "+(r*r*Math.PI)+" 입니다.";
	}

}

  ↑자식이 함수 오버라이딩시켜줘야함. 오버라이딩은 자식거.

 

둘다 타입이 다른데(objec , circle ) 형변환안해줌. extends가 없다=모든클래스들은 object를 상속받고있다. 라는뜻!

//이건 상속개념임

class 컴퓨터{}
class 노트북 extends 컴퓨터{}

노트북은 컴퓨터 기능을 확장해서 휴대할수 있게 만든 기기라서요

노트북은 노트북이면서 컴퓨터가 되요

컴퓨터는 컴퓨터이면서 노트북이 될순 없구요

컴퓨터 컴1 = new 노트북()
Object obj = new Circle()

모든 클래스의 조상은 Object 클래스니까

class Object()
class Circle extends Object()

노트북이 컴퓨터이듯이
Circle도 Object예요.

Object obj = new Object()가 된다면
Object obj = new Circle()가 될수 있어요 Circle는 Object 니까

//String toString(int r)넣으면 @2348972 오류나는 이유
아까 int r때문에 오버라이딩이 아니라 오버로딩이 되었다는거 
어떤의미인지 설명해주실수 있으신가요??

toString()
toString(int r)
toString(double d)
메소드 이름은 같지만 매개변수의 갯수나 위치만 다르게 만드는게 오버로딩

오버라이딩은 부모의 메소드를 바꾸지않고 {} 속의 내용만 고치는게 오버라이딩

부모는 toString(){} 이런 메소드이고
circle 클래스가 상속받았으니
toString()  가 있고(눈에 안보이지만)
toString(int r) 있었어요.

.java에는 없는데 .class 에는 있어요
그럼 자바에 미리 숨겨진거?? ㄴㄴ숨겨진건 아니고 상속받으면 있어요
==========정리==============
class 컴퓨터{
    void 전원켬(){
       sysout("전원켬")
    }
}

class 노트북 extends 컴퓨터{}

컴퓨터 컴1 = new 노트북()
컴1.전원켬()

노트북 클래스에 직접적으로 코드 안 적어도 jvm이 컴퓨터 클래스의 메소드를
노트북 클래스가 사용할수 있게 해줘서 노트북 클래스에는 상속받은 전원켬() 메소드가 있어요


전원켬(int r){} 노트북 클래스에 만들면

전원켬(){}
전원켬(int r){}

전원켬() 메소드가 두개 생겨요
상속받은거 하나, 직접 만든거 하나

13. 아래의 메모리를 그리시오.

class MobilePhone {
    protected String number;
    
    public MobilePhone(String num) {
        number = num;
    }    
    public void answer() {
        System.out.println("Hi~ from " + number);
    }
}

class SmartPhone extends MobilePhone { 
    private String androidVer;
    
    public SmartPhone(String num, String ver) {
        super(num);
        androidVer = ver;
    }    
    public void playApp() {
        System.out.println("App is running in " + androidVer);
    }
}
=======================================
	MobilePhone phone = new SmartPhone("010-555-777", "Nougat");
    	phone.answer();    	
    	SmartPhone s = (SmartPhone)phone;    	
    	s.playApp();

설명

class MobilePhone {
    protected String number;
    
    public MobilePhone(String num) {
        number = num;
    }    
    public void answer() {
        System.out.println("Hi~ from " + number);
    }
}

class SmartPhone extends MobilePhone { 
    private String androidVer;
    
    public SmartPhone(String num, String ver) {
        super(num);
        androidVer = ver;
    }    
    public void playApp() {
        System.out.println("App is running in " + androidVer);
    }
}
=======================================
MobilePhone phone = new SmartPhone("010-555-777", "Nougat");//다형성이 적용되어있음(자식=부모)
		phone.answer();    	
    	SmartPhone s = (SmartPhone)phone;    
    	s.playApp();

MobilePhone phone = new SmartPhone("010-555-777", "Nougat"); //다형성이 적용되어있음(자식=부모)

자식=부모 는 원래 안됨

근데 되는 케이스가 있다.

Moblie phone = new SmartPhone(); 해서 형변환 시켜줌

 

MobilePhone phone = new SmartPhone();

자식=부모인데 이건 부모=자식 - 되는이유는 이미 자식 거를 갖고있기 때문에!

 

SmartPhone s = (SmartPhone)phone; 이 되는 이유

 

728x90

댓글