public class 클래스명 {
// 객체 변수
// 메소드
// + 접근제어자
// + static
}
클래스명 객체명 = new 클래스명();
public class 클래스명 {
클래스명() {}
}
this
: 객체 자신을 의미this()
: 생성자public class 클래스명 {
클래스명() {}
클래스명(String name, String type) {
구현 내용;
}
}
private
: 해당 클래스에서만 접근 가능public
: 어디서든 접근 가능default
: 해당 패키지 내에서만 접근 가능protected
: 해당 패키지 및 상속받은 클래스에서 접근 가능= 상위 클래스, 기초클래스
= 하위 클래스, 파생 클래스
생성자, 초기화 블록은 상속되지 않음
default의 경우, 내부 패키지의 자식 클래스는 가능
class Person {}
class Student extends Person {}
Person p1 = new Student();
// Student s1 = new Person();
class Person {}
class Student extends Person {}
Person p1 = new Student();
// Student s1 = new Person();
System.out.println(p1 instanceof Person); // 이렇게 하면 p1이 Person의 객체인지 아닌지 확인 가능
class Person {
public void print() {
System.out.println("Person.print");
}
}
// Person을 상속
class Student extends Person {
public void print() { //print()오버라이딩
System.out.println("Student.print");
}
public void print2() {
System.out.println("Student.print2");
}
}
// Person을 상속
class CollegeStudent extends Person {
public void print() {
System.out.println("CollegeStudent.print");
}
}
public class Main {
public static void main(String[] args) {
// 1. 다형성
System.out.println("== 다형성 ==");
Person p1 = new Person();
Student s1 = new Student();
Person p2 = new Student(); // 자식 객체인데 부모 타입의 클래스로 만들어줌
// Student s2 = new Person(); 이렇게 사용 못함
p1.print(); // 결과 : Person.print
s1.print(); // 결과 : Student.print
s1.print2(); // 결과 : Student.print2
p2.print(); // 결과 : Student.print
// p2.print2(); 이거는 오류남 왜냐하면 오버라이딩된 부분이 print()이기 때문에 print()까지만 접근 가능
Person p3 = new CollegeStudent();
// CollegeStudent c1 = new Student(); 이렇게 다형성은 안됨
p3.print();
// 2. 타입 변환
System.out.println("== 타입 변환 ==");
Person pp1 = null;
Student ss1 = null;
Person pp2 = new Person();
Student ss2 = new Student();
Person pp3 = new Student(); // 업캐스팅(그래서 실객체는 Student임)
pp1 = pp2;
pp1 = ss2;
ss1 = ss2;
// ss1 = (Student)pp2; 거꾸로는 안됨
ss1 = (Student)pp3; // 다운캐스팅
// CollegeStudent cc1;
// CollegeStudent cc2 = new CollegeStudent();
// ss1 = (Student) cc2;
// cc1 = (CollegeStudent) ss2;
// 3. instanceof
System.out.println("== instanceof ==");
Person pe1 = new Person();
Student st1 = new Student();
Person pe2 = new Student();
Person pe3 = new CollegeStudent();
System.out.println("== instance of ==");
System.out.println(pe1 instanceof Person); // 결과 : true
System.out.println(pe1 instanceof Student); // 결과 : flase
System.out.println(st1 instanceof Student); // 결과 : true
System.out.println(st1 instanceof Person); // 결과 : true
System.out.println(pe2 instanceof Person); // 결과 : true
System.out.println(pe2 instanceof Student); // 결과 : true
System.out.println(pe3 instanceof Person); // 결과 : true
System.out.println(pe3 instanceof CollegeStudent); // 결과 : true
if (pe1 instanceof Student) {
Student stu1 = (Student) pe1;
}
if (st1 instanceof Person) {
Person per1 = (Person)st1;
}
}
}
업캐스팅
: 자식클래스의 객체가 부모 클래스의 타입으로 형변환 되는 것
다운캐스팅
: ppr3의 객체는 Student였으니까 잠깐 업캐스팅돼서 타입만 Person이었으니까 이 타입을 다시 원래 자기 자신인 Student로 타입 변환을 해주면 사용 가능
class Car {
Car(){}
public void horn() {
System.out.println("빵빵!");
}
}
class FireTruck extends Car {
public void horn() {
System.out.println("위이잉!");
}
}
class Ambulance extends Car {
public void horn() {
System.out.println("삐뽀삐뽀!");
}
}
public class Practice {
public static void main(String[] args) {
// Test code
Car car = new Car();
car.horn();
car = new FireTruck();
car.horn();
car = new Ambulance();
car.horn();
// 2번째 방법
// Car car[] = {new Car(), new FireTruck(), new Ambulance()};
//
// for (Car item: car) {
// item.horn();
// }
}
}
abstract void print();
abstract class 클래스명 {
…
abstract void print();
}
// 추상 클래스 Person
abstract class Person {
abstract void printInfo();
}
// 추상 클래스 상속
class Student extends Person {
public void printInfo() {
System.out.println("Student.printInfo");
}
}
public class Main {
public static void main(String[] args) {
// 추상 클래스의 사용
// Person p1 = new Person(); 추상 클래스를 바로 객체로 만드는 것을 안됨
Student s1 = new Student();
s1.printInfo();
Person p2 = new Person() {
@Override
void printInfo() {
System.out.println("Main.printInfo");
}
};
p2.printInfo();
}
}
abstract class Device {
int deviceId;
abstract void deviceInfo();
abstract void connect();
abstract void disconnect();
abstract void send();
abstract void receive();
}
// UsbPort1 클래스
class UsbPort1 extends Device {
UsbPort1(int id) {
this.deviceId = id; // 생성자
}
// 여기서부터는 오버라이딩이 필요한 추상 메소드들
void deviceInfo() {
System.out.println("id = " + this.deviceId);
}
void connect() {
System.out.println("연결 하였습니다.");
}
void disconnect() {
System.out.println("연결이 해제되었습니다.");
}
void send() {
System.out.println("데이터를 전송합니다.");
}
void receive() {
System.out.println("데이터를 수신합니다.");
}
}
// WiFi 클래스
class WiFi extends Device {
public WiFi(int id) {
this.deviceId = id; // 생성자
}
void deviceInfo() {
}
void connect() {
}
void disconnect() {
}
void send() {
}
void receive() {
}
}
public class Practice {
public static void main(String[] args) {
// Test code
UsbPort1 usb1 = new UsbPort1(1);
WiFi wifi = new WiFi(0);
}
}
오버라이딩 유용한 기능
: 우클릭
-> Generate
-> implement
접근제어자 interface 인터페이스이름 {
public static final 타입 상수이름 = 값;
public abstract 반환타입 메소드이름(매개변수);
…
}
class 클래스이름 implements 인터페이스이름 {
…
}
접근제어자 interface 인터페이스이름 {
…
}
접근제어자 class 클래스이름 {
…
}
class 클래스이름 extends 클래스이름 implements 인터페이스이름 {
…
}
// School 인터페이스
interface School {
public static final int MAX_CLASS = 20;
public static final int MAX_PERSON_PER_CLASS = 40;
public abstract void printSchool();
}
// Student 클래스 - School 인터페이스 이용
class Student implements School {
public void printSchool() {
System.out.println("00 University");
}
}
// Person 클래스
class Person {
public String name;
public void printName() {
System.out.println("Name: " + name);
}
}
// Student2 클래스 - Person 상속, School 인터페이스 이용
class Student2 extends Person implements School {
Student2(String name) {super.name = name;}
public void printSchool() {
System.out.println("11 University");
}
}
public class Main {
public static void main(String[] args) {
// 1. 인터페이스 기본 사용
System.out.println("== 기본 인터페이스 ==");
Student s1 = new Student();
s1.printSchool(); // 결과 : 00 University
System.out.println(s1.MAX_CLASS); // 결과 : 20
System.out.println(s1.MAX_PERSON_PER_CLASS); // 결과 : 40
// 2. 다중 상속처럼 사용하기
System.out.println("== Like 다중 상속 ==");
Student2 s2 = new Student2("A");
s2.printSchool(); // 결과 : 11 University
s2.printName(); // 결과 : Name: A
}
}
abstract class GreenOrc {
public final String SKIN_COLOR = "녹색";
public int health;
public int attackDamage;
public int defense;
public abstract void setHealth();
public abstract void setDamage();
public abstract void setDefense();
}
interface NPCSystem {
public abstract void conversationSystem();
public abstract void questionSystem();
}
interface UserSystem {
public abstract void partySystem();
public abstract void tradeSystem();
}
// OrkNPC1 클래스
class OrkNPC1 extends GreenOrc implements NPCSystem {
@Override
public void setHealth() {
this.health = 100;
}
@Override
public void setDamage() {
this.attackDamage = 10;
}
@Override
public void setDefense() {
this.defense = 5;
}
@Override
public void conversationSystem() {
System.out.println("안녕");
System.out.println("요즘 새로운 소식 없나요?");
}
@Override
public void questionSystem() {
System.out.println("새로운 퀘스트");
System.out.println("퀘스트 완료");
}
}
// OrkUser1 클래스
class OrkUser1 extends GreenOrc implements UserSystem {
@Override
public void setHealth() {
this.health = 200;
}
@Override
public void setDamage() {
this.attackDamage = 20;
}
@Override
public void setDefense() {
this.defense = 10;
}
@Override
public void partySystem() {
System.out.println("파티 초대");
System.out.println("파티 수락");
}
@Override
public void tradeSystem() {
System.out.println("거래 신청");
System.out.println("거래 완료");
}
}
public class Practice {
public static void main(String[] args) {
// Test code
// No test code
}
}
class Outer {
…
class Inner {
…
}
}
인스턴스 클래스 (instance class)
: 바깥 클래스를 만들어야 사용 가능정적 클래스 (static class)
: static사용, 바깥 클래스가 없어도 사용 가능지역 클래스 (local class)
: 메소드 안에 클래스가 있음익명 클래스 (anonymous class)
클래스이름 참조변수이름 = new 클래스 이름 () {
…
};
class Outer {
public void print() {
System.out.println("Outer.print");
}
class Inner {
void innerPrint() {
Outer.this.print();
}
}
static class InnerStaticClass {
void innerPrint() {
// Outer.this.print();
}
}
public void outerMethod() {
class InnerLocal {
}
InnerLocal il1 = new InnerLocal();
}
}
abstract class Person {
public abstract void printInfo();
}
class Student extends Person {
public void printInfo() {
System.out.println("Student.printInfo");
}
}
public class Main {
public static void main(String[] args) {
// 외부 클래스
Outer o1 = new Outer();
// 내부 클래스 - 인스턴스
Outer.Inner i1 = new Outer().new Inner();
// 내부 클래스 - 정적
Outer.InnerStaticClass is1 = new Outer.InnerStaticClass();
// 익명 클래스
Person p1 = new Person() {
@Override
public void printInfo() {
System.out.println("Main.printInfo");
}
};
}
}