【Java基础】继承
首先
最近我參加了Java基礎的培訓。雖然在學生時期上過Java課程,有一些基礎已經掌握,但也有些忘記了,所以我把它們寫下來作為備忘錄。
在这篇文章中,我们将概述Java的基础知识。这次是关于继承。
继承是指
继承是一种创建新类并继承类功能以扩展功能的方法。
在此过程中,被继承的类被称为父类(超类),新创建的类被称为子类(子类)。
让我们来看一下下面的关系。
-
- 商品
本
食材
在这种情况下,从”商品”这个父类派生出了”本”和”食材”两个子类。
继承的方法:
继承的方式如下进行。
class 子クラス extends 親クラス名 {
}
让我们来看一个继承的例子。
class Item {
// 「商品」クラス
}
class Book extends Item {
// 「本」クラス
}
class Food extends Item {
// 「食材」クラス
}
继承的注意事项 de
在利用继承时,请注意以下几点。
-
- 只能继承一个类
-
- 可以继承已经被继承的类
- 无法从父类引用子类的成员
(参考)对象类
所有的类都隐式地继承自Object类。所有类的起源都是Object类。
Object类声明了所有类都应具有的方法。
-
- toStringメソッド
オブジェクトの文字列表現を返す
equalsメソッド
2つのインスタンスが等しいかどうかを示す
每个类都可以调用toString方法和equals方法。
覆盖
覆盖是指在子类中重写父类的方法。
让我们重写Object类的toString方法试试看。
class Item {
private String name;
private int price;
public void setName(){ 省略 }
public void setPrice(){ 省略 }
@Override
public String toString() {
return name + "(" + price + "円)";
}
}
public static void main(String[] args) {
Item item = New Item();
item.setName("Qiita攻略本");
item.setPrice(1000);
String str = item.toString();
System.out.println(str); // Qiita攻略本(1000円)
}
在重写的方法中使用super.方法名(参数列表)的方式,可以调用父类的方法。
抽象方法与抽象类
将基于override的方法称为抽象方法,将声明了抽象方法的类称为抽象类。相对应地,有些人也将没有抽象方法的类称为具体类。
抽象类具有以下特点。
-
- インスタンスを作成できない
-
- 抽象クラスは継承され、抽象メソッドをオーバーライドされる前提で作られる
- 抽象クラスを継承したクラスは抽象メソッドを全てオーバーライドしないとコンパイルエラーとなる
声明抽象类和抽象方法
抽象方法被声明为在返回类型前加上关键词“abstract”。此外,由于其没有具体的处理内容,所以用分号“;”代替了大括号“{}”。
在使用抽象方法时,请按照以下方式进行描述。
修飾子 abstract 戻り値の型 メソッド名(引数リスト);
与抽象类的抽象方法类似,需要在class前面加上abstract来声明。除了抽象方法,还可以声明其他成员。
修飾子 abstract class クラス名 {
抽象メソッドなどのメンバ
}
让我们看一些抽象类和具体类的例子。
abstract class Page {
public abstract String getTitle();
public void printReview() {
System.out.println("title : " + getTitle() );
System.out.println("review : It was really great story.");
}
}
class ReviewPage extends Page {
@Override
public abstract String getTitle() {
return "The Story Of Qiita";
}
}
public static void main(String[] args) {
ReviewPage page = New ReviewPage();
page.printReview();
}
title : The Story Of Qiita
review : It was really great story.
构造函数
无论是继承具象类还是抽象类,父类的构造函数都不会被子类继承。
class Item {
private String name;
private int price;
public Item(String name, int price) {
this.name = name;
this.price = price;
}
}
class Book extends Item {
// メンバを宣言していない
}
public static void main(String[] args) {
// Book book = new Book("Qiita攻略", 1000); // コンパイルエラー
}
在子类的构造函数中,可以通过super(参数列表)来调用父类的构造函数。
class Book extends Item {
public Book(String name, int price) {
super(name, price); // 親クラスのコンストラクタを呼び出す
}
}
public static void main(String[] args) {
Book book = new Book("Qiita攻略", 1000); // コンパイルエラーは起こらない
}
通常情况下,子类的构造函数会隐式地调用父类的无参构造函数。但如果父类只声明了一个或多个带参数的构造函数,则需要显式地调用。
继承了类的实例
可以将子类的实例赋值给父类类型的变量。
※反之不成立。
Item book = new Book();
Page page = new ReviewPage();
当将子类的实例赋值给父类类型的变量时,需要注意调用的方法和调用结果。这是因为,在编译时和运行时,引用的类型是不同的。
-
- コンパイル時:変数の型を参照し、メソッドが実行できるかが決まる
- 実行時:インスタンスの型を参照し、メソッドの実行内容が決まる
总结
开始时,希望能够在班级中建立起一种亲子关系,并且能够进行更新。虽然有一些具体的限制,但我们可以逐渐记住它们!