package superCode;
import java.util.Scanner;

class Phone {
	String name, tel;
	public Phone(String name, String tel) {
		this.name = name;
		this.tel = tel;
	}
}

public class Phone_for {

	public static void main(String[] args) {
		System.out.print("인원수>>");
		Scanner scanner = new Scanner(System.in);
		int a = scanner.nextInt();
		Phone [] p;
		p = new Phone[a];
		
		for (int i = 0; i < p.length; i++) {
			System.out.print("이름과 전화번호(번호는 연속적으로 입력)>>");
			String name = scanner.next();
			String tel = scanner.next();
			p[i] = new Phone(name, tel);
		}
		System.out.println("저장되었습니다...");
		for (int j = 0; true; j++) {
			System.out.print("검색할 이름>>");
			String b = scanner.next();
          if (b.equals("exit")) {
                System.out.println("프로그램을 종료합니다...");
                 break;
           }
              for(int i = 0 ; i < p.length; i++){
                  if (b.equals(p[j].name)) {
                          System.out.println(p[j].name + "의 번호는 " + p[j].tel);
                           break;
                  }
   
                   else  {
                         System.out.println(b + " 이 없습니다.");
                         break;
                    }

}
		}
		scanner.close();
	}

}

 

Student ( 필드, 총점, 평균, 제너레이터, Get, Set )

package score0602;

public class Student {
	// 필드
	private String name;
	private int kor;
	private int math;
	private int eng;
	private int tot;
	private int avg;
	
	//총점 메소드
	public int total() {
		return kor + math + eng;
	}
	
	//평균
	public double avg() {
		return total() / 3.0;
	}
	
	
	@Override // 제너레이터 to string
	public String toString() {
		return "Student [name=" + name + ", kor=" + kor + ", math=" + math + ", eng=" + eng + ", tot=" + tot + ", avg="+ avg + "]";
	}
	//생성자
	public Student() {}
	public Student(String name, int kor, int math, int eng) {
		
	this.name = name;
	this.kor = kor;
	this.math = math;
	this.eng = eng;
	}
	
	//Get,Set
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getKor() {
		return kor;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	public int getMath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}
	public int getEng() {
		return eng;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}
	public int getTot() {
		return tot;
	}
	public void setTot(int tot, int kor, int math, int eng) {
		this.tot = ( kor + math + eng);
	}
	public int getAvg() {
		return getAvg();
	}
	public void setAvg(int avg) {
		this.avg = avg;
	}
	
	
	
	
}

 

 

싱글톤 ( 최고 점수,이름, 향상된 for문 ) 

package score0602;

public class Singleton {
	//최고 점수/이름 필드 생성
	public String korKingName;
	public String mathKingName;
	public String engKingName;
	
	public int korKingScore;
	public int mathKingsScore;
	public int engKingScore;
	
	//이름으로 성적 검색
	public Student search(String name) {
		for (Student student : students) {
			if(name.equals(student.getName())) {
				return student;
			}
		}
		return null;
	}
	
	//최고 점수/이름 메서드 
	public void makeKing() {
		for (Student student : students) {
			if (korKingScore < student.getKor()) {
				korKingScore = student.getKor();
				korKingName = student.getName();
			}
		}
		for (Student student : students) {
			if (mathKingsScore < student.getMath()) {
				mathKingsScore = student.getMath();
				mathKingName = student.getName();
			}
		}
		for (Student student : students) {
			if (engKingScore < student.getEng()) {
				engKingScore = student.getEng();
				engKingName = student.getName();
			}
		}
	}
	
	// 클래스 배열
	Student[] students = new Student[3]; 
	
	//생성자
	private static Singleton st = new Singleton();
	
	
	


	private Singleton() {
		// 학생  클래스 배열의 객체를 생성
		for(int i=0; i< students.length; i++) {
			students[i] = new Student();
		}
	}
	
	//메소드 
	public static Singleton getInstance() {
		return st;
	}
	
	
}

 

실행

package score0602;

import java.util.Scanner;

public class ScoreEx {

	public static void main(String[] args) {
		boolean run = true;
		
		Scanner sc = new Scanner(System.in);
		Singleton st = Singleton.getInstance();
//		for (int i=0; i < st.students.length; i++) {
//			//임시 자료 더미코드
//			 st.students[i].setName("김"+i);
//			int score =(int) (Math.random()*100 + 1);
//			 st.students[i].setKor(score);
//			 score =(int) (Math.random()*100 + 1);
//			 st.students[i].setMath(score);
//			 score =(int) (Math.random()*100 + 1);
//			 st.students[i].setEng(score);
//
//		}
		for(int i=0; i <st.students.length; i++) {
			System.out.print(i+1+"번 학생 이름>");
			String name = sc.nextLine();
			st.students[i].setName(name);
			// 국어 점수 입력
			System.out.print(i+1+"번 학생 국어 점수>");
			int kor = Integer.parseInt(sc.nextLine());
			st.students[i].setKor(kor);
			// 수학 점수 입력
			System.out.print(i+1+"번 학생 수학 점수>");
			int math = Integer.parseInt(sc.nextLine());
			st.students[i].setMath(math);
			// 영어 점수 입력
			System.out.print(i+1+"번 학생 영어 점수>");
			int eng = Integer.parseInt(sc.nextLine());
			st.students[i].setEng(eng);
			
		}
			for(Student student : st.students) {
				System.out.println(student);

			}
			while(run) { // 무한루프
				System.out.println("-----------------------------------------------");
				System.out.println("1.학생별 총점/평균 2.과목별 최고 점수/이름 3.이름으로 성적 검색 4.종료");
				System.out.println("-----------------------------------------------");
				int num = Integer.parseInt(sc.nextLine());
				switch(num) {
				case 1: // 1. 학생별 총점/평균
					System.out.println("이름\t국어\t수학\t영어\t총점\t평균");
					System.out.println("---------------------------------------------");
//					배열에 저장된 학생 객체를 하나씩 가져와서 반복문의 코드 블록을 실행하는 역할
					for(Student student : st.students) {
						System.out.printf("%s\t%d\t%d\t%d\t%d\t%f\n",
								student.getName(), student.getKor(),
								student.getMath(), student.getEng(),
								student.total(), student.avg());
					}
					System.out.println("---------------------------------------------");
					break;
					
				case 2: // 2.과목별 최고 점수/이름
					st.makeKing();// 싱글톤에서 작성한 for문 메서드 호출
					System.out.printf("국어 최고 점수: %d, 이름: %s\n",
							          st.korKingScore, st.korKingName);
					System.out.printf("수학 최고 점수: %d, 이름: %s\n",
									  st.mathKingsScore, st.mathKingName);
					System.out.printf("영어 최고 점수: %d, 이름: %s\n",
							          st.engKingScore, st.engKingName);
					break;
					
				case 3://3.이름으로 성적 검색
					System.out.print("이름입력>");
					String name = sc.nextLine();
					Student student = st.search(name);
					if(student != null) {
						System.out.println("이름\t국어\t수학\t영어\t총점\t평균");
						System.out.println("---------------------------------------------");
						System.out.printf("%s\t%d\t%d\t%d\t%d\t%f\n",
								student.getName(), student.getKor(),
								student.getMath(), student.getEng(),
								student.total(), student.avg());
						
					}System.out.println("정보가 없습니다.");
					
					break;
					
					
				case 4:
					run = false; // 루프 종료
				}
			}
			System.out.println("프로그램 종료");
		

	}

}

 

결과 ( 점수 입력  후 추가 메뉴 선택 )

 

결과 ( 1. 학생별 총점/ 평균 출력 )

 

결과 ( 2. 과목별 최고 점수/이름 )

 

결과 ( 3. 이름으로 성적 검색 )

 

부모 메소드 호출

자식 클래스에서 부모 클래스의 메소드를 재정의하게 되면, 부모 클래스의 메소드는 숨겨지고 재정의 된

자식 메소드만 사용됨

그러나 클래스 내부에서 재정의된 부모 클래스의 메소드를 호출해야 하는 상황이 발생한다면 명시적으로

super 키워드를 붙여서 부모 메소드를 호출할 수 있음

super.부모메소드();

 

super는 부모 객체를 참조하고 있기 때문에 부모 메소드에 직접 접근할 수 있음

 

실습 예제

열거 ( 상수 ) enum파일
package sec01.exam04;

public enum FLY {
	NORAML, SUPERSONIC
}
부모

package sec01.exam04;
// 부모
public class Airplane {
	public void land() {
		System.out.println("착륙합니다.");
	}
	public void fly() {
		System.out.println("일반비행합니다.");
	}
	public void takeOff(){
		System.out.println("이륙합니다.");
	}
}

 

자식 ( 상속 받음 ) 

package sec01.exam04;
//자식 ( 상속 받음 ) 
public class SupersonicAirplane extends Airplane {
	public FLY flymode = FLY.NORAML;//열거 
	
	//메소드 재정의
	//flyMode가 SUPERSONIC 상수값을 가질 경우에는 true값 실행
	public void fly() {
		if(flymode == FLY.SUPERSONIC) {//열거
			System.out.println("초음속비행합니다.");
		}else {
			super.fly();// 부모 객체의 fly()메소드 호출
		}
	}
	
}

 

실행

package sec01.exam04;

public class SuperEx {

	public static void main(String[] args) {
		SupersonicAirplane sa = new SupersonicAirplane();
		sa.takeOff();
		sa.fly();
		sa.flymode = FLY.SUPERSONIC; // 열거 
		sa.fly();
		sa.flymode = FLY.NORAML; // 열거
		sa.fly();
		sa.land();

	}

}

 

 

 

final 클래스와 final 메소드

final 키워드는 클래스, 필드, 메소드를 선언할 때 사용할 수 있음

해당 선언이 최종상태이고 결코 수정될 수 없음을 뜻함

final 키워드는 클래스, 필드, 메소드 선언에 사용될 경우 해석이 조금씩 달라짐

클래스와 메소드를 선언할 때 final 키워드가 지정되면 상속과 관련이 있다는 의미임\

 

상속할 수 없는 final 클래스

클래스를 선언할 때 final 키워드를 class 앞에 붙이면 이 클래스는 최종적인 클래스이므로 상속할

수 없는 클래스가 됨, 즉 final 클래스는 부모 클래스가 될 수 없어 자식 클래스를 만들 수 없다는 것

선언 방식
public final class 클래스 {...}

final 클래스의 대표적인 예는 자바 표준 API에서 제공하는 String 클래스임

 

재정의할 수 없는 final 메소드

메소드를 선언할 때 final 키워드를 붙이면 이 메소드는 최종적인 메소드이므로 재정의할 수 없는 메소드가 됨

부모 클래스를 상속해서 자식 클래스를 선언할 때 부모 클래스에 선언된 final 메소드는 자식 클래스에서

재정의할 수 없다는 것

public final 리턴타입 메소드 ( [매개변수, ...] ){ ... }

 

 

protected 접근 제한자

protected는 public과 default 접근 제한의 중간쯤에 해당

같은 패키지에서는 default와 같이 접근 제한이 없지만 다른 패키지에서는 자식 클래스만 접근을 허용

protected는 필드와 생성자, 메소드 선언에 사용될 수 있음

 

패키지 1 

package sec01.exam07.pack1;

public class A {

	protected String field;
	
	protected A() {
		
	}
	
	protected void method() {
		
	}
}
패키지 1

package sec01.exam07.pack1;

public class B {
	public void method() {// 접근가능
		A a = new A();
		a.field = "value";
		a.method(); 
	}
}
패키지 2

package sec01.exam07.pack2;

import sec01.exam07.pack1.A;

public class C  {
	public void method() {// 패키지  접근 불가
		
		
		// 생성자 호출 불가
//		A a = new A();
//		a.field = "value";
//		a.method(); 
	}
}
패키지 2

package sec01.exam07.pack2;

import sec01.exam07.pack1.A;

public class D extends A {
	public D() { // 상속으로 인해 접근 가능
		super();
		this.field = "value";
		this.method();
	}
	
}

 

타입 변환과 다형성

 

 

 

자동 타입 변환

타입 변환이란 타입을 다른 타입으로 변환하는 행위를 말함

자동 타입 변환은 프로그램 실행 도중에 자동적으로 타입 변환이 일어나는 것을 말함

클래스도 마찬가지로 타입 변환이 있는데, 클래스의 변환은 상속 관계에 있는 클래스 사이에서 발생

자식은 부모 타입으로 자동 타입 변환이 가능

 

자동 타입 변환의 개념은 자식은 부모의 특징과 기능을 상속받기 때문에 부모와 동일하게 취급될 수 있음

위에 예제에서 Cat 클래스로부터 Cat 객체를 생성하고 이것을 Animal 변수에 대입하면 자동 타입 변환이

일어남, 맨 마지막 예제는 메모리 상태를 그림으로 묘사한건데 cat과 animal 변수는 타입만 다를 뿐,

동일한 Cat 객체를 참조, 참조변수의 == 연산은 참조 번지가 같을 경우 true를 산출하므로 두 변수가

동일한 객체를 참조하고 있다는 뜻 

cat == animal true
부모
package sec01.verify.exam05;

public class Animal {
	
}

자식 1
package sec01.verify.exam05;

public class Cat extends Animal {

}

자식2
package sec01.verify.exam05;

public class Dog extends Animal {

}

실행 ( 다형성 )
package sec01.verify.exam05;

public class Ex1 {

	public static void main(String[] args) {
		// 다형성
		
		Animal a1 = new Cat();
		Animal a3 = new Dog();
		
//		Cat a1 = new Cat();
//		Animal a2 = a1;
//		
//		
//		Dog a3 = new Dog();
//		Animal a4 = a3;

	}

}

 

바로 위의 부모가 아니더라도 상속 계층에서 상위 타입이라면 자동 타입 변환이 일어날 수 있음

밑에 이미지 참고

다형성

package sec01.verify.exam05;
//다형성

class A{}

class B extends A {}
class C extends A {}

class D extends B {}
class E extends C {}
public class PromotionExample {

	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;
		A a2 = c;
		A a3 = d;
		A a4 = e;
		
		B b1 = d;
		C C = e;
		
		//B b3 = e;
		//C c2 = d; 
		//상속관계 아님 컴파일에러

	}

}

부모 타입으로 자동 타입 변환된 이후에는 부모 클래스에 선언된 필드와 메소드만 접근이 가능

비록 변수는 자식 객체를 참조하지만 변수로 접근 가능한 멤버는 부모 클래스 멤버로만 한정됨

그러나 예외가 있는데, 메소드가 자식 클래스에서 재정의되었다면 자식 클래스의 메소드가 대신 호출

Child 객체는 method3() 메소드를 가지고 있지만, Parent 타입으로 변환된 이후에는 method3()을

호출할 수 없음, 그러나 method2()메소드는 부모와 자식 모두에게 있습니다. 이렇게 재정의된 메소드는

타입 변환 이후에도 자식 메소드가 호출됨

부모

package sec01.verify.exam06;

public class Parent {
	public void method1() {
		System.out.println("Parent-method1()");
	}
	public void method2() {
		System.out.println("Parent-method2()");
	}
	
}

 

자식

package sec01.verify.exam06;

public class Child extends Parent {

	@Override // 재정의
	public void method2() {
		System.out.println("Child-method2()");
	}

	
	public void method3() {
		System.out.println("Child-method3()");
	}
	
}

 

실행

package sec01.verify.exam06;

public class ChildEx {

	public static void main(String[] args) {
		Child child = new Child();
//		Parent child = new Child();
		
		Parent parent = child; // 자동 형변환
		parent.method1();
		parent.method2();// 재정의된 메소드가 호출됨
//		parent.method3();// 호출 불가능
		
		// 강제 형변환
		Child ch = (Child) parent;
		ch.method3();
	}

}

 

 

필드의 다형성

필드의 타입을 부모타입으로 선언하면 다양한 자식 객체들이 저장될 수 있기 때문에 필드 사용 결과가

달라질 수 있다. 이것이 필드의 다형성 / 예) 자동차를 구성하는 부품

프로그램은 수많은 객체들이 서로 연결되고 각자의 역할을 하게 되는데, 이객체들은 다른 객체로 교체될 수

있어야 한다.

부모 클래스를 상속하는 자식 클래스는 부모가 가지고 있는 필드와 메소드를 가지고 있으니 사용 방법이 동일

할 것입니다. 자식클래스는 부모의 메소드를 재정의해서 메소드의 실행 내용을 변경함으로써 더 우수한 실행

결과가 나오게 할 수도 있습니다. 그리고 자식 타입을 부모 타입으로 변환할 수 있습니다.

 

public class Car {
	//필드
	Tire frontLeftTire = new Tire("앞왼쪽", 6);
	Tire frontRightTire = new Tire("앞오른쪽", 2);
	Tire backLeftTire = new Tire("뒤왼쪽", 3);
	Tire backRightTire = new Tire("뒤오른쪽", 4);
	
	//생성자
	
	//메소드
	int run() {
    frontLeftTire.roll();
    frontRightTire.roll();
    backLeftTire.roll();
    backRightTire.roll();
    }

Car 클래스로부터 Car 객체를 생성하면 4개의 Tire 필드에 각각 하나씩 Tire 객체가 들어가게 됩니다.

그런데  frontRightTire와 backLeftTire를 한국타이어와 금호타이어로 교체할 이유가 생겼습니다.

이러한 경우 밑에와 같은 코드를 사용해서 교체할 수 있습니다.

 

Car myCar = new Car();
myCar.frontRightTire = new HankookTire();
myCar.backLeftTire = new KumhoTire();
myCar.run();

Tire 클래스 타입인 frontRightTire와 backLeftTire는 원래 Tire 객체가 저장되어야 하지만, Tire의 자식 객체가 저장되어도 문제가 없습니다. 왜냐하면 자식 타입은 부모 타입으로 자동 타입 변환이 되기 때문입니다. frontRightTire와 backLeftTire에 Tire 자식 객체가 저장되어도 Car 객체는 Tire 클래스에 선언된 필드와

메소드만 사용하므로 전혀 문제가 되지 않습니다.

HankookTire와 KumhoTire는 부모인 Tire의 필드와 메소드를 가지고 있기 때문입니다.

Car 객체에 run()메소드가 있고, run()메소드는 각 Tire 객체의 roll() 메소드를 밑에 코드 처럼 호출한다고 가정을 해보겠습니다.

void run() {
    frontLeftTire.roll();
    frontRightTire.roll();
    backLeftTire.roll();
    backRightTire.roll();
    }

frontRightTire와 backLeftTire를 교체하기 전에는 Tire 객체의 roll() 메소드가 호출되지만, HankookTire와 KumhoTire로 교체되면 HankookTire와 KumhoTire가 roll()메소드를 재정의하고 있으므로 교체 이후에는 HankookTire와 KumhoTire의 roll()메소드가 호출되어 실행 결과가 달라집니다. 

이와 같이 자동 타입 변환을 이용해서 Tire 필드값을 교체함으로써 Car의 run()메소드를 수정하지 않아도 다양한 roll()

메소드의 실행 결과를 얻게 됩니다. 이것이 바로 필드의 다형성입니다.

 

 

 

위의 내용으로 만든 예제 ) 실습

 

부모 ( Tire )

package sec01.tire.exam01;

public class Tire {
	//부모
	
	//필드
	public int maxRotation;// 최대 회전수(타이어수명)
	public int accumulatedRotation;// 누적 회전수
	public 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;
		}
		
	}
}

 

부모( Tire )를 부품으로 가지는 클래스 ( Car )

package sec01.tire.exam01;

	// 부모( Tire )를 부품으로 가지는 클래스
public class Car {
	//필드
	Tire frontLeftTire = new Tire("앞왼쪽", 6);
	Tire frontRightTire = new Tire("앞오른쪽", 2);
	Tire backLeftTire = new Tire("뒤왼쪽", 3);
	Tire backRightTire = new Tire("뒤오른쪽", 4);
	
	//생성자
	
	//메소드
	int run() {
		System.out.println("[자동차가 달립니다.]");
		if (frontLeftTire.roll()==false) {stop(); return 1;}
		if (frontRightTire.roll()==false) {stop(); return 2;}
		if (backLeftTire.roll()==false) {stop(); return 3;}
		if (backRightTire.roll()==false) {stop(); return 4;}
		return 0;
	}
	void stop() {
		System.out.println("[자동차가 멈춥니다.]");
	}
}

 

Tire의 자식 클래스 ( HankookTire )

package sec01.tire.exam01;

public class HankookTire extends Tire {
	//Tire의 자식 클래스 
	
	//필드
	//생성자
	public HankookTire(String location, int maxRotation) {
		super(location, maxRotation);
	}


	
	//메소드
	@Override
	public boolean roll() {
		++accumulatedRotation;
		if(accumulatedRotation<maxRotation) {
			System.out.println(location + "HankookTire 수명:" +
				(maxRotation-accumulatedRotation + "회"));
			return true;
		}else {
			System.out.println("***" + location + "HankookTire 펑크 ***");
			return false;
		}
		
	}
	
}

 

Tire의 자식 클래스 ( KumhoTire )

package sec01.tire.exam01;

public class KumhoTire extends Tire {
	//Tire의 자식 클래스 
	
	//필드
	//생성자
	public KumhoTire(String location, int maxRotation) {
		super(location, maxRotation);
	}
	//메소드
	public boolean roll() {
		++accumulatedRotation;
		if(accumulatedRotation<maxRotation) {
			System.out.println(location + " KumhoTire 수명:" +
				(maxRotation-accumulatedRotation + "회"));
			return true;
		}else {
			System.out.println("***" + location + "KumhoTire 펑크 ***");
			return false;
		}
		
	}
}

 

실행

package sec01.tire.exam01;

public class CarEx {

	public static void main(String[] args) {
		Car car = new Car(); 
		
		for(int i=1; i<=5; i++) {
			int problemLocation = car.run();
			
			switch (problemLocation) {
			case 1:
				System.out.println("앞왼쪽 HankookTire로 교체");
				car.frontLeftTire = new HankookTire("앞왼쪽", 15);
				break;
				
			case 2:
				System.out.println("앞오른쪽 kumgoTire로 교체");
				car.frontRightTire = new KumhoTire("앞오른쪽", 13);
				break;
				
			case 3:
				System.out.println("뒤왼쪽 HankookTire로 교체");
				car.backLeftTire = new HankookTire("뒤왼쪽", 14);
				break;
			case 4:
				System.out.println("뒤오른쪽 kumgoTire로 교체");
				car.backRightTire = new KumhoTire("뒤오른쪽", 17);
				break;
				
			}
			System.out.println("---------------------------");
		}
	}

}

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-08 15일차  (0) 2023.06.08
2023-06-07 14일차  (0) 2023.06.07
2023-06-01 12일차  (0) 2023.06.01
2023-05-31 11일차  (0) 2023.05.31
2023-05-30 10일차  (0) 2023.05.30

상속

 

클래스 상속

현실에서 상속은 부모가 자식을 선택해서 물려주지만,

프로그램에서는 자식이 부모를 선택

package sec01.exam01;

선언
class Aaa {
	
}
// 부모 
public class Ppp {
	int x;
}

//상속
class Ccc extends Ppp {

}

실행
package sec01.exam01;

public class Ex1 {

	public static void main(String[] args) {
		Ccc ccc = new Ccc();
		ccc.x = 100;
		System.out.println(ccc.x);

	}

}

 

 

자바 상속 특징

1. 여러 개의 부모 클래스를 상속할 수 없음

2. 부모 클래스에서 private 접근 제한을 갖는 필드와 메소드는 상속 대상에서 제외

부모 클래스와 자식 클래스가 다른 패키지에 존재한다면 default 접근 제한을 갖는 필드와 

메소드도 상속 대상에서 제외됨

 

실습

부모
package sec01.exam01.Phone;

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 sec01.exam01.Phone;

public class DmbCellPhone extends CellPhone {
	//필드
	int channel;
	
	//생성자
	DmbCellPhone(String model, String color, int channel){
		
//		super(); 자동적으로 추가 
		this.model = model; // 부모
		this.color = color;
		this.channel = channel;
	}
	
	//메소드
	
		void turnOnDmb() {
			System.out.println("채널" + channel + "번 DMB 방송 수신을 시작합니다.");
		}
		void changChannelDmb(int channel) {
			this.channel = channel;
			System.out.println("채널" + channel + "번으로 바꿉니다.");
		}
		void turnOffDmb() {
			System.out.println("DMB 방송 수신을 멈춥니다.");
		}
	}
실행

package sec01.exam01.Phone;

public class DmbCellPhoneEx {

	public static void main(String[] args) {
		// DmbCellPhone 객체 생성
		DmbCellPhone dmbCellPhone = new DmbCellPhone("자바폰", "검정", 10 );
		
		// cellPhone 클래스로부터 상속받은 필드
		System.out.println("모델: " + dmbCellPhone.model);
		System.out.println("색상: " + dmbCellPhone.color);
		
		System.out.println("채널: " + dmbCellPhone.channel);
		
		dmbCellPhone.powerOn();// 부모
		dmbCellPhone.bell();
		dmbCellPhone.sendVoice("여보세요");
		dmbCellPhone.receiveVoice("안녕하세요? 저는 홍길동인데요");
		dmbCellPhone.sendVoice("아~ 반갑습니다.");
		dmbCellPhone.hangUp();
		
		dmbCellPhone.turnOnDmb();
		dmbCellPhone.changChannelDmb(12);
		dmbCellPhone.turnOffDmb();

	}
}
결과
모델: 자바폰
색상: 검정
채널: 10
전원을 켭니다.
벨이 울립니다.
자기:여보세요
상대방:안녕하세요? 저는 홍길동인데요
자기:아~ 반갑습니다.
전화를 끊습니다.
채널10번 DMB 방송 수신을 시작합니다.
채널12번으로 바꿉니다.
DMB 방송 수신을 멈춥니다.

 

부모 생성자 호출

현실에서 부모 없는 자식이 있을 수 없듯이 자바에서도 자식 객체를 생성하면, 부모 객체가 먼저 생

성되고 그다음에 자식 객체가 생성됨

DmbCellPhone(자식) 객체만 생성하는 것 처럼 보이지만, 사실은 내부적으로 부모인 CellPhone 객체가 먼

저 생성되고 자식인 DmbCellPhone 객체가 생성 

DmbCellPhone dmbCellPhone = new DmbCellPhone()

모든 객체는 클래스의 생성자를 호출해야만 생성되며, 부모 생성자는 자식 생성자의 맨 첫줄에서 호출됨

예를 들어, DmbCellPhone(자식)의 생성자가 명시적으로 선언되지 않았다면 컴파일러는 밑에 같이 기본

생성자를 생성함

public DmbCellPhone() {
	super();
}

super()는 부모의 기본 생성자

만약에 직접 자식 생성자를 선언하고 명시적으로 부모 생성자를 호출하고 싶다면 다음과 같이 작성

자식클래스( 매개변수선언, ... ){
	super(매개값, ...)
}

super(매개값, .. )는 매개값의 타입과 일치하는 부모 생성자를 호출

매개값의 타입과 일치하는 부모 생성자가 없을 경우 컴파일 에러가 발생

super(매개값, .. )가 생략되면 컴파일러에 의해 super()가 자동적으로 추가되기 때문에 부모의

기본 생성자가 존재해야함

부모 클래스에 기본 생성자가 없고 매개 변수가 있는 생성자만 있다면 자식 생성자에서 반드시

부모 생성자를 호출을 위해 super(매개값, .. )를 명시적으로 호출해야함

super(매개값, .. )는 반드시 자식 생성자 첫 줄에 위치해야 하며, 그렇지 않으면 컴파일 에러가 발생

 

 

 

 

메소드의 재정의( 오버라이딩 )

부모 클래스의 모든 메소드가 자식 클래스에 맞게 설계되어 있다면 가장 이상적인 상속이지만

어떤 메소드는 자식 클래스가 사용하기에 적합하지 않을 수도 있습니다.

상속된 일부 메소드는 자식 클래스에서 다시 수정해서 사용해야 합니다.

자바는 이런경우를 위해 메소드 재정의(오버라이딩) 기능을 제공

메소드 재정의 방법

메소드 재정의는 자식 클래스에서 부모 클래스의 메소드를 다시 정의하는 것을 말함

메소드를 재정의할 때는 다음과 같은 규칙에 주의

1. 부모의 메소드와 동일한 시그너처(리턴 타입, 메소드 이름, 매개 변수 목록)을 가져야함

2. 접근 제한을 더 강하게 재정의할 수 없음

3. 새로운 예외를 throws 할 수 없음

접근 제한을 더 강하게 재정의할 수 없다는 것은 부모 메소드가 public 접근 제한을 가지고 있을 경우

재정의하는 자식 메소드는 default나 private 접근 제한으로 수정할 수 없다는 뜻

 

 

실습1

부모

package sec01.exam01.Child01;

public class Parent {
	void method1() {
		System.out.println("부모의 method1");
	}
	void method2() {
		System.out.println("부모의 method2");
	}
}

자식
package sec01.exam01.Child01;

public class Child extends Parent {
	void method2() {
		System.out.println("자식의 method2");
	}
	void method3() {
		System.out.println("자식의 method3");
	}
	void method4() {
		super.method1();
		System.out.println("부모의 method1");
	}
	
	@Override // 재정의 
	void method1() {
		
		super.method1();
	}
	
	
}

재정의된 메소드 호출
package sec01.exam01.Child01;

public class ChildEx {

	public static void main(String[] args) {
		
		Child child = new Child();
		
		child.method1();
		//부모의 method2
		
		child.method2(); // 재정의된 메소드 호출
		//자식의 method2

		child.method3();
		//자식의 method3
		
		child.method4();
		//부모의 method1
		//부모의 method1
	}

}
결과
부모의 method1
자식의 method2
자식의 method3
부모의 method1
부모의 method1

 

 

실습2

부모

package sec01.exam01.Child02;

public class Calculator {
	double areaCircle(double r) {
		System.out.println("Calculator 객체의 areaCircle() 실행 ");
		return 3.14159 * r * r;// 정밀한 계산을 위해 수정
	}
}
자식

package sec01.exam01.Child02;

public class Computer extends Calculator {

	@Override // 재정의
	double areaCircle(double r) {
		System.out.println("Computer 객체의 areaCircle() 실행");
		return Math.PI * r *r;
	}
	
}
실행

package sec01.exam01.Child02;

public class ComputerEx {

	public static void main(String[] args) {
		int r = 10;
		
		Calculator calculator = new Calculator();
		System.out.println("원면적 : " + calculator.areaCircle(r));
		System.out.println();
		
		//computer.areaCircle(r) => 재정의된 메소드 호출
		Computer computer = new Computer();
		System.out.println("원면적 : " + computer.areaCircle(r));

	}

}
결과
Calculator 객체의 areaCircle() 실행 
원면적 : 314.159

Computer 객체의 areaCircle() 실행
원면적 : 314.1592653589793

 

 

'프로젝트 기반 자바(JAVA) 응용 SW개발자 취업과정' 카테고리의 다른 글

2023-06-07 14일차  (0) 2023.06.07
2023-06-02 13일차  (0) 2023.06.02
2023-05-31 11일차  (0) 2023.05.31
2023-05-30 10일차  (0) 2023.05.30
2023-05-26 9일차  (1) 2023.05.26

소스코드 작성

Student.java ( static )

package static0601;

public class Student {
	// 필드
	//총점, 평균 Getter/Setter
	
	private String name;
	private int kor;
	private int math;
	private int eng;
	
	private int tot;
	private int avg;
	
	//사용 안함
//	private int kmax;
//	private int mmax;
//	private int emax;
//	
//	String kMaxName;
//	String eMaxName;
//	String mMaxName;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getKor() {
		return kor;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	public int getMath() {
		return math;
	}
	public void setMath(int math) {
		this.math = math;
	}
	public int getEng() {
		return eng;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}
	public int getTot() {
		return tot;
	}
	public void setTot(int kor, int math, int eng) {
		this.tot = kor + eng + math;
		

	}
	public int getAvg() {
		return avg;
	}
	public void setAvg(int kor, int math, int eng) {
		this.avg = (kor + eng + math) / 3;
	}
	
	//사용 안함
//	public int getKmax() {
//		return kmax;
//	}
//	public void setKmax(int kmax, int kor, String kMaxName) {
//	    this.kmax = kmax;
//	    this.kor = kor;
//	    this.kMaxName = kMaxName;
//	}
//	public int getMmax() {
//		return mmax;
//	}
//	public void setMmax(int mmax, int math, String mMaxName) {
//		this.mmax = mmax;
//	    this.math = math;
//	    this.mMaxName = mMaxName;
//	}
//	public int getEmax() {
//		return emax;
//	}
//	public void setEmax(int emax, int eng, String eMaxName) {
//		this.emax = emax;
//	    this.eng = eng;
//	    this.eMaxName = eMaxName;
//	}
	
	
	
}

 

Singleton.java (static)

package static0601;

public class Singleton {
	public Student[] stu = new Student[3];
	private int index;
	
	public int getIndex() {
		System.out.println(index);
		return index++ % stu.length;
	}
	public void setIndex(int index) {
		this.index = index;
	}
	private static Singleton st = new Singleton();
	
	// 과목별 최고 점수, 학생 필드값 지정
    private int kmax;
    private String kMaxName;
    
    private int emax;
    private String eMaxName;
    
    private int mmax;
    private String mMaxName;
	
	private Singleton() {
		for (int i=0; i < stu.length; i++) {
			stu[i] = new Student();
		}
	}
	public static Singleton getInstance() {
		return st;
	}
	
	// 과목별 최고 점수. 학생 Getter/Setter 
	 public int getKmax() {
	        return kmax;
	    }

	    public void setKmax(int kmax) {
	        this.kmax = kmax;
	    }

	    public String getKMaxName() {
	        return kMaxName;
	    }

	    public void setKMaxName(String kMaxName) {
	        this.kMaxName = kMaxName;
	    }
		public int getEmax() {
			return emax;
		}
		public void setEmax(int emax) {
			this.emax = emax;
		}
		public String geteMaxName() {
			return eMaxName;
		}
		public void seteMaxName(String eMaxName) {
			this.eMaxName = eMaxName;
		}
		public int getMmax() {
			return mmax;
		}
		public void setMmax(int mmax) {
			this.mmax = mmax;
		}
		public String getmMaxName() {
			return mMaxName;
		}
		public void setmMaxName(String mMaxName) {
			this.mMaxName = mMaxName;
		}
	    
	    
}
	
	
	
	// 기본 싱글톤
//	private static Singleton st = new Singleton();
	
//	private Singleton() {}
	
//	public static Singleton getInstance() {
//		return st;
//	}

 

 

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="static0601.*" %>
<%
Singleton st = Singleton.getInstance();
String nm = request.getParameter("name");
String kor = request.getParameter("kor");
String math = request.getParameter("math");
String eng = request.getParameter("eng");

%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="">
이름<input type="text" name="name" /><br/>
국어<input type="text" name="kor" /><br/>
수학<input type="text" name="math" /><br/>
영어<input type="text" name="eng" /><br/>

<input type="submit" />
</form>
<%

if (kor != null) {
	int index = st.getIndex();
	st.stu[index].setName(nm);
	st.stu[index].setKor(Integer.parseInt(kor));
	st.stu[index].setEng(Integer.parseInt(eng));
	st.stu[index].setMath(Integer.parseInt(math));
/*총점*/st.stu[index].setTot(Integer.parseInt(kor), Integer.parseInt(math) , Integer.parseInt(eng));
/*평균*/st.stu[index].setAvg(Integer.parseInt(kor), Integer.parseInt(math) , Integer.parseInt(eng));

 // 최고점수,사람 
if (Integer.parseInt(kor) > st.getKmax()) {
    st.setKmax(Integer.parseInt(kor));
    st.setKMaxName(nm);
}
 
if (Integer.parseInt(math) > st.getMmax()) {
    st.setMmax(Integer.parseInt(math));
    st.setmMaxName(nm);
}
if (Integer.parseInt(eng) > st.getEmax()) {
    st.setEmax(Integer.parseInt(eng));
    st.seteMaxName(nm);
}
 
}
%>
<table border="1">
<%
for (int i = 0; i < st.stu.length; i++) {
	
%>

    	<tr><th>이름</th>
        <td><%= st.stu[i].getName() %></td>
        <th>국어</th> 
        <td><%= st.stu[i].getKor() %></td>
        <th>수학</th> 
        <td><%= st.stu[i].getMath() %></td>
        <th>영어</th> 
        <td><%= st.stu[i].getEng() %></td>
        <th>총점</th> 
        <td><%= st.stu[i].getTot() %></td>
        <th>평균</th> 
        <td><%= st.stu[i].getAvg() %></td>   
    </tr>    
<%
}
%>

</table>

</table>
<table border="1">
<tr>
    <th>과목</th>
    <th>최고 점수</th>
    <th>최고 점수를 받은 학생</th>
</tr>
<tr>
    <td>국어</td>
    <td><%= st.getKmax() %></td>
    <td><%= st.getKMaxName() %></td>
</tr>
<tr>
    <td>수학</td>
    <td><%= st.getMmax() %></td>
    <td><%= st.getmMaxName() %></td>
</tr>
<tr>
    <td>영어</td>
    <td><%= st.getEmax() %></td>
    <td><%= st.geteMaxName() %></td>
</tr>
</table>

</body>
</html>

 

 

 

결과

 

각 칸에 이름과 국영수 점수 입력

입력한 값 table에 저장됨

학생 국영수 총점과 평균 출력

국영수 각 각 최고점수 최고 점수 학생 나오게 출력

 

+ Recent posts