Java 抽象クラス
私たちの親クラスはいくつかのメソッドを設定しています。それらを設定する主な目的は、サブクラスが親クラスを継承してそれらのメソッドをオーバーライドして、異なる結果を表示することです。言い換えれば、親クラスのメソッドの特定の実装は気にしません。いずれにせよ、子クラスのメソッドによってオーバーライドされます。その後、親クラスをより抽象的にして、メソッド宣言のみを含めることができます。メソッド本体はありません。このメソッドを抽象メソッドと呼び、抽象メソッドを含むクラスを抽象クラスと呼びます。
抽象クラスの特徴
抽象クラスは、1つ以上の抽象メソッドを含んでいる限り、抽象クラスです。 ただし、抽象メソッドが存在しない場合、この抽象クラスは意味を持ちません。抽象メソッドは、次の形式のメソッドです。
[public] 抽象戻り型メソッド名 (パラメータ リスト);
抽象メソッドにはメソッド本体がないため、メソッド名が記述された後に、メソッドの終わりを示すために追加されます。メソッド宣言、および抽象メソッドのメソッド本体を abstract で変更すると、アクセス修飾子が public または protected のみになるか、デフォルトのアクセス許可はまったく継承できないため使用できなくなります。
同様に、抽象クラスの形式は次のとおりです。
[public] abstract class 类名{ [public] abstract 返回类型 方法名(参数列表); }
抽象クラスは、先頭に abstract を追加することで変更され、アクセス修飾子が public または protected、またはデフォルトのアクセス許可のみであることを示します。 . privateが使えない理由は上記と同じです。
抽象クラスの作成の重要性は、メソッドの宣言をメソッドの実装から分離し、それによってポリモーフィズムを実現することです。そして、次のような特徴があります:
抽象クラスはインスタンス化できません。つまり、抽象クラスのオブジェクトを直接作成することはできませんが、パラメータ化されたコンストラクターの場合、サブクラスは呼び出しを表示するために Go する必要があります。それ。
抽象クラスは継承されることを目的としており、サブクラスが抽象親クラスを継承する場合は、親クラスの抽象メソッドをオーバーライドする必要があります。オーバーライドされない場合は、サブクラスも次のように定義する必要があります。抽象クラス。
abstract を private static、final 修飾子と一緒に使用してメソッドを変更することはできません。
ここで3つ目のポイントであるabstractはprivateでは使用できないことを説明します。privateで変更したメソッドやクラスにはクラス外からアクセスできないためです。相続の可能性はありません。 Abstract を static と一緒に使用することはできません。abstract の機能はポリモーフィズムを実現することであり、ポリモーフィズムの実現は継承と上書きに依存しているためです。静的に変更されたメソッドはサブクラスに継承できますが、継承されたメソッドを変更する場合は上書きとしてカウントされず、親クラスのメソッドは非表示になり、親クラス名とメソッド名のみが使用できるようになります。これを呼び出してもポリモーフィズムが達成されないことを示しています。別の観点から見ると、静的メソッドはコンパイル中に決定され、遅延バインディングは実現できないため、実行時にメソッド呼び出しを決定する可能性はありません。したがって、静的に変更されたメソッドは継承できますが、ポリモーフィズムは実現できず、当然、abstractで使用することはできません。
finalでabstractが使えない理由は上記と同じで、finalで変更されたメソッドは継承できず、当然ポリモーフィックではないので、finalではabstractが使えません。
抽象クラスの例
上記のポリモーフィックな例を引き続き変更して抽象化していきます。 Animal コードを次のように変更します。
public abstract class Animal { abstract void run(); }
Dog クラスと Cat クラスのコードを変更する必要はありません。
public class Dog extends Animal{ @Override public void run() { System.out.println("狗在奔跑"); } }public class Cat extends Animal{ @Override public void run() { System.out.println("猫在奔跑"); } }
他の Print クラスと Test クラスのコードも変更されていません。コードは次のとおりです。
public class Print { public void print(Animal animal) { animal.run(); } } public class Test { public static void main(String[] args) { Animal dog = new Dog(); Animal cat = new Cat(); new Print().print(dog); new Print().print(cat); } }
抽象クラスと前の通常のクラスの間で、他の場所には基本的に変更がないことがわかります。メソッドが抽象化され、意味がより明確になります。
抽象的な概要
抽象クラスと抽象メソッドを作成することは、クラスを設計する際に、クラスの意味をより明確にし、一連のメソッドを宣言することを可能にします。ユーザーに使い方を伝えるため。
Java インターフェース
インターフェースは、何ができるかを知るためにそれを継承し、それをどのように行うかは私たち次第です。例えば、KFCはインターフェースを見ればわかりますが、具体的な味やサービスは店舗によって異なります。 。したがって、インターフェース内のメソッドも抽象的である必要があることがここでわかります。
インターフェースの特徴
Java でインターフェースを記述する方法は次のとおりです:
[public] interface InterfaceName { 成员变量 方法声明 }
インターフェースはクラスとは異なり、特定のインターフェースのキーワードを使用します。パブリックまたはデフォルト。コンテンツには、抽象メソッドとメンバー変数の 2 種類のみがあります。メンバー変数はデフォルトで public static Final で追加されます。つまり、メンバー変数は所有者として分類され、最大のアクセス権を持ちますが、継承または変更することはできません。これは、インターフェイスのメンバー変数はインスタンス化できないため、この方法で合意されていることも示しており、インターフェイスのメンバー変数は定義時に割り当てる必要があります。 インターフェイス メソッドのデフォルトは抽象メソッドです。抽象メソッドと同様に、メソッド宣言のみを記述できます。
extends を使用してクラスを継承するのとは異なり、このインターフェースの実装を表すためにimplements を使用します。
class ClassName implements Interface1{ }
特別な存在として、インターフェイスにはいくつかのユニークな機能があります。
一个类是可以实现多个接口的,这在一定程度上实现了Java的多继承。
接口是不能被实例化,不同于抽象类,接口的内部只能由成员变量和抽象方法,是不可以存在静态变量块,以及构造器的。
我们是可以声明一个接口类型的变量,但是只能引用一个实现了这个接口的类。
同抽象方法,实现了接口的类必须实现接口的所有方法,否则就会变成抽象类。
接口举例
看过抽象的例子,我们可能想,我们把Animal从抽象换成接口,不就实现了一个接口的例子嘛,其他地方基本也不用去改动。但这显然是错的。我们并不能去说Animal是一个接口,我们上面说了,接口是一种协议,规定我们能做什么,而不是一个事物的抽象。从这里我们也能看出接口和抽象的不同,抽象更多的是一种重构而产生的东西,我们先有dog,cat类,然后才会把他们共性的东西提取出来,放到一个更通用,更抽象的父类Animal中,而我们发现Animal不需要管run方法是怎么实现的,所以我们将run方法设定为抽象的方法,从而将Animal类设为抽象类,等待去=继承者来实现run。这是一种从下而上的设计思想。但是接口不是,接口一开始就是设定好的,我们根据设定好的接口从上往下去写。接口先规定好了有什么方法,然后我们再去具体实现他。这是一种从上而下的设计思想。
所以,我们不能将Animal设为接口,但是我们可以将Print设为接口,他规定我们有一个print()方法,代码如下:
public interface Print { void print(Object obj); }
那我们就可以写一个新的类去实现这个Print接口。代码如下:
public class SimplePrint implements Print{ @Override public void print(Object obj) { ((Animal)obj).run(); } }
除了Test类以外,其他地方都不需要改变。我们Test类代码如下:
public class Test { public static void main(String[] args) { Animal dog = new Dog(); Animal cat = new Cat(); Print print = new SimplePrint(); print.print(dog); print.print(cat); } }
接口总结
接口和抽象虽然都是通过抽象的方法来提供我们实现多态的方式,但是他们却是两个不同的设计思想。这里关于接口的讲解比较简单,关于接口自身的继承,接口内部包含其他接口,以及利用接口来实现回调等等留在以后的文章专门来说。这里主要是通过对比来了解抽象和接口。