JavaSE オブジェクト指向の基本_インターフェイス

インターフェース

要件: 出張で北京に飛ぶ必要がある

飛行機、鳥、スーパーマンは同じカテゴリに属しませんが、飛行できるという同じ特性を共有しています。したがって、インターフェイスと呼ばれる新しい概念が導入され、インターフェイス内の抽象メソッドがインターフェイスを実装するクラスに実装される必要があることを指定するために使用できます。インターフェースはコントラクトとして理解できる

キーワード「interface」を使用してインターフェースを定義します。

public interface 会飞的 {
    
    
	public void 起飞();
	public void 巡航飞行();
	public void 降落();
}

インターフェイスを直接使用することはできません。対応する実装クラスが必要です。

public class 飞机类 implements 会飞的 {
    
     //共性是通过实现接口来表示的
private String name; //名称,这是类属的属性,这里可以定义字节类的成员,和接口无关
//如果当前类不是抽象类,则必须实现接口中的所有抽象方法
@Override
public void 起飞() {
    
    
System.out.println("使劲的跑,一抬头就飞起来了");
}
@Override
public void 巡航飞行() {
    
    
System.out.println("使劲的烧油...");
}
@Override
public void 降落() {
    
    
System.out.println("我对准...");
}
}

インターフェイスを通じて変数を定義し、具象クラスのインスタンスを使用して、

会飞的 obj = new 飞机类();
obj.起飞();
obj.巡航飞行();
obj.降落();

インターフェイスを導入する目的は、実装を分離することです。

public void 出差(飞机 obj){
    
    }
这种写法当前类和飞机是耦合的,如果需要坐超人出差,则必须修改源代码
public void 出差(会飞的 obj){
    
    }
当前类只是和接口耦合,任何实现了接口的对象都可以作为参数进行传入

特定のクラスを使用する代わりにインターフェイスを使用すると、スーパーヒューマンの定義など、インターフェイスを実装する複数の具象実装クラスを切り替えることができます。

インターフェースとは何ですか

Java は呼び出しの不確実性のため、多重継承を直接サポートしていません。そのため、Java は多重継承メカニズムを改良し、Java での多重実装になります。クラスは複数のインターフェイスを実装でき、インターフェイスは複数のインターフェイスを継承できます。

interface IA{
    
    }
interface IB{
    
    }
interface IC extends IA,IB{
    
    } 正确的,其中IC中的方法等于IA+IB
class A implements IA,IB{
    
    }
IA a=new A();
IB b=new A();
  • インターフェイスは特別な抽象クラスであり、インターフェイスは抽象またはパブリックによってのみ変更できます
  • コンストラクターメソッドがありません
public interface IA{
    
    
	public IA(){
    
    } //语法报错
}
  • 属性はなく、定数のみを定義できます
public class Test {
    
    
	public static void main(String[] args) {
    
    
		System.out.println(IA.name); //常量可以直接使用
		System.out.println(B.name); //实现类也可以直接访问常量
	}
}
interface IA {
    
    
	String name = "yanjun";// 接口中只能定义常量,不能定义属性,默认限定词
	public static final,自定义限定词不能冲突
}
class B implements IA{
    
    }
  • 抽象メソッドを含めることも含めないことも可能
interface IA1 {
    
    
}// 这个接口中没有包含任何抽象方法
class A1Impl implements IA1 {
    
    
}
    • インターフェイス内のメソッドは、public、default、abstract、static によってのみ変更できます。
      • 一般に、インターフェイスには抽象メソッドのみが定義されます。
      • 定義されたメソッドはデフォルトでパブリック抽象メソッドになります

抽象メソッドは実装クラスで実装を提供する必要があります

class A2Impl implements IA2{
    
     //在实现类中必须实现接口中的所有抽象方法,否则当前
类只能是抽象类
public int ee() {
    
    
return 0;
}
public void pp() {
    
    
System.out.println("A2Impl....");
}
public void cc() {
    
    
System.out.println("A2Impl.....");
}
//dd方法由于在接口中有默认实现,所以可以不用重新定义,也允许重新定义
}
  • default キーワードを使用して、抽象メソッドのデフォルト実装を提供できます。また、デフォルト実装を持つメソッドは、実装クラスで再定義することも、再定義しないこともできます。

エラーの理由: クラスの多重継承は Java ではサポートされておらず、クラスは親クラスを 1 つだけ持つことができます。

インターフェースでは多重継承が可能

クラスは別のクラスから継承しながら複数のインターフェイスを実装できます

接口允许多重继承
interface IA1{
    
    
public void p1();
}
interface IA2{
    
    
public void p2();
}
interface IC extends IA1,IA2{
    
    
public void p3();
}//可以继承多个父接口,此时IC中实际有3个抽象方法
类是单根继承,不允许继承多个父类

クラスは複数のインターフェイスを実装できますが、各インターフェイスの抽象メソッドは実装を提供する必要があります。それ以外の場合、そのクラスは抽象クラスになります。提供された実装は以下から継承することもできます

public class A1{
    
    
public void p1(){
    
    }
}
public class A2 extends A1 implements IA1,IA2{
    
    
public void p2(){
    
    }
}
public abstract class A3 extends A1 implements IA1,IA2{
    
    }//因为p2方法没有实现

インターフェイスの外観により、単一継承の制限が回避されます。このようにして、C インターフェイスの定義には A+B のすべての定義が含まれます。A インターフェイスと B インターフェイス、および親クラス D を使用して、変数の型と親クラス D を宣言できます。直接新しいT. ただし、制約する場合、変数を宣言した人がコンパイラ システムによって認識される型になります。つまり、識別された型のメソッドのみを呼び出すことができ、他のメソッドは呼び出すことができません。

interface A{
    
    
public void p1();
}
interface B{
    
    
public void p2();
}
interface C extends A,B{
    
    }
class D{
    
    
public void abc(){
    
    }
}
class T extends D implements C{
    
    
public void p1(){
    
    }
public void p2(){
    
    }
}
D d=new T();这里只能调用abc方法,如果使用其他方法则需要进行类型转换
A a=new T();这里只能调用A接口中声明的方法p1
B b=new T();这里只能调用B接口中声明的方法p2

インターフェースを宣言するための構文

访问修饰符 interface 接口名{
    
     } 一般建议接口名称使用形容词
  • パブリック インターフェイスが定義されている場合、ルールはパブリック クラスの定義と一致し、インターフェイス名はファイル名と一致する必要があります。
  • 外部インターフェイスでは、パブリックおよびデフォルトのスコープ修飾子のみを使用できます。内部インターフェイスを定義する場合は、4 つの主要なスコープ修飾子を使用できます。
  • このインターフェースは実際には同じ操作インターフェース (メソッド) を提供しますが、JDK1.8 バージョンの場合、どのメソッドも実装されず、クラスがそのメソッドを実装するのを待ちます (インターフェース内のすべてのメソッドは抽象メソッドである必要があります)。JDK1.8 以降を使用している場合は、default を使用してインターフェースでデフォルトの実装を定義できます。これにより、実装クラスでオーバーライドを再定義できます。
public class Test1 {
    
    
public static void main(String[] args) {
    
    
IA2 a2=new A2Impl();
a2.pp();
}
}
interface IA2 {
    
    
default void pp(){
    
    
System.out.println("this is pp....");
this.ff();
}
void ff();
}
class A2Impl implements IA2{
    
    
public void ff() {
    
    
System.out.println("this is ff...");
}
}

デフォルトのデフォルトメソッド実装では制限が使用されます

public class Test1 {
    
    
public static void main(String[] args) {
    
    
IA2 a2 = new A2Impl();
a2.pp();
}
}
interface IA2 {
    
    
default void pp() {
    
    
System.out.println("this is No2 pp....");
}
}
interface IA3 {
    
    
default void pp(){
    
    
System.out.println("this is No3 pp");
}
}
class A2Impl implements IA2, IA3 {
    
    //如果IA2中有一个default实现的方法和IA3中
的方法一致,则必须在实现类中重新定义
public void pp() {
    
    
IA2.super.pp();//调用IA2接口中的pp方法的默认实现
IA3.super.pp();
}
}
  • インターフェイスにはプロパティはなく、定数のみを定義できます。インターフェイスにはいくつかの定数が用意されており、インターフェイスを実装するクラスはこれらの定数を共有できます。
  • インターフェイスにはアクセス制御文字を与えることができ、public で変更されたインターフェイスはどこでも見ることができるパブリック インターフェイスです。インターフェイスがスコープ修飾子なしで定義されている場合、同じパッケージ内でのみアクセスできます。

インターフェイスでは定数と抽象メソッドのみを定義できます。

  • インターフェイスではパブリック定数のみを定義できます。インターフェイスのプロパティはデフォルトで public static Final 型であり、public static Final 型である必要があります。
interface IA{
    
    
String name="yanjun";//这里实际上是常量定义,不是属性,它的限定词是public
static final String name="yanjun",必须在声明的同时进行赋值
} 在接口中不能定义静态块 static{
    
    }
接口中不能定义构造器
  • インターフェイスではパブリック抽象メソッドのみを定義でき、JDK1.8 以降でのみ、default キーワードを使用してメソッド実装を定義できます。インターフェイス内のメソッドはデフォルトでパブリック抽象型であり、パブリック抽象型である必要があります。JDK1.8 以降でのみ、default キーワードを使用してメソッドのデフォルト実装を定義でき、実装クラスで再定義をオーバーライドできます。
  • インターフェイスはインスタンス化できず、クラスを実装することによってのみ実装できますが、変数の型を宣言するために使用できます。
    接口 变量名=new 实现接口类();
  • インターフェースにはコンストラクターがありません
  • インターフェイスの抽象メソッドは、継承可能な非抽象サブクラスの実装を提供する必要があります。
interface IA2 {
    
    
public void pp();
}
class A2 {
    
    
public void pp() {
    
    
}
}
class B2 extends A2 implements IA2 {
    
     //这里的pp方法的实现是从父类中继承来的
}

インターフェイスを実装するクラスの構文

class 类名称 implements 接口名称 {
    
     }
  • インターフェイス抽象メソッドのデフォルトの修飾子は public であり、インターフェイスを実装するときに public キーワードを使用してメソッド ヘッダーに指定する必要があります。
interface IA2 {
    
    
void pp();
}
class B2 implements IA2 {
    
    
void pp() {
    
     //语法报错,因为IA2接口中的方法为public abstract
}
}
  • インターフェイスは複数のサブクラスによって実装できます。サブクラスは複数のインターフェイスを実装することもできます

クラスはインターフェイスを実装します

  • クラスがインターフェイスの抽象メソッドを実装する場合、まったく同じメソッド ヘッダー public を使用する必要があります。
  • クラスが複数のインターフェイスを実装する場合は、それらをカンマで区切ります
  • クラスが同じメソッドを宣言する 2 つのインターフェイスを実装している場合、そのクラスは複数のインターフェイスで共有されます。
public class Test1 {
    
    
public static void main(String[] args) {
    
    
IA2 a2=new B2(); a2.pp();
IA3 a3=new B2(); a3.pp();
}
}
interface IA2 {
    
    
void pp();
}
interface IA3{
    
    
void pp();
}
class B2 implements IA2,IA3 {
    
    
public void pp() {
    
    
System.out.println("this is B2.pp()");
}
}
  • クラスはインターフェイスを実装するときに独自の追加メンバーを定義できます。これが最も一般的な形式です。
public class Test1 {
    
    
public static void main(String[] args) {
    
    
IA2 a2=new B2();
a2.pp();//这里不能直接调用B2实现类中的其它方法,如果需要调用则应该进行强制
类型转换
((B2)a2).dd();
}
}
interface IA2 {
    
    
void pp();
}
class B2 implements IA2 {
    
    
public void pp() {
    
    
System.out.println("this is B2.pp()");
}
private int age=100;
public void pp(int k){
    
    
System.out.println("this is pp(int)");
}
public void dd(){
    
    
System.out.println("this is dd()");
}
}
  • クラスがインターフェイスのすべてのメソッドを完全に実装していない場合、クラスは抽象型クラスとして定義する必要があり、クラスを継承するサブクラスはインターフェイスを実装する必要があります。

インターフェース内の定数

複数のインターフェースの実装クラスで定数を共有可能

public class Test1 {
    
    
public static void main(String[] args) {
    
    
System.out.println(IA2.PI);//可以直接使用
A3 a=new A3();
a.setR(4);
System.out.println(a.getArea());
}
}
interface IA2 {
    
    
double PI=3.1415;
}
class A3 implements IA2{
    
     //在实现类中也可以直接使用
private double r;
public double getArea(){
    
    
return PI*r*r;
}
public void setR(double r) {
    
    
this.r = r;
}
}
  • インターフェイスで値を定義して割り当てるだけで、後で変更することはできません
  • クラス内にはインターフェースの実装クラスであることが記述されており、インターフェースの定数が利用可能

オブジェクトには複数の ID があることがよくあります

  • Java のサブクラスは 1 つの親クラスからのみ継承できます (表現できません)。
  • Java のクラスは複数のインターフェイスを実装できます。(表現できる)
class 类名称 implements 接口1,接口2,{
    
     }
  • 継承と実行時ポリモーフィズムの 2 つのメカニズムを通じて、多くの異なる、しかし関連するオブジェクト タイプで使用される一貫したインターフェイスを定義することができます。
  • 抽象インターフェイスを維持し、再コンパイルしなくても、新しいクラスのインスタンスを呼び出すことができます。
public void 出差(会飞的 obj){
    
     obj.起飞(); ...}
调用的时候可以传入不能类型的对象
出差(new 飞机()); --- 出差(new());

インターフェースの特殊機能

  • クラスは親クラスを 1 つだけ持つことができます。
  • クラスは複数のインターフェイスを実装できます。
  • インターフェイスは複数のインターフェイスを継承できます
interface 接口名 extends 接口名称1 ,父接口名称2 , ... {
    
     }

インターフェースの役割

  • 統合アクセス
接口 obj=new 实现1(); 可以还有实现2,实现3等
obj只能调用接口中定义的方法
  • デカップリングでは、インターフェイスを通じて特定の実装を分離できます。
    デカップリングとは、ユーザーと実装者の間に関係がないことを意味します。実装者が実装をどのように変更しても、ユーザーにとっては変わりません

インターフェイスと抽象クラスの類似点と相違点

  • 共通点:すべて継続的に作成される
  • 違い:
    • 抽象クラスは継承する必要があり、単一継承のみが必要です
    • インターフェースを実装する必要があり、さらに多くのインターフェースを実装することができます
  • 抽象メソッドと非抽象メソッドは抽象クラスで定義でき、非抽象メソッドはサブクラス継承の直後に使用できます。
  • 抽象メソッドとデフォルト メソッドはインターフェイスで定義でき、抽象メソッドはサブクラスによって実装する必要があります。JDK1.8 以降では、インターフェイス内のメソッドにデフォルト実装を持たせることができ、デフォルト実装はサブクラスで直接使用できます。実装クラスであり、定義はオーバーライドできます。
  • 抽象クラスの継承は関係であり、システムの基本的な共通コンテンツを定義します。
  • インターフェイスの実装は関係に似ており、定義システムの追加機能は
  • インターフェイスで定義できるのは定数のみであり、初期化する必要があります。プロパティは抽象クラスで定義でき、宣言時に直接初期化するかどうかを許可し、定数の定義を許可します。

インターフェイス内のパブリック メソッドはすべて抽象である必要があります。JDK1.8 以降のバージョンでは、メソッドのデフォルトの実装は、静的メソッドの定義を許可するdefault キーワードを通じて定義できます。JDK1.9 以降、プライベート メソッドは次のとおりです。定義できる; 抽象クラスも抽象メソッドを持つことができる 通常のメソッドも存在できる

public class Test1 {
    
    
public static void main(String[] args) {
    
    
IA2.pp();
A2Impl.pp();
IA2 a2 = new A2Impl();
a2.pp();// 语法报错
}
}
interface IA2 {
    
    
public default void cc(){
    
    }
public static void pp() {
    
    
System.out.println("IA2 static....");
}
}
class A2Impl implements IA2 {
    
    
public static void pp() {
    
    
System.out.println("A2Impl static..");
}
}

インターフェイスで呼び出し仕様を定義し、抽象クラスがインターフェイスを実装し、パブリック関数部分を提供し、最後に特定の実装クラスで特別なメソッドを実装します。

public class Test2 {
    
    
public static void main(String[] args) {
    
    
Fa ff = new Son();
ff.pp();
}
}
class Fa {
    
    
public static void pp() {
    
    
System.out.println("Fa static....");
}
}
class Son extends Fa {
    
    
public static void pp() {
    
    
System.out.println("Son static....");
}
}

public void pp(); はインターフェースの抽象メソッドですが、public void pp(){} の構文が間違っている場合は、JDK1.8 以降のバージョンでは public default void pp(){} を使用しても問題ありません。

インターフェースの使用方法

一般に、インターフェイスは特定の実装を分離するために使用され、クラス間の相互依存関係をインターフェイスに対するクラスの依存関係に変えることができます。例えば、出張クラスと飛行物体は飛行インターフェースを介して分離されているため、出張クラスを変更する必要があるか、飛行物体を変更する必要があるかに関係なく、相互に影響を与えることはありません。

関連するクラスのグループにパブリック メソッドと特別なメソッドが存在する場合、抽象クラスを使用すると、特定のサブクラスを繰り返し実装することなく、抽象クラス内のパブリック メソッド [アルゴリズム スケルトン] を強固にすることができますが、抽象クラスで実装できないものはメソッドサブクラスが実装するまで延期できます。たとえば、ソーター BubbleSorter では、抽象クラス BubbleSorter が使用されるバブル ソート アルゴリズムを固定化し、BubbleSorter のサブクラス PigSorter に実現できないより大きな比較アルゴリズムの実装を遅らせ、ソート アルゴリズムを再定義する必要がありません。豚選別機で

ソフトウェア開発のベスト プラクティス: 最初にインターフェイス仕様の呼び出しメソッドを定義し、次に抽象クラスを使用してインターフェイスを実装し、パブリック メソッドを定義し、最後に特定のサブクラスを定義してすべてのメソッドを実装します。

インターフェースと抽象クラスの利用シナリオ

設計の観点から見ると、抽象クラスは継承関係を具体化しており、主にクラスの所属または親子関係を記述します。抽象クラスとその派生クラスの間の関係は、典型的な IS-A 関係、つまり子です。親です。

インターフェイスは複数の方法で実装できます。実装者とインターフェイス定義が概念上一貫している必要はなく、インターフェイスによって定義されたコントラクトのみが実装されます。ここでは主に、型間の動作規約と、インターフェイスとその実装クラスの間の典型的な CANDO 関係 (子が親の役割を果たすことができる) について説明します。

インターフェイスにデフォルトのメソッドが必要な理由

インターフェイスにデフォルト メソッドを追加する場合、実装クラスを変更する必要はありません。インターフェイスに追加されたデフォルト メソッドは、実装クラスで直接使用できます。

デフォルトのメソッドの競合にも注意してください。

おすすめ

転載: blog.csdn.net/qq_39756007/article/details/127234376