java

22.11.10 접근제한자, 상속, 다형성(Polymorphism), Override

SoulMania 2023. 2. 13. 23:11

221110.zip
0.03MB
단원설명.txt
0.00MB
설명.txt
0.02MB
송준호_1110 - 업그레이드버전.txt
0.01MB
송준호_1110.txt
0.01MB
혼자 연습.txt
0.00MB

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
면접 대비는 목차보고 그걸 말하는 연습을 하는게 가장 좋다.
물론 코딩을 잘하는게 제일 중효하지만...
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

접근제한자

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
default
패키지만 같으면 다 된다>!!!! 상속 관계 다 필요없고 패키지만 같으면 허용. 다르면 다 비허용

protected 패키지가 같으면 default와 동일, 다르면 자식이면 허용. 상속관계 허용
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
상위클래스(추상적)
하위클래스(구체적)

하위클래스 is 상위클래스 이다.
개는 동물이다.
닭은 동물이다. 등등등...

int a =10;
상위클래스=하위클래스

하위클래스 is 상위클래스 이다.
10은 a이다.

동물=사람

Animal animal = new Human();
Animal animal = new Student();
Animal animal = new Dog();
Animal animal = new Cat();

animal 이라는 참조변수는 다양한 형태를 가질 수 있다. == 다형성

Object동물

필드

  • 나이 int age = 20;
  • 키 int height = 180;
  • 몸무게 double weight = 77.7;
    메소드
  • 움직인다() 리턴유형 move(매개변수);
  • 잠을잔다() void sleep();
  • 먹는다() void eat(String anything);
  • 호흡한다() void breath(~~);
  • 소리낸다() 리턴유형 sound("멍멍")
  • 내장기관이 있다() boolean gut();

사람은 동물이다

Human is an animal.

-> is a 관계 => 상속관계
a = 10;
Animal = Human
Animal 참조변수 = new Human();

Animal{
int age; 등
void sleep(){} 등
}

class Human extends {
int age; 등등등
void sleep(){} 등+
@Override
sound(){"말을 한다"}
write()

}


~~는 is 이다 관계 또는
has a 관계

자동차는 타이어를 가지고 있다.

class Car{
//필드
String color;
int price;
Trire tire; //Tire[] tire; String[] names={"홍길", "순신", "난새"}; names[0]="QQ"

//생성자

//method

}


class Tire{
//필드
String company;
int price;
int size;

//생성자
//method

boolean is

부모 메소드 사용(super)​

메소드 재정의는 부모 메소드 숨기는 효과 !!​

자식 클래스에서는 재정의된 메소드만 호출​


★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
자식 클래스에서 수정되기 전 부모 메소드 호출 - super 사용​

super는 부모 객체 참조(참고: this는 자신 객체 참조)
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★


상속

자식클래스 -> 부모 클래스 로 타입변환이 일어나는 것은 자동 타입변환이 일어난다.

작은것에서 큰것으로 갈때는 자동.


부모 - 전기기계
String, String, String, int, String, String
company, model, color, price, nation, productDate --->DB컬럼명 자바소스 필드명
제조회사, 모델명, 색상, 가격, 생산국가, 생산일
powerOn()//전원을 켜다
powerOff()//전원을 끄다
sound() // 소리가 울린다()

자식-전화기, HP, Tv, Audio, Video, Car 등

전화기(기계 상속 Phone)
String, String, String, int, String, String, String
company, model, color, price, nation, productDate, telecom --->DB컬럼명 자바소스 필드명
제조회사, 모델명, 색상, 가격, 생산국가, 생산일, 통신사
넥슨, mns1, red, 350000, korea, 20120203
넥슨, mns2, ivory, 120000, china, 201212

makeCall() // 전화를 건다
receiveCall() // 전화를 받는다

스마트폰(SmartPhone)
company, model, color, price, nation, productDate, OS, telecom
삼성, 갤럭시5, black, 500000, korea, 20220101, 안드로이드, 좋은 무선통신사

문자를 보낸다();-매개변수 필요?
문자를 받는다()
Internet을 사용한다)()
카메라켠다();
sound() // 소리가 울린다() -->오버라이딩

숙제1) Machine01을 상속받는 Phone01클래스를 작성하시오
숙제2) Phone01을 상속받는 SmartPhone01클래스를 작성하시오

Machine01의 sound()메서드는 Phone01클래스와 SmartPhone01클래스에서 오버라이딩합니다.(이 때 Annotation)을 붙이도록 합니다

위의 코드는 본인이름_1110.txt파일로 제출

회원=Member
name id pw birth gender address email
홍길동, hid, h123, 801123, 남, 서울시 강남구, h@test.com
김길동, kid, k123, 831225, 여, 서울시 서초구, k@test.com


동물 = 동물
사람 = 사람

기계 = new 기계
전화기 = new 전화기
스마트폰 = new 스마트폰

기계 = new 전화기
전화기 = new 스마트폰
기계 = new 스마트폰


package ch07;
/*부모 - 전기기계
String, String, String, int, String, String
company, model, color, price, nation, productDate --->DB컬럼명 자바소스 필드명
제조회사, 모델명, 색상, 가격, 생산국가, 생산일
powerOn()//전원을 켜다
powerOff()//전원을 끄다
sound() // 소리가 울린다() */
//이 클래스는 (전기)기계에 대한 속성, 기능을 정의한 클래스이다.
public class Machine01 {
//field //필드 데이터는 외부에서 접근못하도록 private로 선언
//[접근제한자][제어자] 데이터타입 필드명[=초기값];
private String company;
private String model;
private String color;
private int price;
private String nation;
private String productDate;

//constructor //명시적으로 둘다 선언해주는 것이 좋다...
//[접근제한자][제어자] 클래스명(매개변수리스트){}
public Machine01(){}

public Machine01(String company, String model, String color, int price, String nation, String productDate){
    this.company=company;
    this.model=model;
    this.color=color;
    this.price=price;
    this.nation=nation;
    this.productDate=productDate;
}


//method
//[접근제한자][제어자] 리턴유형 메소드명(매개변수리스트){}

// 이건 setter getter 이용... 일단 주석!!
public void setInfo(String company, String model, String color, int price, String nation, String productDate) {
this.company=company;
this.model=model;
this.color=color;
this.price=price;
this.nation=nation;
this.productDate=productDate;

}

//
public String getCompany() {
return company;
}
public String getModel() {
return model;
}
public String getColor() {
return color;
}
public int getPrice() {
return price;
}
public String getNation() {
return nation;
}
public String getProductDate() {
return productDate;
}

//전원을 켜다
public void powerOn(){
    System.out.println("전원을 켭니다.");
}

//전원을 끄다
public void powerOff(){
    System.out.println("전원을 끕니다.");
}

//소리가 울린다
public String sound(){
    return "기계음 ~ 위웅 ~ 위웅";
}


//이건 내가 오버라이딩 한 것.
public String toString() {
    return "[제조사]="+company+", [모델]="+model+", [색상]="+color+", [가격]="+price+", [제조국]="+nation+", [제조일]="+productDate;
}


//Object의 toString()을 오버라이딩
//Object의 toString(): 객체의 정보를 해시코드 문자열형으로 제공
//이 클래스의 toString(): 객체의 필드의 값을 문자열형으로 제공

// @Override
// public String toString() {
// return "Machine01 [company=" + company + ", model=" + model + ", color=" + color + ", price=" + price
// + ", nation=" + nation + ", productDate=" + productDate + "]";
// }
//

// @Override ---> 해시코드 메소드 까지 모두 한것... 마우스 우클릭 소스 -> toString 변환.. 보통 그냥 필드값만 오버라이딩 하면 된다.
// public String toString() {
// return "Machine01 [company=" + company + ", model=" + model + ", color=" + color + ", price=" + price
// + ", nation=" + nation + ", productDate=" + productDate + ", sound()=" + sound() + ", getClass()="
// + getClass() + ", hashCode()=" + hashCode() + ", toString()=" + super.toString() + "]";
// }

}


package ch07;

//이 클래스는 기계 관련 실행클래스이다.
public class Machine01_Main {

public static void main(String[] args) {
    Machine01 machine1 = new Machine01("넥슨", "nms1", "red", 350000, "korea", "2012-02-03");
    Machine01 machine2 = new Machine01("튼튼제조회사", "md1", "white", 300000, "korea", "2000-01-01");
    System.out.println();

// System.out.println(mc.company);

    //필드와 메소드 확인

// System.out.println(machine1);
System.out.println(machine1.toString());
System.out.println();
System.out.println(machine2.toString());

    machine1.powerOn();
    System.out.println(machine1.sound() ); // 앞에 메소드보면 리턴 값으로 스트링 문자열을 주기 때문에 이것을 따로 프린트문으로 찍어줘야 한다.
    machine1.powerOff();

    System.out.println(); // 줄바꿈





    System.out.println("-------아래는 Phone01 추가내용 출력------"); // 줄바꿈
    //클래스타입 참조변수 = new 클래스명();
    //매개변수가 있는 생성자호출
    Phone01 phone1 = new Phone01();
    phone1.setInfo("넥슨", "nms1", "red", 350000, "korea", "2012-02-03");
    phone1.setTelecom("kt");
    Phone01 phone2 = new Phone01();
    phone2.setInfo("넥슨", "nms2", "ivory", 120000, "china", "2012-12-12");
    phone2.setTelecom("sk");
    System.out.println();
    System.out.println(phone1.toString()+", [유선통신사]="+phone1.getTelecom());

// System.out.println(phone1.toString()+", [유선통신사]="+phone1.telecom);
System.out.println();
System.out.println(phone2.toString()+", [유선통신사]="+phone2.getTelecom());
// System.out.println(phone2.toString()+", [유선통신사]="+phone2.telecom);

    phone1.makeCall();
    phone1.receiveCall();

    System.out.println(); // 줄바꿈

    System.out.println("-------아래는 SmartPhone01 추가내용 출력------"); // 줄바꿈

    SmartPhone01 sp1 = new SmartPhone01();

    sp1.setInfo("삼성", "갤럭시5", "black", 500000, "korea", "2022-01-01");

// sp1.telecom="kt";
sp1.setTelecom("kt");
// sp1.OS="안드로이드"; 같은 클래스가 아니면 인식 못함
sp1.setOS("안드로이드");

    SmartPhone01 sp2 = new SmartPhone01();
    sp2.setInfo("삼성", "갤럭시6", "white", 700000, "korea", "2022-02-01");

// sp2.telecom="lgt";
sp2.setTelecom("lgt");
// sp2.OS="안드로이드"; 같은 클래스가 아니면 인식 못함
sp2.setOS("안드로이드");

    System.out.println();
    System.out.println(sp1.toString()+", [OS]="+sp1.getOS()+", [무선통신사]="+sp1.getTelecom());
    System.out.println();
    System.out.println(sp2.toString()+", [OS]="+sp2.getOS()+", [무선통신사]="+sp2.getTelecom());



    sp1.sendMessage("안녕하세요. 반갑습니다.");
    sp1.receiveMessage();
    sp1.useInternet();
    sp1.cameraOn();
    sp1.cameraOn();
    System.out.println(sp1.cameraSound());
    System.out.println(sp1.sound());

    System.out.println();
    System.out.println();

    System.out.println("***** 기계=new 전화기 ==============");
    //기계 mc = new 전화기();
    Machine01 machine3 = new Phone01(); //-->한마디로 이경우 머신 안에 Phone이 속하기 때문에 상속받아온 값들이 출력되거나 상속받아 재정의한 값들이 출력된다.
    machine3.powerOn();// 이것은 Machine01에서 상속받아서 Phone01에서 그대로 쓴 메소드.
    System.out.println(machine3.sound() ); //  Phone01에 재정의된  sound가 호출된다.
    machine3.powerOff();// 이것은 Machine01에서 상속받아서 Phone01에서 그대로 쓴 메소드.
    //machine3.makeCall();// ---X
    //The method makeCall() is undefined for the type Machine01       makeCall이라는 메소드는 Machine에 정의되지 않았다.
    // 즉 Machine01 machine3 = new Phone01(); 이말은 Phone을 기준으로 출력하되 Machine 클래스에 정의가 되어있는 것들이어야 한다는 얘기도 된다.
    // 기계 Machine01클래스에서 makeCall();은 선언되지 않았는데 호출하려니 에러발생
    // ==>makeCall()은 Phone01만 가진 기능이고 기계 Machine01클래스에서 정의된 기능이 아니기 때문이다.
    // Machine01클래스에만 있거나 (물론 이건 상속받아서 굳이 정의 하지 않아도 있기 때문에 가능한 듯)둘 다 있거나 하는건 되는데 Phone01에만 있는건 안되는 논리



    System.out.println("***** 전화기=new 스마트폰 ==============");
    //기계 mc = new 전화기();
    Phone01 phone3 = new SmartPhone01(); //-->한마디로 이경우 머신 안에 Phone이 속하기 때문에 상속받아온 값들이 출력되거나 상속받아 재정의한 값들이 출력된다.
    phone3.powerOn();// 이것은 Machine01에서 상속받아서 Phone01에서 그대로 쓴 메소드.
    System.out.println(phone3.sound() ); //  Phone01에 재정의된  sound가 호출된다.
    phone3.powerOff();// 이것은 Machine01에서 상속받아서 Phone01에서 그대로 쓴 메소드.
    //phone3.cameraOn();// ---X
    //The method cameraOn() is undefined for the type Phone01      cameraOn이라는 메소드는 Phone01에 정의되지 않았다.
    // 즉 Phone01 phone3 = new SmartPhone01(); 이말은 SmartPhone01을 기준으로 출력하되 Phone01클래스에 정의가 되어있는 것들이어야 한다는 얘기도 된다.
    // 기계 Phone01클래스에서 cameraOn();은 선언되지 않았는데 호출하려니 에러발생
    // ==>cameraOn()은 SmartPhone01만 가진 기능이고 전화 Phone01클래스에서 정의된 기능이 아니기 때문이다.
    // Phone01클래스에만 있거나 (물론 이건 상속받아서 굳이 정의 하지 않아도 있기 때문에 가능한 듯)둘 다 있거나 하는건 되는데 SmartPhone01에만 있는건 안되는 논리



    System.out.println("***** 기계=new 스마트폰 ==============");
    //기계 mc = new 전화기();
    Machine01 machine4 = new SmartPhone01(); //-->한마디로 이경우 머신 안에 Phone이 속하기 때문에 상속받아온 값들이 출력되거나 상속받아 재정의한 값들이 출력된다.
    machine4.powerOn();// 이것은 Machine01에서 상속받아서 SmartPhone01에서 그대로 쓴 메소드.
    System.out.println(machine4.sound() ); //  SmartPhone01에 재정의된  sound가 호출된다.
    machine4.powerOff();// 이것은 Machine01에서 상속받아서 SmartPhone01에서 그대로 쓴 메소드.

// machine4.makeCall();// ---X 출발지 Machine01에 정의되지 않은 것들은 에러... Phone01에만 있음
// machine4.cameraOn();// ---X 출발지 Machine01에 정의되지 않은 것들은 에러... SmartPhone01에만 있음

    // 출력되려면 최상위 클래스에 선언된 메소드는 에러가 안나면서 new로 정의된 클래스 기준으로 출력이 되는데
    //최상위 클래스에 아예 선언되지 않은 메소드는 에러가 나버리면서 끝!


}

}


package ch07;

public class Phone01 extends Machine01 {
//field
private String telecom;
//나머지는 상속

//constructor

// Phone01(String company, String model, String color, int price, String nation, String productDate){
// this.company=company;
// this.model=model; 생성자 선언 안됨 private로
// this.color=color;
// this.price=price;
// this.nation=nation;
// this.productDate=productDate;
// this.telecom=telecom;
// }

//method
public void setTelecom(String telecom) {
    this.telecom=telecom;
}
public String getTelecom() {
    return telecom;
}

//전원을 켜다
public void makeCall(){
    System.out.println("전화를 겁니다.");
}

//전원을 끄다
public void receiveCall(){
    System.out.println("전화를 받습니다.");
}

@Override
public String sound(){
    return "전화 벨 사운드 : 따르르르릉.";
}

// public static void main(String[] args) {
// //클래스타입 참조변수 = new 클래스명();
// //매개변수가 있는 생성자호출
// Phone01 phone1 = new Phone01();
// phone1.setInfo("넥슨", "nms1", "red", 350000, "korea", "2012-02-03");
// phone1.telecom="kt";
// Phone01 phone2 = new Phone01();
// phone2.setInfo("넥슨", "nms2", "ivory", 120000, "china", "2012-12-12");
// phone2.telecom="sk";
// System.out.println();
//// System.out.println(phone1.toString()+", [유선통신사]="+phone1.getTelecom());
// System.out.println(phone1.toString()+", [유선통신사]="+phone1.telecom);
// System.out.println();
//// System.out.println(phone2.toString()+", [유선통신사]="+phone2.getTelecom());
// System.out.println(phone2.toString()+", [유선통신사]="+phone2.telecom);
//
//
// phone1.makeCall();
// phone1.receiveCall();
//
// }

}


package ch07;

public class SmartPhone01 extends Phone01 {
//필드
private String OS;
private String a;

//생성자






//메소드
public void setOS(String OS) {
    this.OS=OS;
}
public String getOS() {
    return OS;
}



//문자를 보낸다.
public void sendMessage(String a){
    this.a = a; 
    System.out.print("\""+this.a+"\""+" 내용으로 "); //   \" 으로 쓰면 "이 출력된다.
    System.out.println("문자를 보냈습니다.");
}

//문자를 받는다
public void receiveMessage(){
    System.out.println("문자를 받았습니다.");
}

//인터넷을 사용한다.
public void useInternet(){
    System.out.println("인터넷을 사용합니다.");
}

//카메라를 켭니다.
public void cameraOn(){
    System.out.println("카메라를 켭니다.");
}

//카메라를 끕니다.
public void cameraOff(){
    System.out.println("카메라를 끕니다.");
}

//카메라로 사진을 찍습니다.
public String cameraSound(){
    return "찰칵~~~";
}

//sound() // 소리가 울린다() -->오버라이딩
@Override
public String sound(){
return "스마트폰 진동 사운드 : 위잉 위잉 위잉 위잉.";
}

// public static void main(String[] args) {
//
// SmartPhone01 sp1 = new SmartPhone01();
//
// sp1.setInfo("삼성", "갤럭시5", "black", 500000, "korea", "2022-01-01");
//// sp1.telecom="kt";
// sp1.setTelecom("kt");
// sp1.OS="안드로이드";
//
// SmartPhone01 sp2 = new SmartPhone01();
// sp2.setInfo("삼성", "갤럭시6", "white", 700000, "korea", "2022-02-01");
//// sp2.telecom="lgt";
// sp1.setTelecom("lgt");
// sp2.OS="안드로이드";
//
//
// System.out.println();
// System.out.println(sp1.toString()+", [OS]="+sp1.OS+", [무선통신사]="+sp1.getTelecom());
// System.out.println();
// System.out.println(sp2.toString()+", [OS]="+sp2.OS+", [무선통신사]="+sp2.getTelecom());
//
//
//
// sp1.sendMessage("안녕하세요. 반갑습니다.");
// sp1.receiveMessage();
// sp1.useInternet();
// sp1.cameraOn();
// sp1.cameraOn();
// System.out.println(sp1.cameraSound());
// System.out.println(sp1.sound());
//
//
// }

}

 

최종적으로 정리하면 

상위 클래스에 있는 메소드면 상위클래스것을 그냥 상속받아 그대로 쓰게되고

상위클래스와 하위클래스에 동일한 이름으로 있는 메소드가 있으면 하위클래스가 상속받아서 재정의된 Override메소드 값이 출력된다.

 

상위클래스타입 참조변수 = new 하위클래스타입();

 

참조변수.상위클래스메소드();  --> 상위클래스에 있는 메소드 실행;(하위클래스에는 없음;)

 

참조변수.하위,상위 모두있는 메소드();   -->하위클래스에 있는 오버라이딩 된 메소드 실행;(하위클래스, 상위클래스 모두 있음)