package chapter05;
class Shape{
public void draw() {
System.out.println("Shape");
}
}
class Line extends Shape{
//@Override // annotation (어노테이션) => 시스템 주석(명시적), 생략 가능
public void draw() {
System.out.println("Line");
}
}//확장,상속
class Rect extends Shape{
//@Override // 시스템 추적(명시적), 생략 가능
public void draw() {
System.out.println("Rect");
}
}//확장,상속
class Circle extends Shape{
//@Override // 시스템 추적(명시적), 생략 가능
public void draw() {
System.out.println("Circle");
}
}//확장,상속
public class MethodOverridingEx {
static void paint(Shape p) {
// 직접 여기서 객체 생성은 한건 아니지만 비슷하게
//아래의 Shape shape = new Shape();를 받아서 옴
p.draw();
}
public static void main(String[] args) {
// Shape shape = new Shape();//객체 생성 -> 생성자가 만들어짐.
// Line line = new Line();//객체 생성 -> 생성자가 만들어짐.
// Shape shape = new Line();// 업캐스팅
// (Line객체이지만 슈퍼클래스인 Shpae 영역의 속성과 함수만 쓰겠다.)
// paint(shape); // 출력값 :Shape
// paint(new Shape()); // 출력값 :Shape
// paint(line); // 출력값 :Line
// paint(shape); // 출력값 :Line
// paint(shape); // 출력값 :Shape
// if) public void draw() {
// System.out.println("Line");
// } 하게 되면 Shape가 출력
paint(new Rect());//출력값 :Rect, 객체 생성 하고 바로 메소드 로 넣어버림
paint(new Circle());//출력값 : Circle, 객체 생성 하고 바로 메소드 로 넣어버림
}
}
package chapter05;
class Weapon{
protected int fire() {
//protected는 다른 패키지 있으면 상속 받게 해주기도 하고 접근 제한자로서의 역할도 한다.
return 1;
}
}
class Cannon extends Weapon{
protected int fire() {
return 10;
}
}//Weapon에서 Cannon으로 상속 받음(fire 사용 가능)
public class Overriding {
public static void main(String[] args) {
Weapon weapon;//클래스와 참조변수 //객체 선언
weapon = new Weapon();//객체 생성
System.out.println("기본 무기의 살상 능력은 "+weapon.fire());
// 기본 무기의 살상 능력은 1 출력
weapon = new Cannon();//업캐스팅!(Cannon이지만 weapon의 영역의 속성및 메소드를 사용하겠다.
System.out.println("대포 무기의 살상 능력은 "+weapon.fire());
//대포 무기의 살상 능력은 10 출력
}
}
package chapter05;
import java.util.Random;
public class TwoDArray {
public static void main(String[] args) {
int twoarray[][] = new int [4][4];
Random com = new Random();
//System.out.println(number);
for (int i = 0; i < twoarray.length; i++) {
System.out.println();// 4*4 배열이 나오겠끔 띄어쓰기
for (int j = 0; j < twoarray[i].length; j++) {
int number = com.nextInt(10)+1;
// 랜덤 한 숫자 나오게 함(만약에 밖에 있으면 한개의 숫자만 랜덤 선택됨)
twoarray[i][j]=number;// 배열에 랜덤한 숫자 삽입
System.out.print(twoarray[i][j]+" "); // 출력
}
}
// 강사님 방법
// for (int i = 0; i < twoarray.length; i++) {
// for (int j = 0; j < twoarray.length; j++) {
// twoarray[i][j]=(int) (Math.random()*10+1);
// System.out.println(twoarray[i][j] +"\t");
// }
// System.out.println();
// }
}
}
배열과 반복문
정수를 몇개 저장할 지 개수를 입력받아(100이하의 개수) 정수 배열을 생성하고 1~100까지 범위의 정수를 랜덤 삽입 후 출력
package chapter05;
import java.util.Random;
import java.util.Scanner;
public class RandomArray {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("정수 몇개?");
int number = scanner.nextInt();
Random com = new Random();
int intarray[]= new int [number];
for (int i = 0; i < intarray.length; i++) {
int ranNum = com.nextInt(100)+1;
intarray[i]=ranNum;
System.out.print(intarray[i]+" ");
}
for (int i = 0; i < intarray.length; i++) {
if (i==0) {
System.out.println(intarray[i]+" ");
}else {
if (i%10 ==0) {
System.out.println();
}
System.out.println(intarray[i]+" ");
}
}
scanner.close();
}
}
: 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드
위와 같이 {} 없이 ()로 끝나는 메소드(선언부만 작성하고, 구현부는 작성하지 않은 채로 남겨둔 형태)
? 왜 이렇게 미완성으로 남겨놓는가?
메소드의 내용이 상속받는 클래스에 따라 달라질 수 있기 때문(보통은 주석을 덧붙여 어떤 기능을 수행할 목적으로 작성되었는지 알려주고 실제 내용은 상속 받는 클래스에서 구현하도록 비워놓는 경우가 많음)
두가지의 추상 클래스 사례
추상 클래스 및 추상 메소드를 선언하는 방법은 class, return type 앞에 abstract를 선언하면 된다.
(추상메소드가 포함 되지 않아도 astract class로 선언 되면 추상 클래스로 인지됨)
추상 클래스는 객체를 생성하지 않는다.
(이유 : 실체성이 없고 구체적이지 않음)
(하단에 예시에 상세하게 주석 달아 놓았음)
단순 상속
위의 경우 오버라이딩x
추상 클래스를 구현하지 않았으면 추상 클래스가 됨.
구현하면 일반클래스가 됨.
구현 상속
서브 클래스에서 슈퍼클래스의 추상 메소드 구현(→오버라이딩)
즉, 오버라이딩해서 구현을 하는 경우가 해당됨.
서브 클래스는 추상 클래스가 아닌 일반 클래스가 됨
여기서 보면 Line, Rect,Circle은 추상클래스 Shape를 상속 받아 만든 서브(하위)클래스
draw()를 오버라이딩
하여 구현한 예시
그래서 Line, Rect,Circle는 추상 클래스가 아니며, 객체 생성이 가능함.
: 일종의 추상클래스로, 추상 메소드와 상수만을 멤버로 가질 수있다.
추상 클래스를 미완성 설계도라고 한다면 인터페이스는 구현된것은 아무것도 없고 밑그림만 그려져 있는 기본 설계도
확장
이라는 뜻을 가진 extends
가 아닌 구현
한다는 의미의 implements
를 사용return 타입이 인터페이스라는 것은 메소드가 해당 인터페이스를 구현한 클래스의 인스턴스를 반환한다는 것을 의미
(+)아직 인스턴스와 객체의 차이점을 잘 모르겠음. 공부가 필요함
(복잡하니 잘 이해해야함)
package chapter05;
public class Main {
public static void main(String[] args) {
Animal a;//클래스 Animal의 참조변수 a //선언
//a=new Animal();//이케 적으면 오류발생함.
//왜냐하면 Animal은 추상 클래스이기 때문에 객체 생성이 되지 않아 오류 발생
Bird b;//Bird 클래스의 b라는 참조변수 //선언
//b = new Bird();//이케 적으면 오류발생함.
//왜냐하면 Bird은 추상 클래스이기 때문에 객체 생성이 되지 않아 오류 발생
// Penguin p;//선언
// p = new Penguin();//Penguin은 추상 클래스가 아니니깐 객체 생성 가능
Penguin p = new Penguin();//선언과 동시에 생성
p.swim();
Bird p2 = new Penguin();//업캐스팅 //객체 생성 가능
// p2.swim();// 불가능. 이유 : 업캐스팅해서 Bird에 있는 것들만 가능함. Bird에는 swim 메소드 없음
p.walk();
Penguin p3 =(Penguin) p2;//다운 캐스팅!!
p3.swim();// 다운 캐스팅해서 이제 Penguin안에 있는 swim 메소드 사용 가능
// Duck d = new Duck();
Bird d= new Duck();//업캐스팅
d.eat();
Duck d2 = (Duck) d;//다운캐스팅
d2.fly();
d2.swim();
Bird d3= new Duck();//업캐스팅
int x = d3.life;//여기서 x는 1
System.out.println("x===> "+x);
// Swim3 s =new Swim3();//인터페이스는 객체 생성 불가능(인터페이스는 추상클래스이지만 static와 같이 공유 속성을 가지고 있음)
Swim3 s = new Penguin(); //업캐스팅
// 이부분 내가 이해를 잘 못해서 풀어서 설명함.
// 왜???? 위의 Swim3 s =new Swim3();는 객체 생성이 불가능하고, Swim3 s = new Penguin(); 는 객체생성가 가능한가에 대한 질문
//좌변은 상관없는데, 우변은 실체를 가지고 있어야지만 객체 생성 가능
// Swim3 s =new Swim3();에서 우변은 인터페이스. 인터페이스는 뭐다?
// 공유 속성을 가진 추상클래스
// 그래서 실체가 존재하지 않음. 실체가 존재하지 않는데 어떻게 객체가 생성됨?
// 안되는거임. 그러나Swim3 s = new Penguin();에서
// 우변인 팽귄은 일단 실체가 존재함.(추상클래스가 아님) 그래서 객체 생성 가능
s.swim();// 타입은swim3 이고 출력은 펭귄 수영
// s라는 펭귄이 생성(객체생성) 여기서 이제 메소드를 불러와서 출력됨.
Swim3[] s2=new Swim3[2];//0,1 인덱스 길이 2(공간 2개 생성)//배열 생성, 객체생성x
// 참조변수를 2개 생성한거임. 객체 생성한게 아니라, 점 생성
s2[0]= new Penguin();//각각의 점에 객체를 생성한거임. 이건 가능함.
s2[1]= new Duck();//각각의 점에 객체를 생성한거임. 이건 가능함.
// s2[2]= new Duck();//인덱스 초과!!!!!!! 멀쩡한것 처럼 보이지만 실행시 오류가 발생함.
}
}
출력 결과
package chapter05;
public interface Swim3 {
abstract void swim();
}
package chapter05;
public interface Fly2 {
abstract void fly();
}
package chapter05;
public class Duck extends Bird implements Swim3, Fly2{
//여기까지 펭귄 안에 필드는 4개(상속 받은 4개)(생명, 날개(속성), 걷다,먹다(메소드))
@Override
public void swim() {
System.out.println("duck swims");
}
@Override
public void fly() {
System.out.println("duck fly");
}
// 이제는 6개의 필드 존재.(상속 4개 오버라이딩 (인터페이스) 2개
}
package chapter05;
abstract class Bird extends Animal {//상속//추상메소드
public int wing =2;//속성 필드
//총 속성 필드 2개 (상속받는 속성 필드 1개, 위의 속성 필드 1개)
public void walk() {
System.out.println("walk");
}
public void eat() {
System.out.println("eat");
}
//메소드 2개
}
package chapter05;
public class Penguin extends Bird implements Swim3{
//여기까지 펭귄 안에 필드는 4개(상속 받은 4개)(생명, 날개(속성), 걷다,먹다(메소드))
@Override
public void swim() {
System.out.println("penguin swims");
}//메소드 하나 추가됨
}
package chapter05;
public abstract class Animal {// 추상 클래스
public int life = 1; // 속성 필드
}package chapter05;
public interface Fly2 {
abstract void fly();
}
정리하자면
이러고 있음
getArea 메소드를 갖는 Trapeziod 클래스 생성해서 구하기
package chapter05;
import java.util.Scanner;
class Trapezoid{
int down;
int up;
int height;
public double getArea() {
return ((down+up)*height)*0.5;
}
}
public class Rect_area_1 {
public static void main(String[] args) {
Trapezoid area = new Trapezoid();//객체 생성
Scanner scanner = new Scanner(System.in);
System.out.println("아랫변을 입력하시오");
area.down = scanner.nextInt();
System.out.println("윗변을 입력하시오");
area.up = scanner.nextInt();
System.out.println("높이를 입력하시오");
area.height = scanner.nextInt();
System.out.println("사다리꼴의 면적은"+area.getArea());
scanner.close();
}
}
package chapter05;
public class ArratParameterEx {
static void printStringArray(String c[]){
for (int i = 0; i < c.length; i++) {
System.out.print(c[i]);
}
System.out.println();//to be or not to be 출력
}
static void replaceBe(String c[]) {//be를 eat로 바꿈
for (int j = 0; j < c.length; j++) {
if (c[j]=="be") {
c[j]="eat";
}
}System.out.println();
}
public static void main(String[] args) {
String b [] ={"to"," ","be"," ","or"," ", "not"," ","to"," ","be"};
printStringArray(b);
replaceBe(b);;//replaceBe설정
printStringArray(b);//replaceBe값이 나옴
}
}
: 클래스 안에 다른 클래스를 정의 하는 것
package chapter05;
class OuterClass{//순서2
// public String secret="Time is money";
private String secret="Time is money";
public OuterClass() {//기본 생성자
InnerClass obj = new InnerClass(); //객체생성
obj.method();
}
public class InnerClass{//순서3 =>내부클래스의 생성자입니다.출력
public InnerClass() {
System.out.println("내부클래스의 생성자입니다.");
}
public void method() {
System.out.println(secret);
}
}
}
public class OuterClassTest {
public static void main(String[] args) {
OuterClass f= new OuterClass();//객체 생성 //public private 상관없이 접근 x
//순서1
}
}
:클래스 몸체는 정의 되지만 이름이 없는 클래스
package chapter05;
interface RemoteControl{
void turnOn();//추상 메소드
void turnOff();//추상 메소드
}
public class AnonymousClassTest {
public static void main(String[] args) {
// new RemoteControl() ;
RemoteControl rc = new RemoteControl() {//객체 생성된거지만 무명 클래스임
@Override
public void turnOn() {
System.out.println("TV turnOn()");
}
@Override
public void turnOff() {
System.out.println("TV turnOff()");
}} ;
rc.turnOn();
rc.turnOff();
}
}