目錄
1. 概念
2. 語法
3. 父類成員訪問
3.1 子類訪問父類的成員變數
3.1.1 子類和父類中不存在同名的成員變數
3.1.2 子類和父類存在相同的成員變數
3.2 子類中訪問父類的成員方法
3.2.1 成員方法名字不同
3.2.2 成員方法名字相同
4. super關鍵字
5. 子類構造方法
6. 執行順序
7. 繼承方式
8. final關鍵字
1. 概念
繼承的基本思想是,基于已有的類創造新的類,繼承已存在的類就是復用這些類的方法,而且可以增加一些新的方法和欄位,使新類能夠適應新的情況,繼承是Java程式設計中一項核心技術,它主要解決的問題是:共性的抽取,實作代碼復用,例:

上圖中,dog和cat都繼承Animal類,dog和cat可以稱為Animal的子類或者派生類,繼承之后,子類可以復用父類的方法和屬性,子類在實作時只關心自己新增加的成員即可,
2. 語法
Java中表現繼承的關系需要借助關鍵字extends:
修飾符 class 子類 extends 父類{
//...
}
對上述例子進行代碼展示:
Animal.java
public class Animal {
String name;
String gender;
int age;
public void eat(){
System.out.println(name+"吃東西");
}
public void sleep(){
System.out.println(name+"在睡覺");
}
}
Dog.java
public class Dog extends Animal{
void bark(){
System.out.println(name+"旺旺~");
}
public static void main(String[] args) {
Dog dog = new Dog();
System.out.println(dog.name);
System.out.println(dog.gender);
System.out.println(dog.age);
dog.eat();
dog.sleep();
dog.bark();
}
}
Cat.java
public class Cat extends Animal{
void mew(){
System.out.println(name+"喵喵~");
}
public static void main(String[] args) {
Cat cat = new Cat();
System.out.println(cat.name);
System.out.println(cat.gender);
System.out.println(cat.age);
cat.eat();
cat.sleep();
cat.mew();
}
}
注意:
· 子類將繼承父類的成員變數和成員方法
· 子類繼承父類之后,需要添加自己特有的成員,體現出與基類的不同
3. 父類成員訪問
3.1 子類訪問父類的成員變數
3.1.1 子類和父類中不存在同名的成員變數
public class Base {
int a;
int b;
}
public class Derived extends Base{
int c;
public void method(){
a = 10; //從父類繼承
b = 20; //從父類繼承
c = 30; //訪問自己
}
}
3.1.2 子類和父類存在相同的成員變數
public class Base {
int a;
int b;
int c;
}
public class Derived extends Base {
char b; //與父類同名,不同型別
int c; //與父類同名,相同型別
public void method(){
a = 10; //訪問父類繼承
b = 20; //訪問誰的?
c = 30; //訪問誰的?
//d = 40; //編譯器報錯
}
}
注意:
· 如果訪問的成員變數子類中有,則優先訪問子類本身的
· 如果訪問的成員變數子類中無,父類中有,則訪問繼承下來的
· 如果子類與父類中有同名的成員變數,則優先訪問子類自己的,即子類將父類的同名變數隱藏
成員變數的訪問遵循就近原則,自己有就優先訪問自己的
3.2 子類中訪問父類的成員方法
3.2.1 成員方法名字不同
public class Base {
public void method1(){
System.out.println("我是父類方法");
}
}
public class Derived extends Base {
public void method2(){
System.out.println("我是子類方法");
}
public void method(){
method1(); //父類方法
method2(); //子類方法
}
}
3.2.2 成員方法名字相同
public class Base {
public void method1(){
System.out.println("我是父類方法");
}
public void method2(){
System.out.println("我是父類方法");
}
}
public class Derived extends Base {
public void method1(int a){
System.out.println("我是子類方法");
}
public void method2(){
System.out.println("我是子類方法");
}
public void method(){
method1(); //父類方法
method1(10); //子類方法
method2(); //子類方法
}
}
說明:
· 通過子類訪問成員方法,先看子類本身有沒有,如果有訪問自己的,如果沒有,訪問父類的
· 通過子類訪問與父類同名方法時,如果子類和父類方法的引數串列不同則構成多載,根據呼叫方法傳遞的引數選擇合適的方法訪問
· 如果子類和父類同名方法的原型一致,則只能訪問到子類的
4. super關鍵字
如果子類中存在與父類同名的方法成員,則通過關鍵字super在子類方法中訪問父類方法成員
public class Base {
int a;
int b;
int c;
public void method1() {
System.out.println("我是父類方法");
}
public void method2() {
System.out.println("我是父類方法");
}
}
public class Derived extends Base {
int a;
int b;
int c;
public void method1(int n){
System.out.println("我是子類方法");
}
public void method2(){
System.out.println("我是子類方法");
}
public void method(){
a = 10;
b = 20; //訪問子類成員
c = 30;
super.a = 10;
super.b = 20; //訪問父類成員
super.c = 30;
method1(); //訪問父類方法
method1(10); //訪問子類方法
method2(); //訪問子類方法
super.method2();//訪問父類方法
}
}
注意事項:只能在非靜態方法中使用
5. 子類構造方法
構造哪個類的物件,就呼叫哪個類的構造方法,呼叫構造方法時先呼叫基類,在呼叫子類(即在子類中隱藏super() )
public class Base {
public Base(){
System.out.println("Base()");
}
}
public class Derived extends Base {
public Derived(){
System.out.println("Derived()");
}
}
public class Text {
public static void main(String[] args) {
Derived d = new Derived();
}
}
輸出結果:Base()
Derived()
在子類構造方法中,并沒有寫任何關于基類構造的代碼,但是在構造子類物件時,先執行基類的構造方法,然后執行子類的構造方法
注意:
· 若父類顯示定義無參或者默認的構造方法,在子類構造方法的第一行默認有隱含的super呼叫,即呼叫基類的構造方法
· 如果父類的構造方法是帶有引數的,此時編譯器不會給子類生成默認的構造方法,此時需要用戶在子類中顯示定義構造方法,并在子類構造方法中選取合適的父類構造方法呼叫
· 在子類構造方法中,super(...)呼叫父類構造時,必須是子類構造方法中的第一條陳述句
· super(...)只能在子類的構造方法中出現一次,并不能和this同時出現
6. 執行順序
無繼承關系時的執行順序:
public class Person {
String name;
String gender;
int age;
public Person(String name,String gender,int age){
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("我是構造方法");
}
{
System.out.println("我是實體代碼塊");
}
static {
System.out.println("我是靜態代碼塊");
}
public static void main(String[] args) {
Person p1 = new Person("xiaoHua","男",12);
System.out.println("=====================");
Person p2 = new Person("xiaoHong","女",15);
}
}
執行結果:

說明:
靜態代碼塊先執行,且只執行一次,在類加載階段執行
當有物件創建時,才會執行實體代碼塊,實體代碼塊執行完后,再執行構造方法
有繼承關系時的執行順序:
public class Person {
String name;
String gender;
int age;
public Person(String name,String gender,int age){
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("person的構造方法");
}
{
System.out.println("person的實體代碼塊");
}
static {
System.out.println("person的靜態代碼塊");
}
}
public class Student extends Person{
public Student(String name, String gender, int age) {
super(name, gender, age);
System.out.println("student的構造方法");
}
{
System.out.println("student的實體代碼塊");
}
static {
System.out.println("student的靜態代碼塊");
}
}
public class Text {
public static void main(String[] args) {
Student s1 = new Student("張三","男",35);
System.out.println("=====================");
Student s2 = new Student("李四","男",30);
}
}
執行結果:

結論:
· 父類靜態代碼塊優先子類靜態代碼塊執行,都是最早執行的
· 父類實體代碼塊和父類構造方法緊接著執行
· 子類的實體代碼塊和子類構造方法在接著執行
· 第二次實體化物件時,父類和子類的靜態代碼塊都不會在執行
7. 繼承方式
Java中只支持以下幾種方式:

注意:Java中不支持多支持
8. final關鍵字
final關鍵字可以用來修飾變數,成員方法以及類,
1.修飾變數或欄位,表示常量(即不能修改)
final int a = 10; a = 20;//編譯報錯
2.修飾類,表示類不能繼承
final public class Person{
}
public class Student extends Person{
}//編譯報錯
3.修飾方法,表示方法不能被重寫(后續在介紹)
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/302223.html
標籤:java
