본문 바로가기

IT自主学習 (2023.05.23~)/Java(2023.05.23~)

プログラミング自主学習 45日目 Class確認問題/継承(Inheritance)/protected/タイプ変換/多態性(ポリモーフィズム・Polymorphism)

Class確認問題

<メソッド宣言>

 

login() =実引数が"hong"、"password"であれば、trueをリータンする。

logout()  = idを受ければ、voidでid+"str"を出力する。

 

package ch06.exam;

 

public class MemberService {

 

String id;

String password;

boolean result;

 

 

public boolean login(String id, String password) {

this.id = id;

this.password = password;

 

if(this.id.equals("hong")&&this.password.equals("12345")) {

result =true;

}

 

return result;

}

 

public void logout(String id) {

System.out.println(id + "님이 로그아웃 되었습니다.");

}

 

}

 

package ch06.exam;

 

public class MemberServiceExample {

 

public static void main(String[] args) {

 

MemberService memberService = new MemberService();

boolean result = memberService.login("hong","12345");

 

if(result) {

System.out.println("로그인 되었습니다.");

memberService.logout("hong");

}

else {

System.out.println("id 또는 password가 올바르지 않습니다.");

}

 

}

 

}

 

<オーバーローディング>

package ch06.exam;

 

public class Printer {

 

public void println(int value) {

System.out.println(value);

}

 

public void println(String value) {

System.out.println(value);

}

 

public void println(double value ) {

System.out.println(value);

}

 

public void println(boolean value) {

System.out.println(value);

}

}

 

 

<静的メソッド>

package ch06.exam;

 

public class Printer {

 

public static void println(int value) {

System.out.println(value);

}

 

public static void println(String value) {

System.out.println(value);

}

 

public static void println(double value ) {

System.out.println(value);

}

 

public static void println(boolean value) {

System.out.println(value);

}

}

 

<シングルトーン>

package ch06.exam;

 

public class ShopService {

 

private static final ShopService singleton = new ShopService();

 

 

private ShopService() {

 

}

 

public static ShopService getInstance() {

return singleton;

 

}

 

}

 

 

<Setter, Getter, Constant>

package ch06.exam;

 

public class Account {

 

private int balance;

private static final int MIN_BALANCE = 0;

private static final int MAX_BALANCE = 1000000;

 

 

 

public void setBalance(int balance) {

if(balance>=MIN_BALANCE && balance<=MAX_BALANCE)

this.balance = balance;

}

 

 

public int getBalance() {

return balance;

}

 

}

 

 

package ch06.exam;

 

public class AccountTest {

 

public static void main(String[] args) {

Account account = new Account();

 

account.setBalance(10000);

System.out.println("현재 잔고: " + account.getBalance());

 

account.setBalance(-100);

System.out.println("현재 잔고: " + account.getBalance());

 

account.setBalance(2000000);

System.out.println("현재 잔고: " + account.getBalance());

 

account.setBalance(300000);

System.out.println("현재 잔고: " + account.getBalance());

 

}

 

}

 

 

継承(inheritance)   

サブクラスのオブジェクトを生成する場合、実はスーパクラスを生成してからサブクラスを生成する。

 

stack                 heap

変数 | データー            サブクラスのオブジェクト ー> スーパクラスのオブジェクト

サブクラスのアドレス                       継承

 

 

<サブクラスのコンストラクタ宣言>

//スーパクラスが基本コンストラクタである場合
public サブクラス(...){
super ();  <-自動的にコンパイル過程で追加される
...
}

//スーパクラスがパラメータがあるコンストラクタを持っている場合
public サブクラス(...){
 super (パラメータ, ...); 

パラメータがあるコンストラクタの場合は、サブクラスにも直接コンストラクタコードを入れる。

 

package ch07.sec03;

 

public class Phone {

//필드 선언

public String model;

public String color;

 

//매개변수를 갖는 생성자 선언

public Phone(String model, String color) {

this.model = model;

this.color = color;

System.out.println("Phone(String model, String Color) 생성자 실행");

}

}

package ch07.sec03;

 

public class SmartPhone extends Phone {

//자식 생성자 선언

public SmartPhone(String model, String color) {

super(model, color); //<- 반드시 작성해야함

System.out.println("smartPhone(String model, String color) 생성자 실행됨");

}

}

 

package ch07.sec03;

 

public class SmartPhoneExample {

 

public static void main(String[] args) {

//SmartPhone 객체 생성

SmartPhone myPhone = new SmartPhone("갤럭시", "은색");

 

//Phone으로부터 상속받은 필드 읽기

System.out.println("모델: " + myPhone.model);

System.out.println("색상: " + myPhone.color);

}

}

 

 

<Overriding>

@Override <- コンパイル時、性格にoverridingができたかをチエック。

source -> Override/implement Methodsで自動生成することもできる。

 

1. メソッドの宣言部は同じだ。(リータンタイプ、メソッド名、パラメータ)

2. アクセス修飾子を強化することはできない。(public -> private X)

3. 新しいExceptionをthrowsすることはできない。

 

package ch07.sec04;

 

public class Calculator {

//메소드 선언

public double areaCircle(double r) {

System.out.println("Carculator 객체의 areaCircle() 실행");

return 3.14159*r*r;

}

}

package ch07.sec04;

 

public class Computer extends Calculator{

//메소드 오버라이딩

@Override

public double areaCircle(double r) {

System.out.println("Computer 객체의 areaCircle 실행");

return Math.PI*r*r;

}

 

}

 

 

package ch07.sec04;

 

public class ComputerExample {

public static void main(String[] args) {

int r = 10;

 

Calculator calculator = new Calculator();

System.out.println(calculator.areaCircle(r));

 

Computer computer = new Computer();

System.out.println(computer.areaCircle(r));

}

}

 

Carculator 객체의 areaCircle() 실행

314.159

Computer 객체의 areaCircle 실행

314.1592653589793

 

<super>

Overridingをした場合は、サブクラスからはスーパクラスのメソッドを見れない。

しかし、またメソッドとして存在しており、その際は、superと.演算子でアクセスすることができる。

 

package ch07.sec04.exam02;

 

public class Airplane {

//메소드 선언

public void land() {

System.out.println("착륙합니다.");

}

 

public void fly() {

System.out.println("일반 비행합니다.");

}

 

public void takeOff() {

System.out.println("이륙합니다.");

}

}

 

package ch07.sec04.exam02;

 

public class SupersonicAirPlane extends Airplane {

//상수 선언

public static final int NORMAL = 1;

public static final int SUPERSONIC = 2;

//상태 필드 선언

public int flyMode = NORMAL;

 

//메소드 재정의

@Override

public void fly() {

if(flyMode == SUPERSONIC) {

System.out.println("초음속 비행합니다");

}else {

//Airplane 객체의 fly() 메소드 호출

super.fly();     //일반 비행합니다

}

}

}

 

package ch07.sec04.exam02;

 

public class SupersonicAirplaneExample {

 

public static void main(String[] args) {

SupersonicAirPlane sa = new SupersonicAirPlane();

sa.takeOff();

sa.fly(); //일반 비행합니다.

sa.flyMode = SupersonicAirPlane.SUPERSONIC;   

sa.fly(); //초음속 비행합니다

sa.flyMode = SupersonicAirPlane.NORMAL;

sa.fly(); //일반 비행합니다.

sa.land(); 

}

}

//상태를 컨트롤 할 상수, 상태, 메소드

//두 개의 상수를 통해서 상태 필드를 설정하고, 메소드는 두 개의 케이스를 나눈다.

이륙합니다.

일반 비행합니다.

초음속 비행합니다

일반 비행합니다.

착륙합니다.

 

<final Class & final method>

public final class String{.....}

宣言時、finalを付けたClassは継承されない。

 

package ch07.sec05.exam01;

 

public final class Member {

 

}

 

package ch07.sec05.exam01;

 

public class VeryImportantPerson {

 

//extends Member <- Compile Error

}

 

public final returntype method( ) { }

宣言時、finalを付けたmethodはoverridingできない。

package ch07.sec05.exam02;

 

public class Car {

 

//필드 선언

public int speed;

 

//메소드 선언

public void speedUp() {

speed += 1;

}

 

//final 메소드

public final void stop() {

speed = 0;

}

}

package ch07.sec05.exam02;

 

public class SportsCar extends Car {

 

@Override

public void speedUp() {

speed += 10;

}

 

//오버라이딩을 할 수 없음

//public void stop() {

//System.out.println("스포츠카를 멈춤");

//speed =0;

}

 

protected

default  or  サブクラスのオブジェクトのみアクセスできる。

 

位置(A=Superclass B=Subclass)  
同じパッケージ 他のクラスも、サブクラスもアクセス可能、
new 演算子スパークラスAのオブジェクトを生成可能
異なるパッケージ

サブクラスのみアクセス可能
new 演算子を使用できないため、
サブクラスのコンストラクタ宣言時に、
コンストラクタでsuper();を使用してAのオブジェクトを生成可能

 

package ch07.sec06.package1;

 

public class A {

//필드 선언

protected String field;

 

//생성자 선언

protected A() {

 

}

 

//메소드 선언

protected void method() {

 

}

 

}

package ch07.sec06.package2;

 

import ch07.sec06.package1.A;

 

public class D extends A{

 

//생성자 선언

public D() {

super();

//super()을 통해 A 생성자 호출

}

 

//메소드 선언

public void method1() {

//A 필드값 변경

this.field = "value"; //this는 A의 객체이다.

//A 메소드 호출

this.method();

}

 

 

//메소드 선언: new 연산자를 통한 A 생성자 호출은 불가능

public void method2() {

//A a = new A();

//a.field = "value"

//a.method();

}

}

 

自動タイプ変換

スパークラス 変数 = new サブクラス();
変数のように、クラスも下位クラスの変数、もしくはオブジェクトはスーパクラスのタイプに自動変換される。

参照:https://www.youtube.com/watch?v=cFMgV8ErZlg

 

 

また、この場合、自動タイプ変換されたサブクラスはスーパクラスのフィールドとメソッドしか使用できない。

ただし、Overridingしたメソッドの場合、Overridingされたメソッドを呼び出す。

これがポイントでオブジェクトの多態性とも関係がある。

 

参照:https://www.youtube.com/watch?v=cFMgV8ErZlg

 

 

 強制タイプ変換(キャスト)

 

一度、自動タイプスーパクラスに変換されたサブクラスのオブジェクトのみ
強制的にまた、元のサブクラスに変換することもできる。 

Parent parent = new Child();
Child child = (Child)parent;

元の、サブクラスのフィールドとメソッドを使用することができる。

参照:https://www.youtube.com/watch?v=cFMgV8ErZlg

 

多態性(ポリモーフィズム)

 

自動タイプ変換 + メソッドオーバーライド

 

同じ使用方法(メソッド)を持っているが、オブジェクトにより、性能(機能)は異なる。

例えば、Tireクラスroll()というメ動作(メソッド)があり、speedを80まで出せると仮定する。

そして、このTireの規格を守って作られたK Tire(Tireを継承)J Tire(Tireを継承)はそれぞれroll()メソッドを

通して95100のspeedを出せるとする。このrun()という動作は同じだが、機能がすこしは違うため、メソッドがオーバーライドされているとも表現できる。

 

K TireJ TireTireと同じ使用方法があるため、Tireを代体することができる。これが多態性のポイントだ。

 

<フィールドの多態性>

 

package ch07.sec08.exam01;

 

public class Tire {

//메소드 선언

public void roll() {

System.out.println("회전합니다.");

}

}

 

package ch07.sec08.exam01;

 

public class KumhoTire extends Tire{

//메소드 재정의(오버라이딩)

@Override

public void roll() {

System.out.println("금호 타이어가 회전합니다.");

}

}

package ch07.sec08.exam01;

 

public class HankookTire extends Tire{

//메소드 재정의(오버라이딩)

@Override

public void roll() {

System.out.println("한국 타이어가 회전합니다.");

}

}

package ch07.sec08.exam01;

 

public class Car {

//필드 선언

Tire tire;

 

//메소드 선언

public void run() {

//tire 필드에 대입된 객체의 roll() 메소드 호출

tire.roll();

}

}

 

<main class>

package ch07.sec08.exam01;

 

public class CarExample {

 

public static void main(String[] args) {

//Car 객체 생성

Car myCar = new Car();

 

//Tire 객체 장착            

myCar.tire = new Tire();

myCar.run();                             -----> 회전합니다.

 

//HankookTire 객체 장착

myCar.tire = new HankookTire();

myCar.run();                             -----> 한국 타이어가 회전합니다.

 

//KumhoTire 객체 장착

myCar.tire = new KumhoTire();

myCar.run();                             -----> 금호 타이어가 회전합니다.

 

}

 

}

 

 

<パラメータの多態性>

package ch07.sec08.exam02;

 

public class Vehicle {

//인스턴스 메소드 선언

public void run() {

System.out.println("차량이 달립니다.");

}

}    

package ch07.sec08.exam02;

 

public class Bus extends Vehicle {

//인스턴스 메소드 재정의

@Override

public void run() {

System.out.println("버스가 달립니다.");

}

}

package ch07.sec08.exam02;

 

public class Taxi extends Vehicle {

//인스턴스 메소드 재정의

@Override

public void run() {

System.out.println("택시가 달립니다.");

}

}

package ch07.sec08.exam02;

 

public class Driver {

//인스턴스 메소드 선언

public void drive(Vehicle vehicle) {

vehicle.run();

}

 

<main class>

package ch07.sec08.exam02;

 

public class DriverExample {

 

public static void main(String[] args) {

//Driver 객체 생성

Driver driver = new Driver();

 

//drive는 인스턴스 메소드이므로 Bus의 객체 생성 후, 매개변수에 객체의 참조값을 대입

Bus bus = new Bus();

driver.drive(bus);

 

//drive는 인스턴스 메소드이므로 taxi의 객체 생성 후,매개변수에 객체의 참조값을 대입

Taxi taxi = new Taxi();

driver.drive(taxi);

}

}

 

버스가 달립니다.

택시가 달립니다.