繼承
一 、繼承相關(guān)基礎(chǔ)
1.?為什么需要繼承
先看下代碼
// Dog.javapublic 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.Javapublic 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 + " 喵喵喵 ~~~" );}}
2.繼承概念
3.?繼承的語法
4.?父類成員訪問
在繼承體系中,子類將父類中的方法和字段繼承下來了,那在子類中能否直接訪問父類中繼承下來的成員呢?
4.1 子類中訪問父類的成員變量
public class Base {int a ;int b ;}public class Derived extends Base {int c ;public void method (){a = 10 ; // 訪問從父類中繼承下來的 ab = 20 ; // 訪問從父類中繼承下來的 bc = 30 ; // 訪問子類自己的 c}}
4.2子類和父類成員變量同名
4.3?子類中訪問父類的成員方法
同變量一樣,只是當父類與子類發(fā)生方法重寫(參數(shù)也一樣)時訪問子類,發(fā)生方法重載時根據(jù)參數(shù)判斷訪問誰。當父類與子類都沒有該方法時,編譯器報錯。
二、super關(guān)鍵字
1.為什么要使用super關(guān)鍵字
class Base {
int a;
int b;
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
int a;
int b;
public void methodB() {
super.a = 200;
super.b = 201;
System.out.println("Derived中的methodB()方法");
System.out.println(a);
System.out.println(b); //子類的b
System.out.println(super.a);
System.out.println(super.b); //調(diào)用父類的b要用super
super.methodB(); //調(diào)用父類的方法要寫super?
methodB();這里調(diào)用自己,形成死遞歸
}
}
class c {
public static void main(String[] args) {
Derived s=new Derived();
s.a=2;
s.b=5;
s.methodB();
}
}
屏幕輸出結(jié)果
Derived中的methodB()方法
2
5
200
201
Base中的methodB()
class Base {
int a;
int b;
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
int a;
int b;
public void methodB() {
public static void main(String[] args) {
super.a = 200;
super.b = 201;
a=2;
b=5;
System.out.println("Derived中的methodB()方法");
System.out.println(a);
System.out.println(b); //子類的b
System.out.println(super.a);
System.out.println(super.b); //調(diào)用父類的b要用super
super.methodB(); //調(diào)用父類的方法要寫super?
methodB();這里調(diào)用自己,形成死遞歸
}
}這個代碼編譯器會報錯
2.子類構(gòu)造方法
父子父子,先有父再有子,即:子類對象構(gòu)造時,需要先調(diào)用基類構(gòu)造方法,然后執(zhí)行子類的構(gòu)造方法。
public class Base {public Base (){System . out . println ( "Base()" );}}public class Derived extends Base {public Derived (){// super(); // 注意子類構(gòu)造方法中默認會調(diào)用基類的無參構(gòu)造方法: super(),// 用戶沒有寫時 , 編譯器會自動添加,而且 super() 必須是子類構(gòu)造方法中第一條語句(類比this在構(gòu)造方法的作用)System . out . println ( "Derived()" );}}public class Test {public static void main ( String [] args ) {Derived d = new Derived ();}}結(jié)果打?。?Base ()Derived ()
3.super和this的對比
class Base {int a;public Base(){System.out.println("Base()");}}public class Derived extends Base{int a;public Derived(){System.out.println("Derived()");}this.a=1;? //看成Derived.a=1super.a=2;? //看成Base.a=2this();? ?//調(diào)用子類構(gòu)造方法看成Derived()super()? //調(diào)用父類構(gòu)造方法看成Base()}//該代碼沒有主方法,不能運行,只是為了演示方便。
4.?再談初始化
class Person {public String name ;public int age ;public Person ( String name , int age ) {this . name = name ;this . age = age ;System . out . println ( "Person :構(gòu)造方法執(zhí)行 " );}{System . out . println ( "Person :實例代碼塊執(zhí)行 " );}static {System . out . println ( "Person :靜態(tài)代碼塊執(zhí)行 " );}}class Student extends Person {public Student ( String name , int age ) {super ( name , age );System . out . println ( "Student :構(gòu)造方法執(zhí)行 " );}{System . out . println ( "Student :實例代碼塊執(zhí)行 " );}static {System . out . println ( "Student :靜態(tài)代碼塊執(zhí)行 " );}}public class TestDemo4 {public static void main ( String [] args ) {Student student1 = new Student ( " 張三 " , 19 );System . out . println ( "===========================" );Student student2 = new Student ( "gaobo" , 20 );}public static void main1 ( String [] args ) {Person person1 = new Person ( "bit" , 10 );System . out . println ( "============================" );Person person2 = new Person ( "gaobo" , 20 );}//執(zhí)行結(jié)果Person :靜態(tài)代碼塊執(zhí)行Student :靜態(tài)代碼塊執(zhí)行Person :實例代碼塊執(zhí)行Person :構(gòu)造方法執(zhí)行Student :實例代碼塊執(zhí)行Student :構(gòu)造方法執(zhí)行===========================Person :實例代碼塊執(zhí)行Person :構(gòu)造方法執(zhí)行Student :實例代碼塊執(zhí)行Student :構(gòu)造方法執(zhí)行
首先說下類的加載(在生成class文件創(chuàng)建類時就執(zhí)行了)會導(dǎo)致靜態(tài)成員變量先初始化(父類的靜態(tài)變量先初始化,子類的靜態(tài)變量后初始化),而后是靜態(tài)代碼塊初始化(父類的靜態(tài)代碼塊先執(zhí)行,子類的靜態(tài)代碼塊再執(zhí)行),因為類的加載只有一次,所以它們只能執(zhí)行一次。然后就按上面的順序。
三、protected關(guān)鍵字

public class Date3 {
????protected int a=30;
}
class Date2 extends Date3{
????public void a(){
????????System.out.println(super.a);
????????System.out.println(a);
//以下的部分復(fù)雜化了,在繼承關(guān)系中我們可以直接使用a,這里運行沒有問題
Date3 date3 = new Date3();
????????System.out.println(date3.a);
????}
????public static void main(String[] args) {
????????Date2 date2 ?=new Date2();
????????Date3 date3 ?=new Date3();
????????System.out.println(date2.a);
????????System.out.println(date3.a);
????????date2.a();
????}
}
我們看下不同包的情況
package cot;
public class Date1 {
????protected int a=30;
}
package com;
import cot.Date1;
class Date2 extends Date1 {
????public void a(){
????????System.out.println(super.a);
????????System.out.println(a);
//以下代碼會報錯
Date3 date3 = new Date3();
????????System.out.println(date3.a);
????}
????public static void main(String[] args) {
????????Date2 date2 ?=new Date2();
????????Date1 date1 ?=new Date1();
????????System.out.println(date2.a);
? ? ? ?System.out.println(date1.a); //這里會報錯:a 在 cot.Date1 中是 protected 訪問控制
? ? ? ?date2.a();
????}
}
package cot;
public class Date1 {
????protected int a=30;
}
package com;
import cot.Date1;
class Date2 extends Date1 {
????public void a(){
????????System.out.println(super.a);
????}
????public static void main(String[] args) {
????????Date2 date2 ?=new Date2();
???????// Date1 date1 ?=new Date1();
???????// System.out.println(date2.a);
????????//System.out.println(date1.a);
????????date2.a();
????}
}
//輸出結(jié)果:30
注意:父類中private成員變量雖然在子類中不能直接訪問,但是也繼承到子類中去了。?文章來源:http://www.zghlxwxcb.cn/news/detail-856347.html
四、final關(guān)鍵字
final int a = 10 ;a = 20 ; // 編譯出錯
final public class Animal {...}public class Bird extends Animal {...}// 編譯出錯Error :( 3 , 27 ) java : 無法從最終 com . bit . Animal 進行繼
五、繼承與組合
汽車和其輪胎、發(fā)動機、方向盤、車載系統(tǒng)等的關(guān)系就應(yīng)該是組合,因為汽車是有這些部件組成的。
// 輪胎類class Tire {// ...}// 發(fā)動機類class Engine {// ...}// 車載系統(tǒng)類class VehicleSystem {// ...}class Car {private Tire tire ; // 可以復(fù)用輪胎中的屬性和方法private Engine engine ; // 可以復(fù)用發(fā)動機中的屬性和方法private VehicleSystem vs ; // 可以復(fù)用車載系統(tǒng)中的屬性和方法// ...}// 奔馳是汽車class Benz extend Car {// 將汽車中包含的:輪胎、發(fā)送機、車載系統(tǒng)全部繼承下來}
多態(tài)
待更新文章來源地址http://www.zghlxwxcb.cn/news/detail-856347.html
到了這里,關(guān)于Java之繼承和多態(tài)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!