-다형성 복습: 똑같은 이름을 불렀을 때 다른 결과가 나오는 것.
오버라이딩, ★클래스 형변환★, 오버로딩(매개변수에 따라서 다르게 보여짐)
-클래스 형변환 복습:
자식타입 -> 부모타입(자동형변환)
자식객체+부모객체 -> 부모객체만 사용
부모타입 -> 자식타입(강제형변환)
부모객체 -> 자식객체 + 부모객체(처음부터 부모객체 만들어진 것은 형변환 안됨. 오류!)
자식객체+부모객체 -> 부모객체만 사용 후
부모객체 -> 자식객체+부모객체
반드시 자식객체로 만들어진 부모타입만 자식타입으로 변환가능
배열이 너무 많이 만들어지면 메모리 낭비가 되고, 배열이 너무 적게 만들어지면 새로운 배열을 또 다시 만들고 그 배열로 코드를 수정해야되기 때문에 굉장히 비효율적.
이걸 보완한 것이 List
-순서를 유지하고 저장.
-중복 저장 가능
ArrayList(자료형 a);
ArrayList<Object> 객체명 = new ArrayList<Object>( );
모든 객체 종류가 다 들어올 수 있음
package product03;
import java.util.ArrayList;
public class Buyer2 {
int money = 500;
int bonusPoint;
ArrayList<Object> item = new ArrayList<Object>();
void buy(Product p) {
if(money < p.price) {
System.out.println("잔액이 부족합니다.");
return;
}
money -= p.price;
bonusPoint += p.bonusPoint;
item.add(p); //ArrayList에 삽입은 add로
System.out.println(p + "를 구입하였습니다.");
}
void refund(Product p) {
if(item.remove(p)) { //안 샀는데 반품해달라고 할 수 있으니 if문
money += p.price;
bonusPoint -= p.bonusPoint;
System.out.println(p + "를 반품하였습니다.");
}
else
System.out.println("구입한 물품이 아닙니다.");
}
void summary() {
int sum = 0;
String itemList = "";
if(item.isEmpty()) {
System.out.println("구입한 물품이 없습니다.");
return;
}
for(int i=0; i<item.size(); i++) {
Product p = (Product)item.get(i);
//물품들을 부모타입으로 형변환, ArrayList의 index번호의 객체를 얻어올 때 get(index)메서드
sum += p.price;
itemList += p + ", ";
}
System.out.println("총 구입금액: " + sum);
System.out.println("구입 물품들: " + itemList);
}
}
많이 사용함!!!!
클래스가 '설계도'라면 추상클래스는 '미완성 설계도'
미완성이라 인스턴스(객체)를 생성할 수 없다.
추상메서드(선언부만 있고 구현부가 없는 메서드)를 하나라도 가지고 있으면 추상클래스
-다른 클래스를 작성하는데 도움을 주는 역할.
abstract 리턴타입 메서드명( );
딱 여기까지만 적음
-큰 프로젝트 안에서 각각 다른 팀들이 프로그래밍 할 때 메서드 이름들의 기준을 정해주므로 호출할 때 같은 이름으로 구현할 수 있음.
-추상클래스를 상속받는 자손클래스에서 추상메서드의 구현부를 완성해야한다.
package abstract01;
public abstract class Animal {
String kind;
void breathe() {
System.out.println("숨을 쉽니다.");
}
abstract void sound();
}
package abstract01;
public class Dog extends Animal {
Dog() { //생성자
kind = "포유류";
}
@Override
void sound() { //추상메서드 구현부 완성
System.out.println("멍멍");
}
}
package abstract01;
public class Cat extends Animal {
Cat() {
kind = "포유류";
}
//이름이 같으면 @Override 없어도 가능 근데 그러면 스펠링 조심해라
void sound() {
System.out.println("야옹");
}
}
package abstract01;
public class Pish extends Animal {
Pish() {
kind = "어류";
}
void sound() {
System.out.println("뻐끔");
}
}
package abstract01;
public class AnimalTest {
public static void main(String[] args) {
Dog dog = new Dog();
Cat cat = new Cat();
Pish pish = new Pish();
dog.sound();
cat.sound();
pish.sound();
System.out.println("----------------------------");
//추상클래스는 객체 생성 안 됨.
//Animal a = new Animal();
//자식을 부모로 형변환은 가능
Animal ani = dog; // 오버라이딩은 무조건 자식의 값이 호출됨
ani.sound();
ani = cat;
ani.sound();
ani = pish;
ani.sound();
System.out.println("----------------------------");
aniSound(new Cat());
aniSound(new Dog());
aniSound(new Pish());
}
static void aniSound(Animal ani) { //여러번 호출하는 것들은 메소드로 정의해놓고 여러번 호출 가능
ani.sound();
}
}
interface 인터페이스명 {
public static final타입 상수명(대문자) = 값;
}
★인터페이스 안에 상수를 쓰려면 public static final
을 무조건!!! 써야함. 명시 안 해도 컴파일 과정에서 자동으로 붙음
extends 대신 implemets를 쓰고 여러개를 상속받을 수 있다.
public class 구현클래스명 implements 인터페이스A, 인터페이스B, 인터페이스C
package interface02;
//클래스에서 인터페이스를 상속받을 때 키워드 implements 사용
//인터페이스는 여러개 동시 상속 가능
public class InterClassA implements InterfaceA{
//public class InterClassA implements InterfaceA, InterfaceB{ }
@Override
public void methodA() {
// TODO Auto-generated method stub
}
@Override
public void methodA1() {
// TODO Auto-generated method stub
}
}
extends를 쓰고 여러개를 상속받을 수 있다.
interfce 인터페이스명 extends A, B, C
package interface02;
public interface InterfaceA {
public static final int MAX = 100;
int MIN = 0; //public static final 생략해도 컴파일시 자동으로 붙음
public void methodA(); //구현문이 있는 메소드가 있으면 안 됨
public void methodA1();
}
package interface02;
public interface InterfaceB {
void methodB();
void methodB1();
}
package interface02;
public interface Interface extends InterfaceA, InterfaceB {
void method();
}
*연습문제*
1.tv인터페이스: 상수- 최대채널,최소채널
2.추상메서드 tv 전원 on/off, 채널(채널값)
3.smartTv인터페이스: 영화검색()
4.class는 인터페이스 2개 상속
5.main함수에서 class객체 생성하여 실행
-default void 메서드 :
나중에 필요한 기능을 메서드 추가할 때, 오버라이딩을 구현해도되고 안 해도 되는 메서드
default void internet(String url) {
System.out.println("인터넷 보기");
}
-static void 메서드:
static 메서드랑 똑같음.
static void sInter() {
System.out.println("kkkkk");
}
public static void main(String[] args) {
static void method(Phone phone) { //매개변수를 부모타입으로 해놓으면 부모든 자식이든 객체 생성 가능
phone = new SmartPhone();
}
}
try {
예외가 발생할 상황
} catch(Exception e(모든 예외를 다 넣을 수 있음)) {
예외가 발생했을 때 처리할 것
}
public static void main(String[] args) {
System.out.println(1);
System.out.println(2);
try {
//예외가 발생할 상황을 넣어줌
int result = 5/0;
//예외가 발생하지 않으면 밑에 것 처리
System.out.println(3);
System.out.println(4);
} catch(Exception e) { //모든 예외를 다 넣을 수 있음
//예외가 발생했을 때 처리할 것을 넣어줌
System.out.println("0으로 나눌 수 없습니다.");
System.out.println(5);
}
System.out.println(6);
}
=> 오류가 났다면
1
2
0으로 나눌 수 없습니다.
5
6
오류가 나지 않았다면
1
2
3
4
6
public static void main(String[] args) {
try {
String data = null;
System.out.println(data.toString());
}catch(NullPointerException e) {
System.out.println("데이터가 없습니다.");
System.out.println("메세지: " + e);
}
}
=> 데이터가 없습니다.
메세지: java.lang.NullPointerException: Cannot invoke "String.toString()" because "data" is null
public static void main(String[] args) {
String[] str = {"a", "b", "c"};
try {
str[1] = "d";
str[6] = "e"; //오류인데 빨간 밑줄 안 생김. 실행 때 오류남.
} catch(ArrayIndexOutOfBoundsException e) {
System.out.println("배열의 크기를 넘어섰습니다.");
}
}
=> 배열의 크기를 넘어섰습니다.