繼承
基礎概念
概念:
- 子類擁有父類的所有屬性和方案,屬性和方法的修飾符不能是private
- 私有屬性和方法一樣會繼承,但是不能對其訪問
優點:
- 代碼復用
- 為多態做鋪墊
JAVA特點: JAVA的類的繼承是單繼承(一個類只有一個直接父類)
形式
class 子類名 extends 父類名
操作
方法的重寫
含義:
子類可以重新修改從父類繼承的方法,當子類調用該方法時候,系統優先調用重寫的
語法規則:
返回值類型,方法名,參數類型及個數,要與父類繼承的方法相同
注意:系統會自動繼承Object類
重寫Object類:
直接打印類名稱,會自動加上.tostring
方法。
編譯器技巧:快讀構建父類方法
方法聲明的形式:訪問權限,返回值類型,方法名稱(參數列表)拋出異常
方法重寫的規則:兩同,兩小,一大
兩同: 法名相同,形參列表相同
兩小:
- 子類方法的返回值類型<=父類方法返回值類型
- 子類方法聲明拋出的異常類<=父類方法聲明拋出的的異常類
一大: 類方法的訪問權限>=父類方法的訪問權限
注意: 覆蓋的方法和被覆蓋的方法只能都是類方法/實例方法。不能既有類方法,又有實例方法
構造方法的繼承
創建對象時候:先創建父類對象,再創建子類構造方法:
先執行父類構造方法,再執行子類構造方法。
默認為無參構造方法super()
<這條語句必須為子類構造方法的第一句>
public class Father {
int a;
public Father(int a)
{
this.a=a;
}
}
public class Child extends Father {
super();//會報錯
/*
正確做法
public Child(int a) {
super(a);
}
*/
}
-
一個類中,先執行屬性初始化,在執行構造方法初始化,
-
先父類,再子類
-
子類屬性與父類屬性重名,子類對象優先調用子類的屬性,方法也是
-
父類和子類有重名的屬性時候,在子類對象中擁有他們各自的內存空間和屬性值
關鍵字
instanceof
作用:
判斷某對象是否是某類的一個實例
要求:
instanceof前面對象和后面類必須是父類和子類關系(否則編譯錯誤)
用法及常識:
public class Child extends Father {
public static void main(String[] args) {
Father f=new Father();
Father fc=new Child();
Child c=new Child();
System.out.println(f instanceof Father);
//判斷父類對象的否的父類類型的一個實例 : true
System.out.println(f instanceof Child);//false
System.out.println(c instanceof Father);//true
System.out.println(c instanceof Child);//true
//下面是上轉型對象
System.out.println(fc instanceof Child);//true
System.out.println(fc instanceof Father);//true
}
final
作用:
- 修飾的類不能被繼承,成為最終類;
-
- 如果被繼承,在子類處編譯錯誤
public fianl Father{}
- 修飾方法不能被重寫
-
- 如果被重寫,在final方法處編譯錯誤
overwrite
作用:
super
限定父類成分
子類中的屬性/方法與父類重名,使用父類的,使用super限定
public class Child extends Father {
int a=20;
public Child(int a) {
super(a);
// TODO Auto-generated constructor stub
}
public void m1()
{
System.out.println("Child m1----");
}
public void m2()
{
System.out.println(a);
m1();
System.out.println(super.a);
super.m1();
}
public static void main(String[] args) {
Child c=new Child(1);
c.m2();
}
}
/*
輸出結果
20
Child m1----
1
Father m1----
*/
引用父類的構造方法
super必須在子類該構造方法的第一條語句
用法:
如果父類是有參構造方法,在子類中:super(參數)
實例:
父類:
public class Product {
String id;
String name;
double count;
/*public Product()
{
super();
}*/
public Product(String a, String b, Double c) {
id = a;
name = b;
count = c;
}
子類:(會報錯)
package prj4;
public class Phone extends Product{
int size;
public Phone(String id,String name ,double price,int size)
{
// super(name, id, null);
this.id=id;
this.name=name;
this.count=price;
this.size=size;
}
}
原因:
子類帶參數構造方法時:會自動加入super()
而父類沒有的無參構造方法,
所以報錯
portected
同一個包下,是可以訪問受保護的方法/變量
不同包下,不能訪問,受保護的屬性和方法,
不同包下的,子類可以受保護的變量和方法
上轉型對象
用子類創建一個對象,
並把這個對象的引用放到父類類聲明的變量中
形式: 父類名 變量名=new 子類名
當子類重寫父類的方法時,用上轉型方法
還原上轉型對象
形式子類名 新變量名 = (子類名)上轉型對象名
注意:
其他類 新變量名 = (其他類名)上轉型變量名
編譯不報錯,但是執行有問題
注意:下面三個都是上轉型變量,但是並不相同
public class Test {
public static void main(String[] args) {
Fathter a=new Child();
//a 能調用Father的所有方法
Shape1 aa=new Child();
//aa 能調用Shape1的所有方法
Interface1 aaa=new Child();
//aaa 能調用Interface1的所有方法
}
}
內涵
package sdut.W;
public class Test {
public static void main(String[] args) {
AA aa=new AA();
System.out.println(aa.a);
System.out.println(aa.b);
aa.m1();
aa.m2();
System.out.println("=================================");
BB bb=new BB();
System.out.println(bb.a);
System.out.println(bb.b);
System.out.println(bb.c);
bb.m1();
bb.m2();
bb.m3();
System.out.println("=================================");
AA ab=new BB();
System.out.println(ab.a);
System.out.println(ab.b);//父類的屬性
//編譯錯誤 System.out.println(ab.c);
ab.m1();
ab.m2();//子類的方法
//編譯錯誤 ab.m3();
//編譯錯誤 BB ba=new AA();
}
}
多態
概念
概念0.1: 定義了一個Father類型的F,它先指向ChildOne對象實例,后指向ChildTwo對象實例,再指向...
概念0.2: 在同一個繼承結構中,使用相同邏輯的代碼,處理不同的對象,從而達到執行不同的行為。
概念1.1: 只有在運行的時候才會知道引用變量所指向的具體實例對象。
概念1.2: 程序中定義的引用變量所指向的“ 具體類型和通過該引用變量發出的方法調用 ” 在編程時並不確定,而是在程序運行期間才確定。
概念1.3: 一個引用變量倒底會指向哪個類的實例對象,該引用變量發出的方法調用到底是哪個類中實現的方法,必須在由程序運行期間才能決定。
概念2.1: 不用修改源程序代碼,就可以讓引用變量綁定到各種不同的類實現上。
(從而導致該引用調用的具體方法隨之改變)
概念2.2: 不修改程序代碼,就可以改變程序運行時所綁定的具體代碼,讓程序可以選擇多個運行狀態。
條件
繼承、重寫、向上轉型
Shape shape;
//shape =new shape();
shape=new Triangle(3, 4, 5);//上轉型對象
System.out.println(shape.length());
System.out.println(shape.area());
shape=new Y(10);//上轉型對象
System.out.println(shape.length());
System.out.println(shape.area());
shape =new C(5, 4);//上轉型對象
System.out.println(shape.length());//多態
System.out.println(shape.area());