第11章:継承と多形性
1.親カテゴリとサブカテゴリ
1.継承により、クラス(親クラス)を作成して、より具体的なクラス(サブクラス)に展開することができます。
public class Circle extends GeometricObject{
}
Circleはサブクラスであり、サブクラス、派生クラス、および拡張クラスとも呼ばれます
。GeometricObjectは親クラスであり、基本クラスにもなります。スーパークラス
extendsは継承キーワードです。
2.注意
- サブクラスは親クラスのサブセットではありません。サブクラスには通常、親クラスよりも多くの情報とメソッドが含まれています。
- 親クラスのプライベートメンバー変数にはサブクラスからアクセスできませんが、親クラスのパブリックアクセサーとモディファイアにはアクセスできます。
- 「種類」または継承関係のいずれか。たとえば、正方形は一種の長方形ですが、幅と高さが正方形に適していないため、正方形クラスを使用して長方形クラスを拡張することはできません。
- 親クラスと子クラスの間には「isa」関係が必要ですが、継承関係を盲目的に確立することはできません。
- Javaでは多くの継承は許可されていません。Javaクラスは1つの親クラスから直接継承することしかできませんが、インターフェイスを介して複数の継承を実現できます。
いくつかのクラスは、複数の継承と呼ばれるサブクラスを派生させます
2.スーパーキーワードを使用します
キーワードsuperは親クラスを参照し、使用できます
- 親クラスのコンストラクターを呼び出す
super();//调用父类无参构造
super(参数);//调用有参构造
- 親クラスの通常のメソッドを呼び出す
super()またはsuper(parameter)の使用は、サブクラスの構築メソッドの最初の行に表示する必要があります。これは、親クラスの構築メソッドを明示的に呼び出す唯一の方法です。
public class GeometricObject {
//定义父类
private String color;//颜色
private boolean filled;//是否填充
public GeometricObject() {
this("white", false);//调用重载的构造方法
}
public GeometricObject(String color, boolean filled) {
this.color = color;//this调用对象引用的隐藏数据域
this.filled = filled;
}
}
public class Circle extends GeometricObject {
//Circle类继承GeometricObject 类
private double radius;
public static final double PI = 3.14;
public Circle() {
this(1.0, "black", true);
}
public Circle(double radius, String color, boolean filled) {
super(color, filled);//调用父类构造方法,必须放在第一行
this.radius = radius;
}
}
クラスのインスタンスを構築するとき、継承チェーンに沿ったすべての親クラスのコンストラクターが呼び出されます。サブクラスのオブジェクトを構築する場合、サブクラス構築メソッドは、タスクを完了する前に、まずその親の構築メソッドを呼び出します。親クラスが他のクラスから継承する場合、親クラスの構築メソッドは、独自のタスクを完了する前に、独自の親クラスの構築メソッドを呼び出します。このプロセスは、継承アーキテクチャに沿った最後のコンストラクターが呼び出されるまで続きます。
次の例は、データをチェックすることによって得られたものであり、構築方法チェーンをより適切に反映できます。
public class Faculty extends Employee{
public Faculty(){
System.out.println("(3)Performs Faculty's tasks") ;
}
public static void main(String[] args){
Faculty fac=new Faculty();
}
}
class Employee extends Person {
public Employee(){
System.out.println("(2)Performs Employee's tasks");
}
}
class Person {
public Person(){
System.out.println("(1)Performs Person's tasks");
}
}
//运行结果
//(1)Performs Person's tasks
//(2)Performs Employee's tasks
//(3)Performs Faculty's tasks
サブクラスに構築メソッドの明示的な定義はなく、デフォルトのパラメータなし構築が暗黙的に呼び出され、親クラスのパラメータなし構築がデフォルトで呼び出されますが、パラメータなし構築は親クラスで定義されていないため、正常にコンパイルできません。
public class GeometricObject {
private String color;
private boolean filled;
public GeometricObject(String color, boolean filled) {
this.color = color;
this.filled = filled;
}
//父类中没有定义无参构造
}
public class Circle extends GeometricObject {
private double radius;
public static final double PI = 3.14;
//默认调用无参构造和父类的无参构造
}
したがって、継承可能なクラスを設計する場合は、プログラミングエラーを回避するために、パラメータなしの構築メソッドを提供するのが最善です。
3.メソッドの書き換え
1.メソッドを書き直すには、親クラスの定義と同じ署名と戻り値のタイプでメソッドを定義する必要があります。
public class GeometricObject {
@Override
public String toString() {
//父类toString方法
return "GeometricObject [color=" + color + ", filled=" + filled + "]";
}
}
public class Circle extends GeometricObject {
@Override//只有父类的实例方法是可访问时才能被覆盖
public String toString() {
//子类重写父类toString方法,方法签名和返回值类型相同
return super.toString()+" radius:"+getRadius();//重写方法必须使用super.方法名 调用父类的方法
}
}
public static void main(String[] args) {
//测试
// TODO Auto-generated method stub
Circle circle2=new Circle(3.0,"black",true);
System.out.println(circle2.toString());//GeometricObject [color=black, filled=true] radius:3.0
}
インスタンスメソッドと同様に、静的メソッドも継承できますが、静的メソッドをオーバーライドすることはできません。親クラスによって再定義された静的メソッドがサブクラスでオーバーライドされると、親クラスの静的メソッドは非表示になります。
2.書き換えとリロードの違い
**オーバーロード:**同じメソッド名が異なる署名を持つ複数のメソッドを定義します
**オーバーライド:**サブクラスのメソッドの新しい実装を提供します。署名と戻り値のタイプは同じである必要があります
メソッドのオーバーライドは、継承のために関連するさまざまなクラスで発生します
メソッドのオーバーロードは、継承のために関連する1つのクラスまたはさまざまなクラスで発生する可能性があります
注釈の上書き@Override
注釈が使用されているが上書きされていない場合、エラーが報告されます
オーバーライドするメソッドでは、super.function()を使用して親クラスのメソッドを呼び出す必要があります
3.
オブジェクトクラスjavaのすべてのクラスはオブジェクトクラスから継承します
4.多形性
1.多態性とは、親クラスの変数が親クラスのオブジェクトを指すことができることを意味します
2.各サブクラスのインスタンスは、その親クラスのインスタンスであり、その逆も同様です。
5.動的バインディング
1.タイプと実際のタイプを宣言します
Object o=new GeometricObject();
//Object声明类型 GeometricObject实际类型
2.動的バインディングとは、継承チェーンの多くの部分に実装できることを意味します
3.参照変数の宣言タイプによって、コンパイル時に一致するメソッドが決まり、実際のタイプによって動的バインディングメソッドの実装が決まります。
public static void main(String[] args) {
// TODO Auto-generated method stub
printString(new Circle(3.0));//创建Circle的匿名对象
printString(new Rectangle("black", true, 5.0, 6.0));//创建Rectangle的匿名对象
}
public static void printString(GeometricObject go) {
//动态调用toString方法
System.out.println(go.toString());
//运行结果:
//GeometricObject [color=white, filled=false] radius:3.0
//GeometricObject [color=black, filled=true] width:5.0 high:6.0
6.オブジェクトの変換とinstanceof
1.オブジェクトの参照は、オブジェクト変換と呼ばれる別のオブジェクトの参照に型変換できます。
Object o=new Student();//向下转换
//但是 Student s=o; 错误,需要显式转换
Student s=(Student)o;//向上转换,显式
明示的に変換しようとするときは、instancesOfキーワードを使用して、オブジェクトが別のオブジェクトのインスタンスであることを確認してください。
public static void main(String[] args) {
// TODO Auto-generated method stub
GeometricObject[] go = {
new Circle(5.0), new Rectangle("black", true, 5.0, 6.0),
new GeometricObject("blue", true) };//创建一个GeometricObject类型的数组
for (GeometricObject i : go) {
//遍历数组中元素
if (i instanceof Circle) {
//i是否是Circle的实例
System.out.println(((Circle) i).getArea());//因为GeometricObject 类中没有getArea方法,所以要显式转换
} else if (i instanceof Rectangle) {
//i是否是Rectangle的实例
System.out.println(((Rectangle) i).getPrimeter());//因为GeometricObject 类中没有getPrimeter方法,所以要显式转换
} else {
//i是否是GeometricObject的实例
System.out.println(i.toString());
}
}
}
//运行结果:
//78.5
//22.0
//GeometricObject [color=blue, filled=true]
最初からCircleタイプやRectangleタイプとして定義されていないのはなぜですか?
一般的な設計を可能にするために、変数は親クラスとして定義されているため、任意のサブタイプ値を受け取ることができます。
2.オブジェクトメンバーアクセス演算子(。)は、型変換よりも優先されます。したがって、最初に変換して
Rectangleのメソッドを呼び出します。例:((Rectangle)i).getPrimeter()
3.
基本タイプを変換すると新しい値が返されますが、オブジェクトを変換しても新しいオブジェクトは作成されないことに注意してください。
Object o=new Circle();
Circle c=(Circle)o;
//o和c指向同一个对象
7. Objectクラスのequals()メソッド
1.サブクラスで、署名equals(SomeClassName obj)を使用します(例:equals(Circle c)を使用してequalsメソッドをオーバーライドするのは間違っています。equals(Objectobj)を使用する必要があります)
@Override
public boolean equals(Object obj) {
if(obj instanceof Circle) {
//判断Circle是否是obj的实例
return this.radius==((Circle)obj).getRadius();//比较两个的半径是否相等
}
else
return this==obj;
}
8.ArrayListクラス
1. Arraylistを使用して、オブジェクトのリストを格納できます
2.無制限の数のオブジェクトを保存できます
3. ArrayListは、ジェネリックタイプEのジェネリッククラスです。
4.文法
ArrayList<E> list=new ArrayList<E>();
//jdk1.7之后可以去掉这个E
5.方法
ArrayListクラスには、add、clear、include、find、delete、modifyなどのメソッドが含まれています。
これらについては以下で説明します。
6.arrayとArrayListの違い
アレイ | 配列リスト | |
---|---|---|
定義 | int [] array = new array [5] | ArrayList <> list = new ArrayList <>() |
見積もり | 配列[インデックス] | list.get(index) |
要素を更新 | 配列[インデックス] = b | list.set(index、b) |
リターンサイズ | a。長さ | list.size() |
新しい要素を追加する | list.add() | |
新しい要素を挿入します | list.add(index、b) | |
要素を削除する | list.remove(index)またはlist.remove(b) | |
すべて削除 | list.clear() | |
ソート | java.util.Arrays.sort(array) | java.util.Collections.sort(list) |
オブジェクトはArrayListに格納されるため、基本タイプのパッケージタイプを使用します
ArrayList<int> list=new ArrayList<>();//错误
ArrayList<Integer> list=new ArrayList<>();//正确
注意
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.remove(1);
System.out.println(list);//[1]删掉的是下标所对应的元素
//如果就想删掉1 用用list.remove((Integer)1);
}
7.アレイとアレイリスト間の変換
public static void main(String[] args) {
// TODO Auto-generated method stub
String[] str= {
"hello","java","fun"};
ArrayList<String> list = new ArrayList<>(Arrays.asList(str));//将数组转为数组列表
System.out.println(list);//[hello, java, fun]
String[] str2=new String[list.size()];
list.toArray(str2);//将数组列表转为数组
for(String i:str2) {
System.out.print(i+" ");//hello java fun
}
}
8.リストで最大と最小を見つけて、リストをシャッフルします
public static void main(String[] args) {
// TODO Auto-generated method stub
ArrayList<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++) {
list.add(i);
}
System.out.println(java.util.Collections.max(list));//获取最大值 9
System.out.println(java.util.Collections.min(list));//获取最小值 0
java.util.Collections.shuffle(list);//打乱数组列表
System.out.println(list);//[5, 7, 4, 3, 8, 9, 1, 2, 0, 6]
}
9.保護されたデータとメソッド
1.クラスの保護されたメンバーは、サブクラスからアクセスできます
2.サブクラスが親クラスのデータフィールドとメソッドにアクセスすることを許可しますが、サブクラス以外のアクセスは許可しません。protectedキーワードを使用します
3.可視性の向上:
プライベート(プライベート)、デフォルト(デフォルト)、保護(保護)、グローバル(パブリック)
4.保護されているため、パッケージ内のクラスとパッケージ外のサブクラスにアクセスできます
5.サブクラスは、親クラスの保護されたメソッドをオーバーライドできますが、メソッドのアクセシビリティを弱めることはできず、増やすことしかできません。
10.拡張と書き換えを防止します
1.finalによって変更されたクラスとメソッドは拡張できません
2.メソッドのローカル変数で使用できるのはfinalのみです
11.まとめ
この章の学習を通して、親クラスと子クラスの関係を理解し、スーパーを使用して親クラスの構築メソッドとメソッドを呼び出すことを学びます。最初の文にそれを入れて、多形性の意味を学ぶことを忘れないでください(親クラスの変数はサブクラスオブジェクトを指す)、オーバーライドとオーバーロードの違いを理解し、動的ロードの理由を理解し、アップ明示変換、ダウン変換、instanceofの使用法を理解し、ArrayList配列リスト、保護された修飾子の便利さを学びました拡張を防ぐためにクラスとメソッドを変更するためのfinalキーワードの使用法と使用法。
いい加減にして!第12章もっとなるために...