<1교시 ch07>
상속 (project3에서 사용될 예정)
--> 부모클래스의 수정하면 모든 자식 클래스도 수정됨
--> 자식이 부모를 선택
--> class 자식클래스 extends 부모클래스 { }
[p311~313 예제]
package ex01;
public class CellPhone { // 부모클래스
// 필드
String model;
String color;
// 생성자
// 메소드
void powerOn() {
System.out.println("전원을 켭니다.");
}
void powerOff() {
System.out.println("전원을 끕니다.");
}
void bell() {
System.out.println("벨이 울립니다.");
}
void sendVoice(String message) {
System.out.println("자기: " + message);
}
void receiveVoice(String message) {
System.out.println("상대방: " + message);
}
void hangup() {
System.out.println("전화를 끊습니다.");
}
}
package ex01;
public class DmbCellPhone extends CellPhone { // 자식클래스
//필드
int channel;
//생성자(매개변수 3개를 이용한 생성자 --> 전역변수 처리해야함)
DmbCellPhone(String model, String color, int channel) {
this.model = model; // 상속
this.color = color; // 상속
this.channel = channel;
}
//메소드
void turnOnDmb() {
System.out.println("채널 " + channel + "번 DMB 방송 수신을 시작합니다.");
}
void changeChannelDmb(int channel) {
this.channel = channel;
System.out.println("채널 " + channel + "번으로 바꿉니다.");
}
void turnOffDmb() {
System.out.println("DMB 방송 수신을 멈춥니다.");
}
}
package ex01;
public class CellTest {
public static void main(String[] args) {
//DmbCellPhone(자식) 객체 생성
DmbCellPhone d = new DmbCellPhone("자바폰", "검정", 10);
// CellPhone(부모) 클래스로부터 상속받은 필드
System.out.println("모델: " + d.model);
System.out.println("색상: " + d.color);
// DmbCellPhone(자식) 클래스의 필드
System.out.println("채널: " + d.channel);
//CellPhone(부모) 클래스로부터 상속받은 메소드 호출
d.powerOn(); // 출력구문 : 전원을 켭니다.
d.bell(); // 출력구문 : 벨이 울립니다.
d.sendVoice("여보세요");
d.receiveVoice("안녕하세요! 저는 홍길동인데요.");
d.sendVoice("아~ 예 반갑습니다.");
d.hangup(); // 출력구문 : 전화를 끊습니다.
//DmbCellPhone(자식) 클래스의 메소드 호출
d.turnOnDmb(); // 출력구문 : 채널 10번 DMB 방송 수신을 시작합니다.
d.changeChannelDmb(12); // 출력구문 : 채널 12번으로 바꿉니다.
d.turnOffDmb(); // 출력구문 : DMB 방송 수신을 멈춥니다.
}
}
부모생성자 --> 자식 기본생성자 맨 첫줄에 호출
public DmbCellPhone() {
super( ); --> 부모한테 상속받은거기때문에 this보다 한단계 위인 super 사용(부모로부터 생성하겠다)
}
[p315~316 예제]
package ex01;
public class People { // 부모
public String name;
public String ssn;
// 매개변수 2개 이용한 생성자
public People(String name, String ssn) {
this.name = name;
this.ssn = ssn;
}
}
package ex01;
public class Student extends People { // 자식
public int studentNo;
// 매개변수 3개를 이용한 생성자
public Student(String name, String ssn, int studentNo) {
super(name, ssn); // this() 함수 이용해 부모 생성자 호출
this.studentNo = studentNo;
}
@Override
public String toString() {
return "Student [studentNo=" + studentNo + "]";
}
}
package ex01;
public class StudentTest {
public static void main(String[] args) {
// 자식 Student 객체 생성
Student s = new Student("홍길동", "123456-1234567", 1);
// 부모 필드
System.out.println("이름: " + s.name);
System.out.println("주민번호: " + s.ssn);
// 자식 필드
System.out.println("학년: " + s.studentNo);
}
}
<2교시>
model(칼럼, 등등)
메소드 재정의(오버라이딩) : 부모메소드를 자식클래스에서 재정의
ㄴ> 일반 : toString( )
ㄴ> 상속 경우 : override ( 우클릭 > source > override )
[p318~319 예제]
package sec01.exam03;
public class Cal {
double ac(double r) { // return 안적으면 오류남
System.out.println("Cal 클래스 객체의 ac() 실행");
return 3.14*r*r; //3.14159 원의 넓이
}
}
package sec01.exam03;
public class Com extends Cal {
@Override // 재정의
double ac(double r) {
System.out.println("Com 클래스 객체의 ac() 실행");
return Math.PI*r*r;
}
}
package sec01.exam03;
import java.util.ArrayList;
import java.util.List;
public class ComTest {
public static void main(String[] args) {
int r = 10;
// 부모 클래스로부터 부모 생성자를 이용한 객체 생성
Cal c = new Cal();
System.out.println("원면적: " + c.ac(r));
System.out.println();
// 자식 클래스로부터 자식 생성자를 이용한 객체 생성
Com c1 = new Com();
System.out.println("원면적: " + c1.ac(r));
System.out.println();
// 부모 클래스로부터 자식 생성자를 이용한 객체 생성(!!자식 따라감!!)
Cal c2 = new Com();
System.out.println("원면적: " + c2.ac(r));
// 자식 클래스로부터 부모 생성자를 이용한 객체 생성(사용X 오류남)
//Com c3 = new Cal();
}
}
부모메소드 호출 : super.부모메소드( ); --> 자식클래스에서
[p320~321 예제]
package sec01.exam03;
public class A { // 부모
public void land() {
System.out.println("착륙");
}
public void fly() {
System.out.println("일반비행");
}
public void takeOff() {
System.out.println("이륙");
}
}
package sec01.exam03;
public class B extends A{ //자식
public static final int NORMAL = 1; // 어디에서든 사용 가능
public static final int SUPPERSONIC = 2;
public int flyMode = NORMAL; // 객체.flyMode로 사용 가능
// 부모메소드를 쓴다면 normal, 자식메소드를 쓴다면 suppersonic
@Override
public void fly() {
if(flyMode == SUPPERSONIC) {
System.out.println("초음속 비행");
} else {
super.fly(); // 일반비행
}
}
}
package sec01.exam03;
public class BTest {
public static void main(String[] args) {
B b = new B();
b.takeOff();
b.fly();
b.flyMode = b.SUPPERSONIC;
b.fly();
b.flyMode = b.NORMAL;
b.fly();
b.land();
}
}
public final class
--> 클래스에 final이 있다면 상속 불가능
--> 클래스에 final 없는데 안에 final 메소드라면 상속 가능
<3교시>
[p330 Q05] --> 부모꺼 많 > 적 > 자식꺼 많 > 적 순으로 출력됨
package sec01.exam03;
public class P {
public String nation;
public P() {
this("대한민국");
System.out.println("P() 기본 생성자 이용");
}
public P(String nation) {
this.nation = nation;
System.out.println("P() 매개변수 생성자 이용");
}
}
package sec01.exam03;
public class C extends P{
private String name;
public C() {
this("홍길동");
System.out.println("C() 기본 생성자");
}
public C(String name) {
this.name = name;
System.out.println("C() 매개변수 이용한 생성자");
}
}
package sec01.exam03;
public class CTest {
public static void main(String[] args) {
C c = new C();
}
}
/* 출력구문
P() 매개변수 생성자 이용
P() 기본 생성자 이용
C() 매개변수 이용한 생성자
C() 기본 생성자
*/
다형성
--> 하나의 타입으로 여러 객체를 대입해 여러 결과를 얻어내는 성질
--> 메소드 재정의 + 타입변환
타입변환(--> 실행용 Test 클래스에서) : 멤버들에 대한 사용범위가 달라짐!! * 클래스 변환 : 상속관계에 있는 클래스끼리
1) 자동타입변환
--> 자식은 부모타입 변수로 자동변환됨
--> 부모타입 변수 = 자식타입;
--> 변환 후 : 부모에 선언된 필드와 메소드만 사용 가능
--> 필요한 이유 ; 다형성(필드타입을 부모타입을 선언하면 다양한 자식 객체들 저장 가능하기 때문)
2) 강제타입변환
--> 부모타입을 자식타입으로 변환하는 것
--> 이미 자동변환으로 부모타입이 된 자식을 다시 자식타입으로 변환하기 위해 사용
--> 변환 후 : 자식에 선언된 필드 메소드 사용할 수 있음
--> 자식타입 변수명 = (자식타입) 부모타입;
Parent p = new Child(); // 자동타입변환( 부 = 자 )
Child c = (Child) parent; // 강제타입변환 ( 자 = (자)부 )
[p334 예제]
package ex02;
public class A {
}
package ex02;
public class B extends A {
}
package ex02;
public class C extends A {
}
package ex02;
public class D extends B {
}
package ex02;
public class E extends C {
}
package ex02;
public class Test {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
E e = new E();
A a1 = b; // 부모클래스 타입으로 자식생성자됨
// B b1 = e; 직계 아니므로 오류(부모, 형제, 조카 등 안됨)
int x = 1;
int y = x;
}
}
[p336 예제]
package ex02;
public class Parent {
public void m1() { // 리턴 X
System.out.println("Parent-m1()");
}
public void m2() { // 리턴 X
System.out.println("Parent-m2()");
}
}
package ex02;
public class Child extends Parent {
@Override
public void m2() { // 재정의
System.out.println("Child-m2()");
}
public void m3() {
System.out.println("Child-m3()");
}
}
package ex02;
public class ChildTest {
public static void main(String[] args) {
Child c = new Child(); // 자식클래스 타입으로 자식생성자 이용
c.m1();
c.m2(); // 내꺼 재정의된 메소드
c.m3();
System.out.println();
Parent p = new Child(); // 부모클래스 타입으로 자식생성자 이용
p.m1();
p.m2(); // 자식 생성자 따라감 (재정의한 메소드)
// p.m3(); 호출 불가능
System.out.println();
Parent p1 = new Parent();
p1.m1();
p1.m2();
}
}
/* 출력
Parent-m1()
Child-m2()
Child-m3()
Parent-m1()
Child-m2()
Parent-m1()
Parent-m2()
*/
<4교시>
필드의 다형성
[p339~345 예제]
package ex03;
public class Tire {
//필드
int maxRotation; // 최대회전수(타이어수명)
int accumulatedRotation; // 누적회전수
String location; // 타이어의 위치
//생성자
public Tire(String location, int maxRotation) { // 초기화
this.location = location;
this.maxRotation = maxRotation;
}
//메소드
public boolean roll() {
++accumulatedRotation; // 누적회전수 1씩 증가
if(accumulatedRotation<maxRotation) {
System.out.println(location + " Tire 수명: " + (maxRotation-accumulatedRotation) + "회");
return true;
} else {
System.out.println("=== " + location + " Tire 펑크 ===");
return false;
}
}
}
package ex03;
public class Car {
//필드
Tire fl = new Tire("앞왼쪽", 6);
Tire fr = new Tire("앞오른쪽", 2);
Tire bl = new Tire("뒤왼쪽", 3);
Tire br = new Tire("뒤오른쪽", 4);
//생성자
//메소드
int run() {
System.out.println();
System.out.println("[자동차가 달립니다]");
if(fl.roll()==false) {
stop(); return 1; // return 값 = 타이어 번호
}
if(fr.roll()==false) {
stop(); return 2;
}
if(bl.roll()==false) {
stop(); return 3;
}
if(br.roll()==false) {
stop(); return 4;
}
return 0;
}
void stop() {
System.out.println("[자동차가 멈춥니다]");
}
}
package ex03;
public class HanTire extends Tire { // 한국타이어
//필드
//생성자
public HanTire(String location, int maxRotation) {
super(location, maxRotation); // 상속
}
//메소드
@Override
public boolean roll() {
++accumulatedRotation;
if(accumulatedRotation<maxRotation) {
System.out.println(location + " 한국타이어수명: " + (maxRotation-accumulatedRotation) + "회");
return true;
} else {
System.out.println("=== " + location + " 한국타이어 펑크 ===");
return false;
}
}
}
package ex03;
public class KumTire extends Tire { //금호타이어
//필드
//생성자
public KumTire(String location, int maxRotation) {
super(location, maxRotation); // 상속
}
//메소드
@Override
public boolean roll() {
++accumulatedRotation;
if(accumulatedRotation<maxRotation) {
System.out.println(location + " 금호타이어수명: " + (maxRotation-accumulatedRotation) + "회");
return true;
} else {
System.out.println("=== " + location + " 금호타이어 펑크 ===");
return false;
}
}
}
package ex03;
public class CarTest {
public static void main(String[] args) {
Car c = new Car(); // 차 뽑음(객체생성)
for(int i=1; i<=5;i++) {
int problemLocation = c.run();
switch(problemLocation) {
case 1:
System.out.println("앞왼쪽 한국타이어로 교체");
c.fl = new HanTire("앞왼쪽",15);
break;
case 2:
System.out.println("앞오른쪽 금호타이어로 교체");
c.fr = new KumTire("앞오른쪽",13);
break;
case 3:
System.out.println("뒤왼쪽 한국타이어로 교체");
c.bl = new HanTire("뒤왼쪽",14);
break;
case 4:
System.out.println("뒤오른쪽 금호타이어로 교체");
c.br = new KumTire("뒤오른쪽",17);
break;
}
System.out.println("--------------------------");
}
}
}
/* 출력구문
[자동차가 달립니다]
앞왼쪽 Tire 수명: 5회
앞오른쪽 Tire 수명: 1회
뒤왼쪽 Tire 수명: 2회
뒤오른쪽 Tire 수명: 3회
--------------------------
[자동차가 달립니다]
앞왼쪽 Tire 수명: 4회
=== 앞오른쪽 Tire 펑크 ===
[자동차가 멈춥니다]
앞오른쪽 금호타이어로 교체
--------------------------
[자동차가 달립니다]
앞왼쪽 Tire 수명: 3회
앞오른쪽 금호타이어수명: 12회
뒤왼쪽 Tire 수명: 1회
뒤오른쪽 Tire 수명: 2회
--------------------------
[자동차가 달립니다]
앞왼쪽 Tire 수명: 2회
앞오른쪽 금호타이어수명: 11회
=== 뒤왼쪽 Tire 펑크 ===
[자동차가 멈춥니다]
뒤왼쪽 한국타이어로 교체
--------------------------
[자동차가 달립니다]
앞왼쪽 Tire 수명: 1회
앞오른쪽 금호타이어수명: 10회
뒤왼쪽 한국타이어수명: 13회
뒤오른쪽 Tire 수명: 1회
--------------------------
*/
<5~6교시>
[예제]
package ex04;
public class Student {
//필드
String name; // 학생이름
int money; // 가진 돈
//생성자
public Student(String name, int money) {
this.name = name;
this.money = money;
}
public void takeBus(Bus b) {
this.money -= b.busmoney; // 버스비 지출
b.take(); // 버스 탑승
}
public void takeSubway(Subway s) {
this.money -= s.subwaymoney; // 지하철비 지출
s.take(); // 지하철 탑승
}
public void takeTaxi(Taxi t, int tm) { //택시정보, 택시비
this.money -= tm;
t.take(tm); // 택시비내고 탑승
}
//메소드
@Override
public String toString() {
return "Student [이름: " + name + ", 잔액: " + money + "]";
}
}
package ex04;
public class Bus {
//필드
int busNumber; // 버스 번호
int passCount; // 승객 수
int money; // 버스 수입
int busmoney = 1300; // 버스비
//생성자
public Bus(int busNumber) {
this.busNumber = busNumber;
}
public void take() { //take 함수 이용
this.money += busmoney; // 버스수입
this.passCount++; // 승객수 +1 처리
}
//메소드
@Override
public String toString() {
return "Bus [버스번호: " + busNumber + ", 승객수: " + passCount + ", 버스수입: " + money + ", 버스비: " + busmoney + "]";
}
}
package ex04;
public class Subway {
String subwayNumber; //지하철호선
int passCount; // 승객수
int money; //지하철 수입
int subwaymoney = 1500; // 지하철비
public Subway(String subwayNumber) {
this.subwayNumber = subwayNumber;
}
public void take() {
this.money += subwaymoney; // 지하철 수입
this.passCount ++; // 승객수 +1 처리
}
@Override
public String toString() {
return "Subway [호선: " + subwayNumber + ", 승객수:" + passCount + ", 지하철수입: " + money
+ ", 지하철비: " + subwaymoney + "]";
}
}
package ex04;
public class Taxi {
String taxiNumber; // 택시 번호
int passCount; // 승객수
int money; // 택시비 수입
public Taxi(String taxiNumber) {
this.taxiNumber = taxiNumber;
}
public void take(int tm) {
this.money += tm; // 택시 수입
this.passCount ++; // 승객수 +1 처리
}
@Override
public String toString() {
return "Taxi [택시번호: " + taxiNumber + ", 승객수: " + passCount + ", 택시수입: " + money +
"]";
}
}
package ex04;
public class Test {
public static void main(String[] args) {
System.out.println("[승객 정보]");
Student s1 = new Student("홍길동", 10000);
Student s2 = new Student("홍길영", 12000);
Student s3 = new Student("홍길투", 30000);
System.out.println(s1.toString()); // s1 승객 정보
System.out.println(s2.toString()); // s2 승객 정보
System.out.println(s3.toString()); // s3 승객 정보
System.out.println("=============================================");
System.out.println("[버스]");
//////////////////////////////////////
Bus b148 = new Bus(148); // 148번 버스 생성
s1.takeBus(b148); // s1 승객 버스 탐
System.out.println(b148.toString()); // 148번 버스 정보
System.out.println(s1.toString()); // s1 승객 정보
System.out.println("=============================================");
System.out.println("[버스]");
/////////////////////////////////////////////////
Bus b42 = new Bus(42); // 42번 버스 생성
s1.takeBus(b42); // s1 버스 탐
s2.takeBus(b42); // s2 버스 탐
System.out.println(b42.toString()); // 42번 버스 정보
System.out.println(s1.toString()); // s1 승객 정보
System.out.println(s2.toString()); // s2 승객 정보
System.out.println("=============================================");
System.out.println("[지하철]");
////////////////////////////////////////////////
Subway sub4 = new Subway("4호선");
s2.takeSubway(sub4);
System.out.println(sub4.toString()); // 4호선 정보
System.out.println(s1.toString()); // s1 승객 정보
System.out.println(s2.toString()); // s2 승객 정보
System.out.println("=============================================");
System.out.println("[택시]");
////////////////////////////////////////////////
Taxi t1 = new Taxi("12가1234");
s3.takeTaxi(t1, 15000);
System.out.println(t1.toString()); // 택시 정보
System.out.println(s1.toString()); // s1 승객 정보
System.out.println(s2.toString()); // s2 승객 정보
System.out.println(s3.toString()); // s3 승객 정보
System.out.println("=============================================");
System.out.println("[택시]");
////////////////////////////////////////////////
Taxi t2 = new Taxi("35가3214");
s3.takeTaxi(t2, 3400);
System.out.println(t2.toString()); // 택시 정보
System.out.println(s1.toString()); // s1 승객 정보
System.out.println(s2.toString()); // s2 승객 정보
System.out.println(s3.toString()); // s3 승객 정보
}
}
<7교시>
매개변수의 다형성
[p345~347 예제]
package ex05;
public class Vehicle {
public void run() {
System.out.println("차량 달려");
}
}
package ex05;
public class Driver {
public void drive(Vehicle v) {
v.run();
}
}
package ex05;
public class Bus extends Vehicle {
@Override
public void run() {
System.out.println("버스 달려");
}
}
package ex05;
public class Taxi extends Vehicle {
@Override
public void run() {
System.out.println("택시 달려");
}
}
package ex05;
public class Test {
public static void main(String[] args) {
Driver d = new Driver();
Bus b = new Bus();
Taxi t = new Taxi();
d.drive(b); // 부모 클래스 타입(Vehicle)으로 자식생성자 이용
d.drive(t); // 부모 클래스 타입(Vehicle)으로 자식생성자 이용
}
}
package ex05;
public class Test2 {
public static void main(String[] args) {
Driver d = new Driver(); // 내가 만든 객체
Vehicle t = new Taxi();
Vehicle b = new Bus();
Taxi t1 = (Taxi)t; // 강제타입변환
d.drive(t);
d.drive(b);
}
public void drive(Vehicle v) { // 다형성
v.run();
}
}
객체타입확인 : instanceof 연산자 이용
'JAVA > jsp' 카테고리의 다른 글
230116 (0) | 2023.01.16 |
---|---|
230113_추상클래스, 인터페이스(jsp 시작) (0) | 2023.01.13 |
230111_멤버(필,생,메), 오버로딩, 접근제한자 (0) | 2023.01.11 |
230110_참조, 배열, 객체, 필드 (0) | 2023.01.10 |
230109_삼항연산자, 조건문, 반복문,은행 (0) | 2023.01.09 |