一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中的重要核心知識點之繼承詳解

Java中的重要核心知識點之繼承詳解

2022-02-23 13:18Luka.lh Java教程

繼承是java面向對象編程技術的一塊基石,因為它允許創建分等級層次的類。繼承就是子類繼承父類的特征和行為,使得子類對象(實例)具有父類的實例域和方法,或子類從父類繼承方法,使得子類具有父類相同的行為

一、繼承

1、概念

繼承(inheritance)機制:是面向對象程序設計使代碼可以復用的最重要的手段,它允許程序員在保持原有類特 性的基礎上進行擴展,增加新功能,這樣產生新的類,稱派生類。繼承呈現了面向對象程序設計的層次結構, 體現了由簡單到復雜的認知過程。
繼承主要解決的問題是:共性的抽取,實現代碼復用。

例如:狗和貓都是動物,分別定義一個貓類和狗類,他們都是動物,讓他們來繼承動物類,那么我們就可以將共性的內容進行抽取,然后采用繼承的思想來達到共用。

// Dog.java
public class Dog{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃飯");
}
public void sleep(){
System.out.println(name + "正在睡覺");
}
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
// Cat.Java
public class Cat{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃飯");
}
public void sleep()
{
System.out.println(name + "正在睡覺");
}
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}

Java中的重要核心知識點之繼承詳解

2、語法

在Java中如果要表示類之間的繼承關系,需要借助extends關鍵字,具體如下:

修飾符 class 子類 extends 父類 {
// ...
}

那么對于貓和狗的場景,我們讓貓類和狗類均繼承自動物類:

public class Animal{
String name;
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 + "汪汪汪~~~");
}
}
// Cat.Java
public class Cat extends Animal{
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}
// TestExtend.java
public class TestExtend {
public static void main(String[] args) {
Dog dog = new Dog();
// dog類中并沒有定義任何成員變量,name和age屬性肯定是從父類Animal中繼承下來的
System.out.println(dog.name);
System.out.println(dog.age);
// dog訪問的eat()和sleep()方法也是從Animal中繼承下來的
dog.eat();
dog.sleep();
dog.bark();
}
}

注意事項:
1、子類會將父類中的成員變量或成員方法繼承到子類中去。
2、子類中一定要含有與父類不同的成員方法或者成員變量,體現出與父類的不同,否則繼承就失去了意義。

3、父類成員的訪問

(1)子類中訪問父類成員變量

第一種情況:子類和父類不存在同名成員變量

public class Base {
  int a;
  int b;
}
public class Derived extends Base {
  int c;
  int d;

  public void method(){
      a=10;//訪問的是從父類繼承下來的成員變量a
      b=20;//訪問的是從父類繼承下來的成員變量b
      c=30;//訪問的是子類自己的成員變量c
      d=40;//訪問的是子類自己的成員變量d
  }
}

第二種情況:子類和父類成員變量有同名

public class Base {
  int a;
  int b;
}
public class Derived extends Base {
  int b;
  int c;

  public void method(){
      a=10;
      b=20;//此時訪問的是父類中的b還是子類中的b?
      c=30;
      //d=40; 編譯報錯,因為在子類和父類中都不存在成員變量d
  }
}

注意事項:
在子類方法中或者通過子類對象訪問成員變量時:
1、如果訪問的成員變量子類中有,優先訪問自己的成員變量。
2、如果訪問的成員變量子類中無,則訪問父類繼承下來的,如果父類也沒有定義,則編譯報錯。
3、如果訪問的成員變量與父類中成員變量同名,則優先訪問自己的,即:子類將父類同名成員隱藏了。

(2)子類中訪問父類成員方法

第一種情況:子類和父類中不存在同名成員方法

public class Base {
  public void methodA(){
      System.out.println("我是父類成員方法");
  }
}
public class Derived extends Base {
  public void methodB(){
      System.out.println("我是子類成員方法");
  }

  public void methodC(){
      methodA();//訪問繼承自父類成員方法
      methodB();//訪問子類自己的成員方法
      //methodD(); 編譯報錯,在繼承體系中沒有methodD方法
  }
}

第二種情況:子類和父類中存在同名方法

public class Base {
  public void methodA(){
      System.out.println("我是父類成員方法methodA");
  }
  public void methodB(){
      System.out.println("我是父類成員方法methodB");
  }
}
public class Derived extends Base {
  public void methodA(int a){
      System.out.println("我是子類成員方法methodA");
  }

  public void methodB(){
      System.out.println("我是子類成員方法methodB");
  }

  public void methodC(){
      methodA(1);//帶參的methodA方法,訪問的是子類的方法
      methodA();//無參的methodA方法,訪問的是父類的方法
      methodB();//直接訪問methodB,訪問到的是子類的方法
  }
}

注意事項:
1、通過子類對象或方法訪問父類與子類中不同名方法時,優先在子類中找,找到則訪問,否則在父類中找,找到則訪問,否則編譯報錯。
2、通過子類對象訪問父類與子類同名方法時,如果父類和子類同名方法的參數列表不同,根據調用方法時傳遞的參數選擇合適的方法訪問,如果沒有則報錯;如果父類和子類同名方法的原型一致,則只能訪問到子類的,父類的無法通過派生類對象直接訪問到。

咦????那么問題來了,如果想要訪問與子類方法同名且原型一致的父類方法時該怎么訪問呢?――super關鍵字

4、super關鍵字

當子類和父類中存在同名且原型一致的方法時,我們想要調用父類的該方法時發現不能直接訪問,而在Java中提供了super關鍵字,該關鍵字的主要作用就是:在子類方法中訪問父類成員。

public class Base {
  int a;
  int b;

  public void methodA(){
      System.out.println("我是父類成員方法methodA");
  }
  public void methodB(){
      System.out.println("我是父類成員方法methodB");
  }
}
public class Derived extends Base {
  int a;//與父類同名成員
  String b;//與父類同名成員的類型不同

  // 與父類中methodA()構成重載
  public void methodA(int a){
      System.out.println("我是子類成員方法methodA");
  }
  //重寫父類中的methodB方法
  public void methodB(){
      System.out.println("我是子類成員方法methodB");
  }

  public void methodC(){
      a=100;
      super.a=110;
      b="abc";
      super.b=100;

      methodA(1);//帶參的methodA方法,訪問的是子類的方法
      methodA();//無參的methodA方法,訪問的是父類的方法
      methodB();//直接訪問methodB,訪問到的是子類的方法
      super.methodB();//通過super關鍵字調用的是父類的methodB
  }
}

注意事項:

1、只能在非靜態方法中使用。

Java中的重要核心知識點之繼承詳解

2、用于在子類方法中,訪問父類的成員變量和方法。

5、子類構造方法

子類對象構造時,需要先調用基類構造方法,然后執行子類的構造方法。

public class Base {
 public Base(){
     System.out.println("我是父類構造方法");
 }
}
public class Derived extends Base {
  public Derived(){
      // super();
      // 注意子類構造方法中默認會調用基類的無參構造方法:super()
      //當用戶沒有寫時編譯器自動添加
      //且super()必須是第一條語句,且只能出現一次
      System.out.println("我是子類構造方法");
  }

  public static void main(String[] args) {
      Derived a=new Derived();
  }
}

/*
執行結果
我是父類構造方法
我是子類構造方法
*/

說明:在子類構造方法中,并沒有寫任何關于基類構造的代碼,但是在構造子類對象時,先執行基類的構造方法,然后執行子類的構造方法,因為:子類對象是一個父類對象,在構造子類對象時,先要將從父類繼承下來的成員初始化完整,然后再初始化子類自己新增加的成員。
從對象模型的角度來看:

Java中的重要核心知識點之繼承詳解

注意事項:
1、若父類顯式定義無參或者默認的構造方法,編譯器會給子類生成一個默認的構造方法,且在子類構造方法第一行默認有隱含的super()調用,即調用基類構造方法。
2、如果父類構造方法是帶有參數的,此時編譯器不會再給子類生成默認的構造方法,此時需要用戶為子類顯式定義構造方法,并在子類構造方法中選擇合適的父類構造方法調用,否則編譯失敗。
具體看如下代碼:

public class Base {
  int a;
  int b;
 public Base(int a){ //父類中帶參數的構造方法
     this.a=a;
 }
}
public class Derived extends Base {
  public Derived(int a,int b){ //此時需要在子類中自定義構造方法
      super(a);//選擇合適的父類構造方法調用
      this.b=b;
  }

  public static void main(String[] args) {
      Derived a=new Derived(10,20);
      System.out.println(a.a);
      System.out.println(a.b);
  }
}

/*
執行結果:
10
20
*/

3、在子類構造方法中,super(…)調用父類構造時,必須是子類構造函數中第一條語句。
4、super(…)只能在子類構造方法中出現一次,并且不能和this同時出現。

6、super和this

相同點:
1、都是Java中的關鍵字
2、只能在類的非靜態方法中使用,用來訪問非靜態成員方法和字段
3、在構造方法中調用時,必須是構造方法中的第一條語句,并且不能同時存在,如下圖所示:

Java中的重要核心知識點之繼承詳解

不同點:
先給一段代碼

public class Base {
  int a;
  int b;
}
public class Derived extends Base {
  int c;
  int d;
  public void method(){
      super.a=10;
      super.b=20;

      this.c=30;
      this.d=40;
  }
  public static void main(String[] args) {
      Derived d=new Derived();
      d.method();
  }
}

1、 this是當前對象的引用,當前對象即調用實例方法的對象,super相當于是父類對象的引用。針對上述代碼,如下圖所示:

Java中的重要核心知識點之繼承詳解

2、在非靜態成員方法中,this用來訪問本類的方法和屬性,super用來訪問父類繼承下來的方法和屬性。上圖也可以進行說明。
3、this是非靜態成員方法的一個隱藏參數,super不是隱藏的參數。還是針對上述代碼,從字節碼的角度來看,打開method方法中的局部變量表,發現只有this,而沒有super。

Java中的重要核心知識點之繼承詳解

4、成員方法中直接訪問本類成員時,編譯之后會將this還原,即本類非靜態成員都是通過this來訪問的;在子類中如果通過super訪問父類成員,編譯之后在字節碼層面super實際是不存在的。

Java中的重要核心知識點之繼承詳解

5、在構造方法中:this(…)用于調用本類構造方法,super(…)用于調用父類構造方法,兩種調用不能同時在構造方法中出現。
6、 構造方法中一定會存在super(…)的調用,用戶沒有寫編譯器也會增加,但是this(…)用戶不寫則沒有。

7、代碼塊執行順序

第一種:在沒有繼承關系時的執行順序

public class Person {
  int age;
  String name;

  public Person(int age,String name){
      this.age=age;
      this.name=name;
      System.out.println("執行構造方法");
  }
  {
      System.out.println("執行實例代碼塊");
  }

  static {
      System.out.println("執行靜態代碼塊");
  }

  public static void main(String[] args) {
      Person a=new Person(20,"luka");
      System.out.println("-----------------------");
      Person b=new Person(21,"stepth");
  }
}

/*
執行結果:
執行靜態代碼塊
執行實例代碼塊
執行構造方法
-----------------------
執行實例代碼塊
執行構造方法
*/

說明:
1、靜態代碼塊先執行,并且只執行一次,在類加載階段執行
2、 當有對象創建時,才會執行實例代碼塊,實例代碼塊執行完成后,最后構造方法執行
第二種:在存在繼承關系時的執行順序

public class Person {
  int age;
  String name;

  public Person(int age, String name) {
      this.age = age;
      this.name = name;
      System.out.println("Person:執行構造方法");
  }

  {
      System.out.println("Person:執行實例代碼塊");
  }

  static {
      System.out.println("Person:執行靜態代碼塊");
  }
}
public class Student extends Person{
  public Student(int age,String name){
      super(age,name);
      System.out.println("Student:執行構造方法");
  }
  {
      System.out.println("Student:執行實例代碼塊");
  }
  static{
      System.out.println("Student:執行靜態代碼塊");
  }

  public static void main(String[] args) {
      Student a=new Student(20,"luka");
      System.out.println("------------------------");
      Student b=new Student(21,"stepth");
  }
}

/*
執行結果:
Person:執行靜態代碼塊
Student:執行靜態代碼塊
Person:執行實例代碼塊
Person:執行構造方法
Student:執行實例代碼塊
Student:執行構造方法
------------------------
Person:執行實例代碼塊
Person:執行構造方法
Student:執行實例代碼塊
Student:執行構造方法
*/

說明:
1、父類靜態代碼塊優先于子類靜態代碼塊執行,靜態代碼塊相較于其他是最早執行。
2、父類實例代碼塊和父類構造方法緊接著執行。
3、子類的實例代碼塊和子類構造方法緊接著再執行。
4、第二次實例化子類對象時,父類和子類的靜態代碼塊都將不會再執行(靜態代碼塊只執行一次)。

8、父類成員在子類中的可見性

Java中的重要核心知識點之繼承詳解

父類中不同訪問權限的成員,在子類中的可見性又是什么樣子的?

// extend01包中
public class B {
private int a;
protected int b;
public int c;
int d;
}
// extend01包中
// 同一個包中的子類
public class D extends B{
public void method(){
// super.a = 10; // 編譯報錯,父類private成員在相同包子類中不可見
super.b = 20; // 父類中protected成員在相同包子類中可以直接訪問
super.c = 30; // 父類中public成員在相同包子類中可以直接訪問
super.d = 40; // 父類中默認訪問權限修飾的成員在相同包子類中可以直接訪問
}
}
// extend02包中
// 不同包中的子類
public class C extends B {
public void method(){
// super.a = 10; // 編譯報錯,父類中private成員在不同包子類中不可見
super.b = 20; // 父類中protected修飾的成員在不同包子類中可以直接訪問
super.c = 30; // 父類中public修飾的成員在不同包子類中可以直接訪問
//super.d = 40; // 父類中默認訪問權限修飾的成員在不同包子類中不能直接訪問
}
}
// extend02包中
// 不同包中的類
public class TestC {
public static void main(String[] args) {
C c = new C();
c.method();
// System.out.println(c.a); // 編譯報錯,父類中private成員在不同包其他類中不可見
// System.out.println(c.b); // 父類中protected成員在不同包其他類中不能直接訪問
System.out.println(c.c); // 父類中public成員在不同包其他類中可以直接訪問
// System.out.println(c.d); // 父類中默認訪問權限修飾的成員在不同包其他類中不能直接訪問
}
}

**注意:**父類中private成員變量隨時在子類中不能直接訪問,但是也繼承到子類中了。

9、繼承方式

Java中支持以下幾種繼承方式:

單繼承:

Java中的重要核心知識點之繼承詳解

多層繼承:

Java中的重要核心知識點之繼承詳解

不同類繼承同一個類

Java中的重要核心知識點之繼承詳解

不支持多繼承

Java中的重要核心知識點之繼承詳解

10、final關鍵字

final關鍵可以用來修飾變量、成員方法以及類。

1、修飾變量或字段,表示常量(即不能修改)。

final int a = 10;
a = 20; // 編譯出錯

2、修飾類:表示此類不能被繼承。

final public class Animal {
...
}
public class Bird extends Animal {
...
}
// 編譯出錯

平時使用的String字符串類,打開其源碼可以看到它是被final修飾的,不可以被繼承。

Java中的重要核心知識點之繼承詳解

3.、修飾方法:表示該方法不能被重寫。

11、組合

組合也是一種表達類之間關系的方式, 也是能夠達到代碼重用的效果。組合并沒有涉及到特殊的語法(諸如 extends 這樣的關鍵字), 僅僅是將一個類的實例作為另外一個類的字段。
這是繼承和組合的區別。

Java中的重要核心知識點之繼承詳解

//車閘類
class Brake{

}
//車把手類
class Handle{

}
//輪胎類
class Tire{

}

public class Bicycle {
  private Brake brake;    //可以復用車閘中的屬性和方法
  private Handle handle;  //可以復用車把手中的屬性和方法
  private Tire tire;      //可以復用輪胎中的屬性和方法
}

作者:luka.lh
over!??!

到此這篇關于Java中的重要核心知識點之繼承詳解的文章就介紹到這了,更多相關Java 繼承內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/m0_58715346/article/details/120734408

延伸 · 閱讀

精彩推薦
  • Java教程因Spring AOP導致@Autowired依賴注入失敗的解決方法

    因Spring AOP導致@Autowired依賴注入失敗的解決方法

    這篇文章主要給大家介紹了因Spring AOP導致@Autowired依賴注入失敗的解決方法,文中通過示例代碼給大家介紹的非常詳細,對大家具有一定的參考學習價值,...

    ngulc2722020-11-30
  • Java教程Java SPI用法案例詳解

    Java SPI用法案例詳解

    這篇文章主要介紹了Java SPI用法案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    jy的blog11932021-12-11
  • Java教程JAVA比較兩張圖片相似度的方法

    JAVA比較兩張圖片相似度的方法

    這篇文章主要介紹了JAVA比較兩張圖片相似度的方法,涉及java針對圖片像素操作的相關技巧,具有一定參考借鑒價值,需要的朋友可以參考下 ...

    fzhlee2042019-12-28
  • Java教程Java鎖之自旋鎖詳解

    Java鎖之自旋鎖詳解

    這篇文章主要介紹了Java鎖之自旋鎖詳解,本文是系列文章的第一篇,請持續關注腳本之家java欄目,需要的朋友可以參考下 ...

    junjie3342019-11-28
  • Java教程Java使用Statement接口執行SQL語句操作實例分析

    Java使用Statement接口執行SQL語句操作實例分析

    這篇文章主要介紹了Java使用Statement接口執行SQL語句操作,結合實例形式詳細分析了Java使用Statement接口針對mysql數據庫進行連接與執行SQL語句增刪改查等相關...

    Young-xy9032021-05-13
  • Java教程MyBatis學習教程(六)-調用存儲過程

    MyBatis學習教程(六)-調用存儲過程

    這篇文章主要介紹了MyBatis學習教程(六)-調用存儲過程的相關資料,非常不錯,具有參考借鑒價值,感興趣的朋友一起看下吧 ...

    孤傲蒼狼2262020-05-04
  • Java教程Java中關于子類覆蓋父類的拋出異常問題

    Java中關于子類覆蓋父類的拋出異常問題

    今天小編就為大家分享一篇關于Java中關于子類覆蓋父類的拋出異常問題,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起...

    yangyongUestc8512021-07-31
  • Java教程java 1.8 動態代理源碼深度分析

    java 1.8 動態代理源碼深度分析

    下面小編就為大家帶來一篇java 1.8 動態代理源碼深度分析。小編覺得挺不錯的,現在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    Java之家3332020-11-15
主站蜘蛛池模板: 国产午夜亚洲精品不卡 | 欧美日韩一区视频 | 成人性爱视频在线观看 | 婷婷丁香色综合狠狠色 | 国产人成精品午夜在线观看 | 成人一区二区丝袜美腿 | 潘甜甜在线观看 | 幻女free性俄罗斯第一次摘花 | 国内9lporm自拍视频区 | 久久偷拍国2017| 娇妻被老外疯狂调教 | 我的年轻漂亮继坶三级 | 国产色视频一区二区三区 | 国内精品91东航翘臀女神在线 | 9久热这里只有精品免费 | 小小水蜜桃视频高清在线播放 | 果冻传媒新在线观看免费 | 欧美生活一级片 | 色哟哟哟在线精品观看视频 | 水野朝阳厨房系列在线观看 | 为什么丈夫插我我却喜欢被打着插 | 国产精自产拍久久久久久 | 手机看片自拍自自拍日韩免费 | 青青热久免费精品视频精品 | 女同久久另类99精品国产 | 免费在线观看日韩 | 日本高清视频网站 | 精品一区二区三区五区六区 | 国产免费成人在线视频 | 欧美人禽杂交狂配无删完整 | 久久99国产精品二区不卡 | 久久精品热在线观看85 | 国产成人h综合亚洲欧美在线 | 成年极品漫画在线观看 | 四虎影视在线看免费 720p | 好湿好紧太硬了我太爽了网站 | 97超pen个人视频公开视频视 | ipx 在线播放| 久久香蕉国产免费天天 | 国产欧美日韩精品一区二区三区 | 色播艾小青国产专区在线播放 |