class 자식클래스 extends 부모클래스 {
// ...
}
class Parent {}
class Child extends Parent {
// ...
}
// 부모의 멤버는 1개
class Parent{
int age;
}
// 자식의 멤버는 상속받은 멤버 1개
class child extends Parent {}
class Parent {
int age
}
// 자신의 멤버 1개 + 상속받은 멤버 1개
class Child extends Preant {
void play() {
System.out.println("놀자~");
}
}
// 부모는 자식에게 영향을 줄 수 있다(부모가 변경되면 자식에게 영향을 줌)
class Point{
int x;
int y;
}
// 그대로 전부 작성을 해주어야 한다
// 누구에게도 영향을 주지 않는다
class Point3D {
int x;
int y;
int z;
}
// 부모 Point에게 x, y 변수를 받아서 z만 따로 선언해주면 된다
// 자식이 부모에게 영향을 주지는 못한다(자식이 변경되도 부모에게는 영향이 없다)
class Point3D extends Point {
int z;
}
포함(composite)이란?
class Point{
int x;
int y;
}
// Circle은 무엇하고도 관계가 없음
class Circle {
int x;
int y;
int z;
}
// Circle이 Point를 포함하고 있다(포함 관계)
class Circle {
Point c = new Point();
int r;
}
class TvDVD extends Tv, DVD { // 에러 조상은 하나만 허용
// ...
}
// 부모가 없는 클래스는 컴파일러에서 자동으로 Object를 상속시킨다
class Tv extends Object{
// ...
}
class SmartTv extends Tv {
// ...
}
class Point {
int x;
int y;
String getLocation() {
return "x :" + x + ", y :" + y;
}
}
class Point3D extends Point {
int z;
@override
String getLocation() {
return "x :" + x + ", y :" + y + ", z :" + z;
}
}
오버라이딩의 조건
class Parent {
void parentMethod() throws IOException, SQLException {
...
}
}
class Child extends Parent {
void parentMethod() throws IOException {
...
}
}
오버로딩 vs 오버라이딩
class Parent { int x = 10; // super.x }
class Child extends Parent {
int x = 20; // this.x
void method() {
System.out.println("x=" + x); // 20
System.out.println("this.x=" + this.x); // 20
System.out.println("super.x=" + super.x); // 10
}
}
class Parent2 { int x = 10; // super.x, this.x 둘 다 가능 }
class Child2 extends Parent2 {
void method() {
System.out.println("x=" + x); // 10
System.out.println("this.x=" + this.x); // 10
System.out.println("super.x=" + super.x); // 10
}
}
class Point {
int x, y;
Point(int x, int y) {
this.x = x;
this.y = y;
}
}
class Point3D extends Point {
int z;
// 자신이 갖고 있는 멤버만 초기화
Point3D(int x, int y, int z) {
super(x, y); // 조상클래스의 생성자Point(int x, int y)를 호출
this.z = z; // 자신의 멤버를초기화
}
}
package com.codechobo.book
public class PackageTest {
public static void main(String[] args) {
System.out.println("Hello, world!");
}
}
class ImportTest {
java.util.Date tody = new java.util.Date();
// ...
}
import java.util.Date;
class ImportTest {
Date today = new Date();
}
import 패키지명.클래스명;
or
import 패키지명.*;
package com.codechobo.book;
import java.text.SimpleDateFormat;
import java.util.*;
public class PackageTest{
public static void main(String[] args) {
Date today = new Date();
SimpleDateFormat date = new SimpleDateFormat("yyyy/MM/dd");
}
}
import static java.lang.Interger.*; // Interger클래스의 모든 static메서드
import static java.lang.Math.random; // Math.random()만, 괄호 안붙임
import static java.lang.System,out; // System.out을 out만으로 참조가능
public class ModifierTest {
public static final int WIDTH = 200;
public static void main(String[] args) {
System.out.println("WIDTH="+WIDTH)
}
}
// 멤버 변수가 전부 public이여서 외부에서 쉽게 접근이 가능해진다
public class Time{
public int hour; // 0 ~ 23
public int minute; // 0 ~ 59
public int second; // 0 ~ 59
}
Time t = new Time
t.hour = 25; // 멤버변수에 직접 접근하여 잘 못된 값을 입력할 수 있다!
public class Time{
// 접근 제어자를 private으로 하여 외부에서 직접 접근하지 못하도록 한다
private int hour; // 0 ~ 23
private int minute; // 0 ~ 59
private int second; // 0 ~ 59
// 클래스는 public으로 간접접근 허용
public int getHour() { return hour; }
// 값을 보호하고 잘못된 값 입력을 방지할 수 있다
public void setHour(int hour) {
if(hour < 0 || hour > 23) return;
this.hour = hour;
}
}
SmartTv s = new SmartTv(); // 참조변수와 인스턴스의 타입 일치
Tv t = new SmartTv(); // 조상 타입 참조변수로 자손 타입 인스턴스 참조
void doWirk(Car c) {
if (c instance of FireEngine) { // 1. 형변환이 가능한지 확인
FireEngine fe = (FireEngine)c; // 2. 형변환
fe.water();
...
}
}
// 형변환을 하는 이유는 인스턴스의 원래 기능을 모두 사용하려고
// Car타입의 리모콘인 c로는 water()를 호출할 수 없으니까
// 리모콘을 FireEngine타입으로 바꿔서 water()를 호출
FireEngine fe = new FireEngine();
// 객체의 최상위 조상은 Object이다
System.out.println(fe instanceof Object); // true
System.out.println(fe instanceof Car); // true
System.out.println(fe instanceof FireEngine); // true
Prouct p1 = new Tv();
Prouct p1 = new Computer();
Prouct p1 = new Audio();
Product[] p = new Product[3];
p[0] = new Tv();
p[1] = new Computer();
p[2] = new Audio();
// 추상메서드는 추상클래스를 갖고 있다
abstract class Player { // 추상클래스(미완성 클래스)
abstract void player(int pos); // 추상메서드(몸통{}이 없는 미완성 메서드)
abstract void stop();
}
Player p = new Player(); // Error, 추상 클래스의 인스턴스 생성불가
class AudioPlayer extends Player {
void play(int pos) { /* 내용 생략 */ } // 추상메서드를 구현
void stop() { /* 내용 생략 */ } // 추상메서드를 구현
}
AudioPlayer ap = new AudioPlayer(); // 추상클래스를 재정의하여 완성
Player p = new AudioPlayer(); // 추상클래스는 자손인스턴스의 참조변수는 가능하다
/*주석을 통해 어떤 기능을 수행할 목적으로 작성하였는지 설명*/
abstract 리턴타입 메서드이름();
abstract class Player { // 추상 클래스
abstract void play(int pos); // 추상메서드
abstract void stop(); // 추상메서드
}
class AudioPlayer extends Player {
void play(int pos) { /*내용생략*/ } // 추상메서드 구현
void stop() { /*내용생략*/ } // 추상메서드 구현
}
// 아직 구현되지 않은 추상메서드가 있기 때문에 abstract를 붙여주어야 한다
abstract class AbstractPlayer extends Player {
void play(int pos) { /*내용생략*/ } // 추상메서드를 구현
}
abstract class Player { // 추상 클래스
boolean pause; // 일시정지 상태를 저장하기 위한 변수
int currentPos; // 현재 play되고 있는 위치를 저장하기 위한 변수
Player() { // 생성자
pause = false;
currentPos = 0;
}
/** 지정된 위치(pos)에서 재생을 시작하는 기능이 수행하도록 작성되어야 한다 */
abstract void play(int pos); // 추상메서드
/** 재생을 즉시 멈추는 기능을 수행하도록 작성되어야 한다. */
abstract void stop(); // 추상메서드
// 메서드는 선언부만 알면 호출가능하므로 추상메서드도 호출 가능
// 상속을 통해서 자손이 완성될 수 있기 때문에 선언은 가능
// 하지만 실제로 사용할려면 객체 생성 후여야 하기 때문에 상속되어 완성되어야 가능
void play() { // 인스턴스 메서드
play(currentPos); // 추상메서드를 사용할 수 있다
}
}
GreforianCalendar cal = new GregorianCalendar(); // 구체적
Calendar cal = Calendar.getInstance(); // 추상적
// interface는 모든 멤버가 public이다
interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 메서드이름(매개변수목록);
}
interface PlayingCard {
public static final int SPADE = 4;
// public static final은 생략 가능하다
// 왜냐하면 인터페이스는 항상 public static final이기 때문이다 예외없이
final int DIAMOND = 3; // public static final int DIAMOND = 3;
static int HEART = 2; // public static final int HEART = 2;
int CLOVER = 1; // public static final int CLOVER = 1;
public abstract String getCardNumber();
// public abstract는 생략가능하다
// 왜냐하면 인터페이스는 항상 public이고 abstract이기 때문이다 예외없이
String getCardKind(); // public abstract String getCardKind();
}
interface Fightable extends Movable, Attackable {}
interface Movable {
/** 지정된 위치(x, y)로 이동하는 기능의 메서드*/
void move(int x, int y);
}
interface Attactable {
/** 지정된 대상(u)을 공격하는 기능의 메서드*/
void attack(Unit u);
}
class 클래스이름 implements 인터페이스이름 {
// 인터페이스에 정의된 추상메서드를 모두 구현해야 한다
}
interface Fightable {
// public abstract 생략
void move(int x, int y);
void attack(Unit u);
}
class Fighter implements Fightable {
public void move(int x, int y) { /* 내용 생략 */ } // 추상메서드 구현
public void attack(Unit u) { /* 내용 생략 */ } // 추상메서드 구현
}
abstract class Fighter implements Fightable {
public void move(int x, int y) { /* 내용 생략 */ } // 추상메서드 구현
}