객체의 확장
클래스의 인스턴스인지를 확인하는 연산
Member m1 = new Member("LGH", "010-3446-5555");
System.out.println(m1 instanceof Object);
//모든 클래스는 Object를 상속 받는다
// extends Object 안써두 됨
//상속 할 경우에는 Memeber 변수와 method 만 상속
class Member extends Object {
String name, mobile;
public String toString() {
return String.format("Name : %s , Mobile : %s", name, mobile);
}
public Member(String name, String mobile) {
this.name = name;
this.mobile = mobile;
}
}
상속 관계(has -a / is-a)
has- a 관계
Car는 Engine을 가지고 있을 뿐이지, car와 engine은 공통된 속성과 기능을 가지지 않음(비공유)
//has-a 관계
class Car {
Engine engine = new Engine();
}
class Engine {
int gitong;
}
is - a 관계
parent와 chile는 공통된 속성과 기능을 공유한다
//is-a 관계
class Parent {
String familyName;
}
class Child extends Parent {
}
자바에서는 다중상속 허용하지 않음(명확하지 않을 수 있기 때문에) - 단일 상속
class SmartPhone extends Phone, Computer { } //에러 발생(사용불가)
상속은 멤버변수와 메서드만 전달이 가능하다
추상클래스는 스스로 인스턴스 생성 불가능함
상속 받은 후 인스턴스 생성이 가능하다
package p05_Inherit;
public class Ex03extentds {
public static void main(String[] args) {
Marin m1 = new Marin();
System.out.println(m1.hp);
}
}
//abstract 추상적인 클래스
abstract class Unit {
public Unit(){
//this(), super()는 항상위(맨첫줄)에 있어야 하기 떄문에 두개를 동시에 사용이 불가능하다
super();
//this("","",15);
System.out.println("야생 동물 생성");
}
public Unit(String tribe){
super();
this.tribe = tribe;
}
int hp;
String tribe;
public void mov(int x, int y) {
}
public void stop() {
}
}
//abstract 를 사용하면 new/인스턴스 를 사용하지 못함
abstract class Terran extends Unit {
//상속 할 경우에는 Memeber 변수와 method 만 상속
public Terran(String uName, int hp) {
//첫줄에 " super() = 부모를 가리킴 "가 숨어있음
super("Terran",uName,hp); //Unit을 가리키고 있음
}
}
class Marin extends Terran {
public Marin() {
super("Marin",60);
}
}
class Medic extends Terran {
public Medic() {
super("Medic",45);
}
}
this(), super()는 항상위(맨첫줄)에 있어야 하기 떄문에 두개를 동시에 사용이 불가능하다
public Unit(){
super();
System.out.println("야생 동물 생성");
}
public Unit(){
this("","",15);
System.out.println("야생 동물 생성");
}
상속관계의 형변환
public class Ex04Casting {
public static void main(String[] args) {
Father f1= new Father();
Son s1= new Son();
s1.hard();
//상속관계의 형변환
Father f2 = new Son();//자식 -> 부모 형변환이 일어나서 가능함
//Son s2 = new Father(); //부모 -> 자식 Error :: s2 >= f2
//Son s2 = (Son)new Father(); //실행 시 ,Error :: s2 >= f2
Son s3 = (Son)f2; //자식 -> 부모 -> 자식
}
}
상속관계의 형변환에서 변수와 메서드의 중복이 일어나는 경우
변수는 형변환 된, 타입의 값을 가진다
메서드는 무조건 자식의 메서드를 따른다
속성값은 부모의 값을 가짐
f2.hard();
System.out.println(f2.age);
s3.hard();
System.out.println(s3.age);
public class Ex04CastingReason {
public static void main(String[] args) {
Buyer person = new Buyer();
person.money =1000;
Tv tv = new Tv();
Laptop laptop = new Laptop();
Audio audio = new Audio();
person.Buyer_Buy(tv.price);
System.out.printf("남은돈 1: %d \n",person.money);
person.Buyer_Buy(laptop.price);
System.out.printf("남은돈 2: %d \n",person.money);
person.Buyer_Buy(audio.price);
System.out.printf("남은돈 3: %d \n",person.money);
}
}
class Buyer{
int money;
int Buyer_Buy(int price){
return money -= price;
}
}
class Tv{
int price=20;
}
}
class Laptop {
int price=30;
}
}
class Audio {
int price=40;
}
오버라이드(Override) : 재정의
package p05_Inherit;
import java.util.Objects;
public class Ex05Override {
public static void main(String[] args) {
Data d1 = new Data(1);
Data d2 = new Data(1);
System.out.println(d1);
System.out.println(d2);
//주소값이 같아서 ,출력되지 않음 => 숫자를 비교함
if (d1 == d2) {
System.out.println("같다");
}
//equals를 재정의 해주어야함
if (d1.equals(d2)) {
System.out.println("같다");
}
}
}
class Data {
int value;
public Data(int value) {
this.value = value;
}
@Override
public String toString() {
return "value : " + value;
}
// @Override // 생략 가능
public boolean equals(Object obj) {
if (obj instanceof Data) {
Data d = (Data) obj;
return value == d.value;
}
return false;
}
@Override
public int hashCode() {
//hashCode의 값이 동일할 때
return Objects.hash(value);
}
}
Interface
java에서는 다중상속이 안된다. 그래서, interface를 사용한다
앞에 i 를 붙이거나 끝에able을 붙이면서 interface를 사용하겠다는 의미이다 -> 약속
class Hydra implements AttackAirable, AttackGroundable {
@Override
public void attack() {
}
}
interface AttackAirable {
//추상메서드와 상수만 정의(static, default 메서드 추가)
public abstract void attack();
}
interface AttackGroundable {
void attack();
}
정의 해주지 않으면 다음과 같이 빨간줄이 생김
interface의 중복된 상수는 static 이 붙어 있기 때문에 클래스와 함께 지정
static과 default 메서드만 선언이 가능함
@Override
public void attack() {
//interface의 중복된 상수는 static 이 붙어 있기 때문에 클래스와 함께 지정
System.out.println(AttackGroundable.Level);
}
interface AttackAirable {
//추상메서드와 상수만 정의(static, default 메서드 추가)
public abstract void attack();
public static final int Level =10;
}
interface AttackGroundable {
void attack();
void attackG();
int Level =30;
}
참조형 타입의 형변환은 상속관계일 때, interface 일 경우 적용
객체지향 언너의 특징중 하나인 다형성(Polymorphism)
package p05_Inherit;
import common.Utils;
import java.util.Objects;
public class Ex08InterfaceCasting {
public static void main(String[] args) {
Mammals[] mammals = {new Dog(), new Cat(), new Bat()};
Birds[] birds = {new Chicken(), new Eagle(), new Parrot()};
Flyable[] flyables = {new Bat(), new Eagle(), new Parrot()};
IGround[] grounds = {new Dog(), new Cat(), new Chicken()};
}
}
interface Flyable {
}
interface IGround {
}
class Birds {
}
class Parrot extends Birds implements Flyable {
}
class Eagle extends Birds implements Flyable {
}
class Chicken extends Birds implements IGround {
}
class Mammals {
}
class Dog extends Mammals implements IGround {
}
class Cat extends Mammals implements IGround {
}
class Bat extends Mammals implements Flyable {
}
Java Casting
1) 기본형
2) 참조형 (상속, Interface)
3) 기본형 <-> 참조형
Object obj =10; //기본형 -> 참조형으로 형변환
Utils.typeOf(obj); //Integer
추상클래스(Abstract)
package p05_Inherit;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Ex09Abstract {
public static void main(String[] args) {
//스스로 인스턴스 생성 불가 (추상클래스, interface)
//Abstract abs = new Abstract();
//Interface inter = new Interface();
new MyFrame();
}
}
//추상클래스 : 스스로 인터페이스를 못만듬
//abstract 공통(표준)으로 사용하기 위해 만듦. 인스턴스 생성 불가
abstract class Abstract {
int num = 10;
void general() {
}
//추상 메서드를 사용할 경우, 반드시 abstract 붙임
abstract void special();
}
interface Interface {
}
class MyFrame extends JFrame {
public MyFrame() throws HeadlessException {
setSize(300, 200);
setTitle("My Window");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setLayout(new FlowLayout());
JButton jButton = new JButton("확인");
jButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Hello");
}
});
add(jButton);
setVisible(true);
}
}
접근 제어자 (Access Modifier) : public , protected , default, private
클래스 public , default, final, abstract
메서드 all , final,(abstract, static = 재정의 불가)
멤버변수 all, final(상수), static
지역변수 final, var
지역변수는 접근 제어자 사용 불가
public String publicVar;
protected String protectedVar;
String defaultVar;
private String privateVar;
메서드 앞에도 접근제어자 4가지 다 사용이 가능하다
default 접근제어자는 패키지 안에서만 사용이 가능하다
final이 class 앞에 붙을 때 제어자는 상속이 안된다
protected는 패키지 안에서도 사용이 가능하지만 상속이 된 곳에서만 사용이 가능하다
상속을 받을 값을 변수에 담아서 사용해야함
public class Ex10protected extends Ex10Modifier {
String str = protectedVar;
Ex10Modifier ex10Modifier = new Ex10Modifier();
void done(){
System.out.println(ex10Modifier.publicVar);
System.out.println(str);
//System.out.println(ex10Modifier.defaultVar);
//System.out.println(ex10Modifier.privateVar);
}
}
지역 변수를 익명객체에서 쓸 때, final 붙인다
(java 8 부터 안 붙여도 됨)
final 이 붙은 지역변수는 변경 불가능하다
public static void main(String[] args) {
final int result = 10;//final이 붙은 지역변수는 변경불가
new JButton().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(result); //상수라서 사용은 가능하지만
// result =10; //지역변수는 익명객체에서 변경이 불가능하다
}
});
지역변수는 익명객체에서 변경이 불가능하다
Java 10 부터 var 생김
지역변수 일 때, 동적할당이 가능하다
var name ="LGH";
Utils.typeOf(name);
선언과 동시에 초기화 분리 적용은 되지 않는다
싱글톤(Singleton)
package p05_Inherit;
public class Ex11Singleton {
public static void main(String[] args) {
Singleton s1 = new Singleton();
Singleton s2 = new Singleton();
System.out.println(s1);
System.out.println(s2);
}
}
//인스턴스를 하나만 사용 할수 있게 만들고 싶음
class Singleton{ }
인스턴스를 하나만 사용할 수 있도록 만들기 위해서
'싱글톤' 을 사용한다
package p05_Inherit;
public class Ex11Singleton {
public static void main(String[] args) {
Singleton s1 = Singleton.getInstance();
//Singleton s2 = new Singleton();
System.out.println(s1);
//System.out.println(s2);
}
}
//인스턴스를 하나만 사용 할수 있게 만들고 싶음
class Singleton{
private static Singleton singleton;
private Singleton() {
}
static public Singleton getInstance(){
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
클래스 내부 값 가져오기?
package p05_Inherit;
public class Ex12Inner {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner oi = new Outer().new Inner();
System.out.println(oi.iv);
//static
Outer.InnerStatic ois = new Outer.InnerStatic();
System.out.println(ois.isv);
}
}
class Outer {
class Inner {
int iv = 100;
}
void outerMethod() {
class LocalInner {
int localInnerVar = 300;
}
}
static class InnerStatic {
int isv = 200;
}
}
trycatch 문
package p05_Inherit;
public class Ex13trycatch {
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(10/0);
System.out.println(5);
System.out.println(6);
System.out.println(7);
System.out.println(8);
}
}
다음 코드를 실행하면 예외 처리가 발생함
예외 처리 할 블럭을 선택하고
[ Ctrl+alt + T ]를 사용해서 블럭을 만들어줄 수있다
에러가 발생하더라도 다음 코드로 진행한다
try 안에있는 System.out.println(4); 은 출력하지 않고 다음코드로 진행됨
package p05_Inherit;
public class Ex13throws {
public static void main(String[] args) {
method1();
System.out.println("main");
}
private static void method1() {
method2();
System.out.println("method1");
}
private static void method2() {
method3();
System.out.println("method2");
}
private static void method3() {
try {
throw new Exception();
} catch (Exception e) {
//throw new RuntimeException(e);
System.out.println("method3");
}
}
}
throws 는 책임을 회피하는
private static void method3() throws Exception{
try {
throw new Exception();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
모든 메소드에 throws 처리를 하면 JVM에서 에러를 내보낸다
method 재정의 할 때 접근 제어자의 범위는 같거나 넓어야한다
범위 : private <default < protected < public
Child2.default가 Parent2.protected 보다 범위가 작기 떄문에 에러가 발생
class Parent2 {
protected void methode() throws ArithmeticException, IOException {
}
}
class Child2 extends Parent2 {
@Override
protected void methode() throws ArithmeticException, IOException {
super.methode();
}
}
throws는 같거나 많아야 한다
class Parent2 {
protected void methode() throws ArithmeticException, IOException {
}
}
class Child2 extends Parent2 {
protected void methode() throws ArithmeticException, IOException {
}
}
예외 처리를 만들어서 메세지 보내는 방법
public class Ex15MyException {
public static void main(String[] args) {
try {
throw new MyException("내가 발생 시킨 에외");
} catch (MyException e) {
//throw new RuntimeException(e);
System.out.println(e.getMessage());
}
}
}
class MyException extends Exception{
public MyException(String message) {
super(message);
}
}
Exception 을 상속 받았기 때문에 throw 사용한다
ctrl+shift+f
프로젝트 안에있는 코드를 찾을 수 있음