Javaを09(インタフェース、継承、インタフェース、継承)に設定
インタフェース(残り)
Interface variable
変数はすべて自動的にpublic static final変数になります.したがって,これらの変数は利用可能であり,クラスの実値に関係なくfinalは値を変更しないため定数のように使用できると考えられる.interface Motion{
int NORTH = 1;
int EAST = 2;
int SOUTH = 3;
int WEST = 4;
void move(int direction);
int getX();
int getY();
}
class TwoDMotion implements Motion {
private int posX, posY;
public TwoDMotion() { posX = 0; posY = 0; }
// 여기와 같이 interface의 변수들이 상수처럼 사용되고 있다.
public void move(int direction) {
if(direction == NORTH) posY--;
else if(direction == SOUTH) posY++;
else if(direction == EAST) posX++;
else if(direction == WEST) posX--;
}
public int getX() { return posX; }
public int getY() { return posY; }
}
Interface method
現在、interfaceの関数はabstract関数と呼ばれていますが、javaのバージョンが8/9になるにつれて、他の形式の方法が現れました.
interface Motion{
int NORTH = 1;
int EAST = 2;
int SOUTH = 3;
int WEST = 4;
void move(int direction);
int getX();
int getY();
}
class TwoDMotion implements Motion {
private int posX, posY;
public TwoDMotion() { posX = 0; posY = 0; }
// 여기와 같이 interface의 변수들이 상수처럼 사용되고 있다.
public void move(int direction) {
if(direction == NORTH) posY--;
else if(direction == SOUTH) posY++;
else if(direction == EAST) posX++;
else if(direction == WEST) posX--;
}
public int getX() { return posX; }
public int getY() { return posY; }
}
(今java 14です.)
この方法は内包を話している.
今回はクラスオブジェクトを作成する方法のファクトリメソッドについてお話しします.
interface IntSequence{
// 이러한 형태의 메소드를 factory method라고 부른다.
static IntSequence digitsOf(int n){
return new DigitSequence(n);
}
boolean hasNext();
int next();
}
それを使うために、IntSequence digits = IntSequence.digitsOf(1729);
上記のようにclassメソッドを呼び出すことで使用できます.インタフェースの内部では,メソッドにはdefault宣言があり,実装もある.したがって、クラスがインタフェースを実装する場合、サブクラスがインタフェースのdefault methodを宣言しない場合、default method機能のextendsを使用してクラスを継承し、継承クラスと同様の形式の結果を生成します.
たとえば、既存のクラスをインタフェースとして受信する場合は、毎回新しい関数を定義する必要があります.そのため、かなり面倒な状況になるのは避けられない.
intercface IntSequence{
default boolean hasNext() {return true;}
int next();
}
//아래와 같이 클래스는 implements 하였지만
//hasNext를 새롭게 정의하지 않았다.
class SquareSequence implements IntSequence{
private int i;
public int next(){
i++;
return i * i;
}
}
しかし、問題も発生します.2つのクラスのimplementsを受信すると、各クラスに同じ名前のメソッドがあり、問題が発生する可能性があります.interface Person {
String getName();
default int getId() { return 0; }
// Error: duplicate
// default methods with the same type of parameters
}
interface Identified {
default int getId() { return 1; }
// Error: duplicate
// default methods with the same type of parameters
}
class Employee implements Person, Identified {
private String name;
public Employee(String name) { this.name = name; }
public String getName() { return this.name; }
}
public class Lecture {
public static void main(String[] args) {
Employee m = new Employee("Peter");
//바로 이부분에서 문제가 생길 수 있다.
System.out.println(m.getId());
}
}
privateメソッドとは、インタフェース内でのみ呼び出されるメソッドです.
メソッド4はprivateとして宣言され、以下に示す.
また,ここでは,既存の静的メソッドは静的メソッドの内部でのみ呼び出され,静的メソッドはdefaultメソッドでも呼び出されることが分かる.すなわち,既存の静的との区別は存在しないがprivateを宣言することによって外部から静的メソッドへのアクセスが阻止される.
interface CustomInterface {
public abstract void method1();
public default void method2() {
// private method를 당연하듯이 사용한다.
method4();
// 또한 여기와 같이 static method로
// 정의된 method5가 default method에서
// 호출 된 것을 확인할 수 있다.
method5();
System.out.println("default method");
}
public static void method3() {
method5();
//static method inside other static method
System.out.println("static method");
}
//method4 private 선언 : 함수의 구현도 해주었다.
private void method4() {
System.out.println("private method");
}
//private static method가 선언되어 있다.
private static void method5() {
System.out.println("private static method");
}
}
ただし、メソッド4は、インタフェースを継承する他のクラスでは使用できません.public class Lecture implements CustomInterface {
public void method1() {
System.out.println("abstract method");
}
//현재 여기에서는 method4의 호출을 하지 않았으나 사용이 불가능하다.
public static void main(String[] args){
CustomInterface instance = new Lecture();
instance.method1();
instance.method2();
CustomInterface.method3();
}
}
このときいくつかのルール(試験)があります
継承
2つのクラス間の関係.
関係をsuperclassとsubclassに分けます.
Extending a class
class Employee{
private String name;
private int salary;
public Employee(){
this.name = "NoName";
this.salary = 0;
}
public String getName() {return this.name;}
public void setName(String name) {this.name = name;}
public int getSalary() {return this.salary;}
public void setSalary(int salary) {this.salary = salary;}
}
extendsを使用してクラス名を追加すればいいです.class Manager extends Employee{
private int bonus;
public void setBonus(int bonus) {this.bonus = bonus;}
}
これにより、Manager classは、Employee classでpublicとして宣言された関数と変数を使用して、新しい関数と変数を定義できます.Super class vs Sub class
Managerはサブクラスです.
Employeeは一流です.
public static void main(String[] args){
Manager m = new Manager();
System.out.println(m.getName() + " " + m.getSalary());
}
Method overriding
今、クラスを継承したら、同名の新しい関数を定義したくないのでしょうか???だから提案した概念は誇張だ.overridingとはsuperclassでサブクラスの関数を再定義して使用することです.
superclass関数を同時に使用する場合は、
super
キーワードを使用してsuperclass関数を呼び出すことができます.class Manager extends Employee{
private int bonus;
public void setBonus(int bonus) {this.bonus = bonus;}
//아래는 함수의 재정의 + superclass 함수의 사용을 보여준다.
public int getSalary(){
return super.getSalary()+bonus;
}
}
ここでaccessmodifierの概念を考え直しましょうpublic>protected>なし>privateの順にアクセスできることを知っています.ここで、継承時に使用できる範囲は保護されています.
class Manager extends Employee {
private int bonus;
public void setBonus(int bonus) { this.bonus = bonus; }
public int getSalary() {
return this.salary + bonus;
// Error: salary is private in class Employee.
}
}
そのため、上記の超一流の給与を使うことは不可能だという誤った表現が発生します.また、継承されたクラスは、親クラスの作成者を同時に呼び出す必要があります.
基本は同じ名前の関数で書きます.
class Employee {
private String name;
protected int salary;
public Employee() {
this.name = "NoName";
this.salary = 100000;
}
public String getName() {return this.name;}
public void setName(String name) {this.name = name;}
public int getSalary() {return this.salary;}
public void setSalary(int salary) {this.salary = salary;}
}
class Manager extends Employee{
private int bonus = 50000;
public void setBonus(int bonus) {this.bonus = bonus;}
public int getSalary() {
return super.getSalary()+bonus;
}
}
書き換え方法を考えてみましょう
class Employee{
private String name;
protected Employee supervisor;
public Employee(){
this.name = "NoName";
}
public boolean worksFor(Employee supervisor){
System.out.println("Employee.worksFor");
return (this.supervisor == supervisor)
}
}
class Manager extends Employee{
public boolean worksFor(Manager supervisor){
System.out.println("Manager.worksFor");
return (this.supervisor == supervisor)
}
}
パラメータが異なるため、マネージャのEmployee関数はハイパースレッドではなく、ハイパースレッドのみであり、他の関数が定義されています.だからこれらの問題を解決するために.
class Manager extends Employee{
@Override
public boolean worksFor(Manager supervisor){
System.out.println("Manager.worksFor");
return (this.supervisor == supervisor)
}
}
@Override
キーワードを関数の上に書き込みます.これでエラーが発生します.この点から,これは問題のあるコードであることが分かった.したがって,誤りを防止するために,@Overrideというキーワードをできるだけ使うことが誤りを防止する最善の方法である.
還付刑が違うと、過剰生活と認定されます.サーブのタイプだけが認められる.そうではありません.普通の資料型ではあり得ません.これは関数の終了時に影響を与えるので、最初はあまり重要ではありません.ただし、それでもできるだけ@Overrideを作成
class Employee {
private String name;
protected Employee supervisor;
public Employee() {
this.name = "NoName";
}
public Employee getSupervisor() {
System.out.println("Employee");
return supervisor;
}
}
class Manager extends Employee {
@Override // this is ok!
public Manager getSupervisor() {
System.out.println("Manager");
return (Manager)supervisor;
}
}
正確には,サブクラスの制限レベルがより高くなると問題が発生する.しかし、その役なら認められる.でも、プライベートでは無理です.
過負荷承認範囲
access modifier
承認X
もどりがた
承認X
パラメータ
承認O
@Override承認範囲
承認O(ただし、サブクラスはスーパークラスの制限以下である必要がある)
一般資料型返却型
承認X
クラスデータ戻りタイプ
承認O
クラスパラメータ
承認X
Reference
この問題について(Javaを09(インタフェース、継承、インタフェース、継承)に設定), 我々は、より多くの情報をここで見つけました https://velog.io/@tonyhan18/자바를-자바-09テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol