<여행 패키지 상품>
A. 기본 패키지 -> 부모 클래스(Parent)
- 기차, 펜션
B. 기본패키지 + 액티비티 -> 딸 클래스(Daughter)
- A + 패러글라이딩
C. 기본패키지 + 힐링 -> 아들 클래스(Son)
- A + 농장체험
class Parent2{
public int a = 10;
public void aaa() {
}
}
class Daughter extends Parent2 {
public int b = 20;
public void bbb() {
}
}
class Son extends Parent2 {
public int c = 30;
public void ccc() {
}
}
java.lang 패키지(모든 패키지 중 기본 패키지 -> import를 안해도 사용 가능)
Class Object is the root of the class hierarchy.Every class has Object as a superclass.
Object클래스는 클래스 계층 구조에서 최상위 클래스이다.
지구 상의 모든 클래스는 부모 클래스로 Object를 가진다.
All objects,including arrays, implement the methods of this class.
배열을 포함한 모든 객체는 Object 클래스의 메소드를 구현한다.
public class Ex44_Object {
public static void main(String[] args) {
SubItem sitem = new SubItem();
//sitem의 멤버 -> a, aaa(), b, bbb()
// sitem.a
// sitem.b
// sitem.aaa();
// sitem.bbb();
//sitem.notify(); -> Object가 물려준 것.
}
}
class Item extends Object {
public int a;
public void aaa() {
}
}
class SubItem extends Item {
public int b;
public void bbb() {
}
}
public class Ex45_Overriding {
public static void main(String[] args) {
Phone p1 = new Phone();
p1.dial();
SmartPhone s1 = new SmartPhone();
//s1.dial(); //물려받긴 했지만.. 사용하기엔.. 찜찜한.. 상황 > 상속을 거부할 수도 없음;;
//부모로부터 물려받았지만 적당하지 않은 경우 재정의해서 사용.(덮어쓰기)
//무조건 자식이 선언한, 오버라이드한 dial() 메소드가 호출된다.(100%)
//메소드가 하는 일이 바뀌었다. -> 메소드 재정의★★★
s1.dial();
}//main
}//Ex45
//폴더폰
class Phone {
public String model;
public void dial() {
System.out.println("버튼을 눌러 전화를 겁니다.");
}
}
//스마트폰
class SmartPhone extends Phone {
//전화기
// - model
// - dial()
//자신의 멤버
public void game() {
System.out.println("게임을 합니다.");
}
//★★★★★★상속관계에서 부모가 물려준 메소드와 동일한 시그너처로 메소드를 선언하게 되면
//자식의 메소드가 부모의 메소드보다 우선해서 노출된다.(호출당하게 된다.)
//메소드 오버라이드
public void dial() {
System.out.println("화면을 터치해서 전화를 겁니다.");
}
}
import java.util.Random;
public class Ex45_Overriding {
public static void main(String[] args) {
MyRandom3 rnd = new MyRandom3();
System.out.println(rnd.nextColor());
System.out.println(rnd.nextBoolean());
System.out.println(rnd.nextDouble());
System.out.println(rnd.nextInt());
}//main
}
//Random이 가지는 기능이 모두 필요 + 추가 기능 필요 -> 확장
// - Random의 모든 기능을 필요하다고 생각했지만,
// - nextInt() 사용을 안함 or nextInt()의 범위 부담이 된다고 가정.
class MyRandom3 extends Random {
//nextTinyInt() -> nextInt()으로 이름을 설정하고 싶
public int nextTinyInt() {
return 1;
}
//부모의 nextInt()를 자식이 재정의 -> 오버라이드
public int nextInt() {
Random rnd = new Random();
return rnd.nextInt(10) + 1;
}
public String nextColor() {
Random rnd = new Random();
String[] color = { "red", "yellow", "blue" };
return color[rnd.nextInt(color.length)];
}
}
public class Ex45_Overriding {
public static void main(String[] args) {
//멤버 6개
CCC c = new CCC();
System.out.println(c.a);//BBB.aaa() -> 할아버지가 아닌 아버지에서 오버라이드된 메소드를 상속했다.
System.out.println(c.b);
System.out.println(c.c);
c.aaa();
c.bbb();
c.ccc();
}//main
}
class AAA {
public int a;
public void aaa() {
System.out.println("부모 행동");
}
}
class BBB extends AAA {
public int b;
public void bbb() {
}
public int a; //변수 오버라이드 -> 사용 안함(100%) -> 의미 전혀 없음;;
@Override //어노테이션. 메소드 오버라이드
public void aaa() {
System.out.println("자식 행동");
}
}
class CCC extends BBB {
public int c;
public void ccc() {
}
}
import java.util.Calendar;
import java.util.Date;
public class Ex46_Override {
public static void main(String[] args) {
//Ex46_Override.java
Time t1 = new Time(10, 5, 30);
//System.out.println(t1.info());
//com.test.question.inheritance.Time@26f0a63f
// - com.test.question.inheritance.Time : 패키지.클래스명
// - @
// - 26f0a63f : 해시코드(HashCode) -> 해당 객체가 있는 메모리 주소값(Hex16진수)
//info() 메소드를 사용안하고 toString()을 재정의 하는 이유★★★
// -> 많은 사람들의 공통된 경험
// -> 대부분의 개발자들은 객체의 toString() 메소드가 객체 자신의 데이터를 문자열로 반환할거라는 많은 경험과 기대치를 가지고 있다.
// -> toString()의 목적 -> 반환된 문자열을 그대로 업무에 사용(X) -> 개발자가 객체의 상태를 확인하는 용도(O)
System.out.println(t1); //com.test.question.inheritance.Time@26f0a63f이 출력됨
System.out.println(t1.toString());
System.out.println(t1.info()); //대신 사용하면 되겠지~ > 귀찮아 죽겠어.. 그냥 toString() 재정의해놓지 왜 메소드 외우기 귀찮에 info()라는걸 또 만들어놨어;;라고 생각이 든다..-> 별도로 info()를 사용하든 tostring을 오버라이드해서 사용하든 기능의 차이는 없지만 많은 사람들이 당연하게 toString을 오버라이드해서 사용하기 때문에 같은 방식을 쓰면 좋은 코드가 될 수 있다.
Calendar c = Calendar.getInstance();
System.out.println(c);
System.out.println(c.toString()); //Calendar.toString() -> Calendar 클래스가 Object 클래스가 물려준 toString()을 그대로 사용 안하고 재정의했다.(★★★)
Date d = new Date();
System.out.println(d);
System.out.println(d.toString()); //Date.toString() -> Date클래스가 Object 재정의
}//main
}
class Time {
private int hour;
private int min;
private int sec;
public Time(int hour, int min, int sec) {
this.hour = hour;
this.min = min;
this.sec = sec;
}
public String info() {
return String.format("%d:%d:%d", this.hour, this.min, this.sec);
}
@Override
public String toString() {
return "Time [hour=" + hour + ", min=" + min + ", sec=" + sec + "]";
}
// @Override
// public String toString() {
//
// return String.format("%d:%d:%d", this.hour, this.min, this.sec);
// }
}
변수에 적용 가능
a, 지역 변수에 적용 가능
b. 멤버 변수에 적용 가능
메소드에 적용 가능
클래스에 적용 가능
public class Ex47_final {
public static void main(String[] args) {
//- 10 : 상수 -> 리터럴 -> 이름 없는 상수
//- int a : 변수
//- final int a : final 변수(= 상수) -> 이름 있는 상수(★★★★★)
//상수의 문제점 : 의미를 알 수 없다. -> final은 상수에 이름을 붙일 수 있다는 장점을 가짐.
int a = 10; //일반 변수
final int b = 20; //final 변수
System.out.println(a);
System.out.println(b);
a = 30;
//The final local variable b cannot be assigned.에러
//b = 40;
//상수값 -> 3.14
//double pi = 3.14;
//final double pi = 3.14;
//pi = 1.11; //-> 누군가 잘못된 값으로 수정할 위험이 있다.
//System.out.println(pi);
final double PI = 3.14;
//PI = 1.11;
System.out.println(PI); //상수명은 모두 대문자로 쓴다.
FinalItem f1 = new FinalItem();
//f1.C = 100; -> 상수라서 값에 변화를 줄 수 없다.
System.out.println(f1.C); //개인 정보 -> 다른 객체와 다른 값을 가질 수 있다.
System.out.println(f1.D);//공용 정보 -> 다른 객체와 다른 값을 가질 수 없다.
FinalItem f2 = new FinalItem();
//f1.C = 200;
System.out.println(f1.C); //개인 정보 -> 다른 객체와 다른 값을 가질 수 있다.
System.out.println(f1.D); //공용 정보 -> 다른 객체와 다른 값을 가질 수 없다.
}
}
class FinalItem{
//클래스 멤버
private int a = 10; //일반 객체 멤버 변수
private final int B = 20; // 객체 멤버 상수
public final int C = 30; //멤버 상수는 접근 지정자를 public으로 하는 경우가 많다. -> 상수에 잘못된 값을 입력할 경우가 없기 때문에
public final static int D = 40; //정적 상수 ->값을 바꿀 수 없기 때문에 공용 정보로 볼 수 있다. -> 가장 많이 사용 (메모리를 아낄 수 있기 때문에)
}
public class Ex47_final {
public static void main(String[] args) {
}
}
//홍길동 제작
// - 길동이는 FinalParent 클래스가 부모가 되길 바라지 않음. 상속에 사용되지 않았으면 좋겠다.
// - 더이상 자식을 가질 수 없는 클래스 > 최종 클래스(Leaf Class)
final class FinalParent {
//홍길동 제작 test()를 만든 의도
// - 이 메소드는 나중에 자식이 고치면 안돼!!! -> final 사용
// - 코드 안정성 향상!!
public final void test() {
System.out.println("부모 행동");
}
}
//아무개 제작
// The type FinalChild cannot subclass the final class FinalParent 에러
//상속하지 말라는 클래스를 상속해서 에러가 생김
//class FinalChild extends FinalParent {
//고치지 말라는 메소드를 고쳤다. -> 예기치못한 문제 발생 가능성!!
// @Override
// public void test() { //Cannot override the final method from FinalParent 에러
// System.out.println("자식 행동");
// }
//}
public class Ex48_Interface {
public static void main(String[] args) {
//Test t = new Test();
//t.aaa();
//t.test(); //-> 겉에서 내용물이 있는지 없는지 확인 할 수 없기 때문에 에러가 난다.
//t.bbb();
//Phone p = new Phone();
//p.test(); //작업이 불가능하기 때문에(추상 메서드 -> 불완전하기 떄문에) 인터페이스는 객체를 생성할 수 없다.
S21 s = new S21();
s.test();
}
}
//인터페이스 선언하기
interface Phone {
//인터페이스 멤버
//{} 없음 -> 구현부가 없는 메소드 -> 실체화가 되지 않은 메소드 -> 추상 메소드(Abstract Method) -> 호출해도 사용이 불가능하다. -> 현 상태로는 사용할 수 없다.
//public void test();
public abstract void test(); //정석
//public int a;
//public void test() {
//}
}
//상속 키워드
//1. extends
// - 클래스 -> 클래스
//2. implements
// - 클래스 -> 인터페이스
//The type S21 must implement the inherited abstract method Phone.test()
class S21 implements Phone { //상속
//public abstract void test()
//오버라이드 -> 구현부 생성
//인터페이스가 물려준 추상 메소드를 물려받고 + 재정의 -> ★★★★★★★
//일반 상속 -> 오버라이드 -> 개발자의 선택
//인터페이스 상속 -> 오버라이드 -> 개발자의 선택X -> 무조건 필수!! -> 안하면 컴파일 오류 -> 강제!!!!!!!!!
public void test() {
System.out.println("테스트입니다.");
}
}
//네가(I12)가 내(Phone) 자식이 되려면 내가 시키는 걸 반드시 해라!!!
// -> 시키는 일 -> 추상 메소드를 구현하는 것 -> 추상 메소드에 없는 몸통을 만드는 것 -> 오버라이드
class I12 implements Phone {
@Override
public void test() {
}
//public void test() {
//이 안쪽은 I12 맘대로..
//}
}
//일반 클래스는 추상 메소드를 가질 수 없다.(★★★★★★★)
class Test {
//public abstract void test(); //추상메소드 -> 실행할 내용이 없어서 사용할 수 없다.
//public void test() {
//}
public void aaa() {
}
public void bbb() {
}
}
파일 따로 작성
Monitor.java -> 인터페이스
LG100.java -> 클래스
HP200.java -> 클래스
public class Ex49_Interface {
public static void main(String[] args) {
//Monitor.java -> 인터페이스
//LG100.java -> 클래스
//HP200.java -> 클래스
//홍길동
// -> 모니터 구입 -> LG100 -> 수령 -> on()
//LG100 lg = new LG100(); //구입
//lg.on(); //전원 O
//lg.off(); //전원 x
//10년이 흘러서 모니터가 고장..
// -> HP 200구입 -> 수령
//HP200 hp = new HP200();
//hp.on(); //먼저의 방식으로 전원을 킴. -> 경험에 기반된 행동
//hp.begin();
//hp.off();
//hp.end();
//---------------------------------
//LG100과 HP200은 같은 인터페이스를 상속받았다(구현했다)
// -> 똑같은 이름의 메소드를 가지고 있다.
// -> 사용법이 동일하다.
// -> 추가 학습없이 서로 다른 클래스의 객체를 동일한 사용법으로 조작이 가능하다.
LG100 lg2 = new LG100();
lg2.powerOn();
lg2.powerOff();
//10년이 흘렀음
HP200 hp2 = new HP200();
hp2.powerOn();
hp2.powerOff();
Dell300 dell = new Dell300();
dell.powerOn();
dell.powerOff();
}//main
}//Ex49
//실제 제품(X) -> 규격 역할(O) -> 모니터의 자격을 가지려면, 최소한 이런 규칙은 지키세요!!! -> 규칙의 집합 역할
public interface Monitor {
//인터페이스 멤버
// - 추상 메소드
// a. abstract 키워드
// b. 구현부를 가지지 않는다.({})
public abstract void powerOn();
public abstract void powerOff();
//** 인터페이스는 구현된(실체화) 멤버를 가질 수 없다.
//public int a;
//public void test() {
//}
}
//모니터 제품 - 실제 제품
public class HP200 implements Monitor {
//모니터 특성
private String name;
private int power;
private String color;
//모니터 행동
// public void begin() {
// System.out.println("HP200 Power on");
// }
//
// public void end() {
// System.out.println("HP200 Power off");
// }
@Override
public void powerOn() {
System.out.println("HP200 Power on");
}
@Override
public void powerOff() {
System.out.println("HP200 Power off");
}
}
//모니터 제품 - 실제 제품
public class LG100 implements Monitor { //인터페이스 구현
//모니터 특성(상태)
private int size;
private String type;
private int price;
//모니터 행동
// public void on() {
// System.out.println("LG100 모니터 전원을 켭니다.");
// }
//
// public void off() {
// System.out.println("LG100 모니터 전원을 끕니다.");
// }
@Override
public void powerOn() {
System.out.println("LG100 모니터 전원을 켭니다.");
}
@Override
public void powerOff() {
System.out.println("LG100 모니터 전원을 끕니다.");
}
}
public class Ex50_Abstract {
public static void main(String[] args) {
//Abstract 키워드
//1. 메소드 -> 추상 메소드
//2. 클래스 -> 추상 클래스
//추상 클래스
// - 추상 메소드를 소유하기 때문에 객체를 생성할 수 없다.
//일반 클래스 - 추상클래스 - 인터페이스
//(구현) (구현+추상) (추상)
//User u1 = new User(); -> 추상 클래스 -> 객체 생성 불가능
}//main
}//Ex50
//추상 클래스
abstract class User {
//멤버
//- 추상 메소드
public abstract void login();
public abstract void logout();
//일반 멤버 -> 인터페이스와 달리 구현 멤버를 가질 수 있다.
public int a;
public void test() {
}
}
class Hong extends User {
//상속받아서 구현.
@Override
public void login() {
}
@Override
public void logout() {
}
}
public class Ex51_Abstract {
public static void main(String[] args) {
// 인터페이스 vs 추상 클래스
// - 둘 다 추상 메소드를 통해서 메소드를 강제 구현
// - 구현된 멤버도 물려주고 싶으면 추상 클래스를 사용해야한다. 인터페이스는 불가능(x)
// - 용도는 다르다.
// - 결론 : 인터페이스를 추상클래스보다 더 많이 사용한다. (인터페이스를 설계하는게 추상 클래스 설계보다 생각해야할 경우의 수가 적다.)
}
}
//컴퓨터가 갖춰야할 사용법들의 집합
//인터페이스
interface Computer {
public abstract void on();
public abstract void off();
}
//추상클래스 -> 구현된 멤버도 물려줄 수 있다.
abstract class AComputer {
private String serialNum;
private int weight;
private int price;
public void check() {
System.out.println("바이러스 검사");
}
public abstract void on();
public abstract void off();
}
//class ASUS100 implements Computer { //인터페이스 상속
class ASUS100 extends AComputer { //추상클래스 상속
// private String serialNum;
// private int weight;
// private int price;
//
// public void check() {
// System.out.println("바이러스 검사");
// }
@Override
public void on() {
//추상 메소드의 의도??
// - 겉으로 보이는 사용법을 강제로 시킴(헤더를 똑같이 만들도록 강제)
// - 구현부는 자유롭게 맘대로~> 되도록 on 이름에 걸맞는 행동을 구현하는 걸 권장:)
//System.out.println("무슨짓하던 ASUS100맘대로");
//System.out.println("전원을 종료합니다.");
System.out.println("전원 on");
}
@Override
public void off() {
System.out.println("전원 off");
}
}
//class Samsumg200 implements Computer { //인터페이스 상속
class Samsumg200 extends AComputer { //추상 클래스 상속
// private String serialNum;
//
// private int weight;
// private int price;
//
// public void check() {
// System.out.println("바이러스 검사");
// }
@Override
public void on() {
System.out.println("Power on");
}
@Override
public void off() {
System.out.println("Power off");
}
}
public class Ex52_enum {
public static void main(String[] args) {
//쇼핑몰] 의류 > 티셔츠 > 선택 > 색상 선택 > 빨강, 노랑, 파랑
//색상을 선택하세요.
//String color = "무지개색"; //주관식 --> 선택지에 없는 색상을 선택할 위험이 있음
//Color c -> enum 변수
//Color.빨강 -> enum 리터럴
Color c = Color.빨강; //enum 타입의 변수에는 멤버중 하나만 넣을 수 있음
//Color sel = Color.검정;
//Color sel = Color.느랑;
Color sel = Color.노랑;
//회사 업무
//String 직급 = "브장";
직급 s = 직급.사원; //열거형을 쓰면 오타가 날 위험이 없다.
//아이콘
//녹색점: 멤버 변수
//S: static
//F: final
System.out.println(Color.노랑); //static final 상수
System.out.println(MyColor.BLUE);
Color input = Color.빨강;
if (input == Color.노랑) {
} else if (input == Color.빨강) {
}
}//main
}//Ex52
/*
class Color {
//멤버
public int a;
public void test() {
}
}
*/
enum Color {
//멤버
// - 변수만(자료형 X, 값 X, 이름 O)
빨강,
노랑,
파랑
}
enum 직급 {
회장,
사장,
이사,
전무,
부장,
과장,
대리,
주임,
사원
}
class MyColor {
public final static int RED = 0;
public final static int BLUE = 1;
public final static int YELLOW = 2;
}
public class Ex53_Cast {
public static void main(String[] args) {
//Ex53_Cast.java
/*
형변환, Type Cast
1. 값형 형변환: 값형끼리만 가능
2. 참조형 형변환: 참조형끼리만 가능 > 클래스간의 형변환
값형 형변환
- 숫자형끼리 가능(boolean 불가능)
- 작은형 -> 큰형 : 암시적(100% 안전)
- 큰형 -> 작은형 : 명시적(Overflow 발생 가능)
참조형 형변환
- 클래스간의 형변환
- 상속 관계를 맺은 (직계)클래스간에만 가능(부모 자식만 가능)
- 자식클래스 -> 부모클래스 : 암시적(100% 안전), 업캐스팅(Up Casting)
- 부모클래스 -> 자식클래스 : 명시적(부분 안전, 불안전), 다운캐스팅(Down Casting), 100% 불가능, 되는 경우도 있음...
*/
Parent p1 = new Parent();
Child c1 = new Child();
Parent p2; //복사본
Child c2 = new Child(); //원본
//Parent = Child
//부모클래스 = 자식클래스
//업캐스팅 발생(암시적)
p2 = c2;
//p2 = (Parent)c2;
//복사가 제대로 이루어졌는지 확인???
// -> 참조형 형변환의 확인 방법 -> "복사된 참조 변수(p2)를 올바르게 사용할 수 있는가?" (★★★★★)
//"p2로 할 수 있는 모든 행동을 테스트 중.."(★★★★★★★)
//복사된 참조변수 p2를 통해서 Parent기준으로 접근을 한 것이기 때문에 객체에 상관없이 Parent로 보이는 멤버만 사용할 수 있다.
p2.a = 10;
p2.b = 20;
System.out.println(p2.a);
System.out.println(p2.b);
/*
Parent p3 = new Parent(); //원본
Child c3; //복사본
//Child = Parent
//자식클래스 = 부모클래스
//다운캐스팅(명시적)
c3 = (Child)p3; //에러!!!!!!!!!(java.lang.ClassCastException -> Parent cannot be cast to class Child)
//검증?
//"복사된 참조 변수(c3)를 올바르게 사용할 수 있는가?"
//"c3로 할 수 있는 모든 행동을 테스트 중.."
c3.a = 10; //O
c3.b = 20; //O
c3.c = 30; //X
c3.d = 40; //X
System.out.println(c3.a); //O
System.out.println(c3.b); //O
System.out.println(c3.c); //X
System.out.println(c3.d); //X
*/
//부모클래스 -> 자식클래스 되는 경우
Parent p4;
Child c4 = new Child();
//업캐스팅
p4 = c4; //안전
Child c5;
//다운캐스팅(100% 불가능) -> 가능한 작업(**)
//자식클래스 = 부모클래스
c5 = (Child)p4; //실제(**): Child -> Child
System.out.println(c5.a);
System.out.println(c5.b);
System.out.println(c5.c);
System.out.println(c5.d);
}//main
}//Ex53
class Parent {
public int a;
public int b;
}
class Child extends Parent {
public int c;
public int d;
}
public class Ex54_exec {
public static void main(String[] args) throws Exception {
//Ex54_exec.java
//자바 프로그램에서 외부 프로그램 호출하기
/*
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
while (true) {
System.out.print("선택: ");
String sel = reader.readLine();
if (sel.equals("1")) {
Process p1 = new ProcessBuilder("notepad.exe").start();
} else if (sel.equals("2")) {
Process p1 = new ProcessBuilder("mspaint.exe").start();
} else if (sel.equals("3")) {
Process p1 = new ProcessBuilder("msedge.exe").start();
} else if (sel.equals("4")) {
Process p1 = new ProcessBuilder("explorer.exe").start();
} else if (sel.equals("5")) {
Process p1 = new ProcessBuilder("calc.exe").start();
}
System.out.println("확인");
}
*/
//Process p1 = new ProcessBuilder("notepad.exe"
// , "D:\\class\\java\\JavaTest\\src\\com\\test\\java\\Ex54_exec.java").start();
//Process p1 = new ProcessBuilder("explorer.exe", "D:\\class\\java").start();
//Process p1 = new ProcessBuilder("C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"
// , "http://www.yes24.com/Product/Goods/91433923?OzSrank=1").start();
}
}