一、總結
1.使用extends關鍵字繼承,eg: class Student extends Persion { ...};
2.Java編程規范中類的首字母大寫,方法的首字母小寫單詞首字母代謝,eg: setYourName()
3.子類繼承父類后可以重寫(override)父類的成員方法。如果子類override了,子類中再調用就是調用自己的,若沒有提供,調用的就是父類的。
4.對象實例化的時候,會先調用父類的構造函數,然后再調用子類的構造方法。若類沒有定義構造方法,java編譯器會幫你生成一個public的無參的什么都不做的構造方法。
若父類有多個構造函數,使用super()調用父類的無參構造函數,這個super()在子類的構造方法中是否顯示的寫出來無所謂。也可以在子類的構造函數中顯式調用super()來調用父類的無參構造方法;
也可以用 super(參數描述) 來調用父類的有參數的構造函數。super()必須要在子類的構造函數的最開始處調用。
5.final關鍵字,final表示最終的
若使用final修飾一個類就表示它是一個最終的類,那么它就不能再有子類。 eg. final class A {...}
若使用final來修飾一個方法,就表示它是一個最終的方法,就不能再被復寫。
若使用final修飾成員變量就表示它不能再被修改,就變成了常量。
6.繼承的限制(父傳子)
(1) 子類無法直接訪問父類的privete屬性.
(2) 子類無法訪問父類的"絕招",比如父類將某個方法定位為privete的。
(3) 子類不能私吞祖傳的東西,必須還要繼續往下傳。比如父類的public方法,子類將其重寫成private的是不行的。也就是是子類可以復寫,但是不能縮小其權限。
7.若父類中有一個private的函數,子類實現了一個同名的函數,這不是override,而是自己又重寫寫的一個函數。因為子類根本就看不見父類的這個方法。只不過剛好名字相同而已。
8.抽象類
作用:可以作為一個“模板”來規定子類必須實現的方法。抽象類不能實例化對象,用於繼承。類前加abstract關鍵字修飾。
抽象方法:抽象方法需要加abstract修飾。若有子類繼承這個抽象類的時候,子類中必須實現父類中的抽象方法。
抽象類中可以定義各種變量、常量、方法,從這里看抽象類強於接口。
abstract class 類名 {
屬性
普通方法{}
//抽象方法,可以一個或多個
訪問權限 abstract 返回值類型 方法名(參數); /*只需要聲明,不需要實現*/
}
子類繼承抽象類:
class Student extends Persion {}
9.接口
interface 接口名稱 {
全局常量;
抽象方法;
}
eg:
interface A {
public static final i = 10; //定義成全局常量
public static int j = 15;
public abstract int getNumber();
}
子類實現接口:
class Student implement A,B{ //這里子類同時實現A B這兩個接口(java中只有單繼承,但是可以同時implements多個接口)。
}
class Student extends Persion implement A,B{ //實現A B這兩個接口的同時繼承(抽象)類。
}
有了抽象類還存在接口的原因:抽象類的使用中,一個子類只能繼承一個抽象類,而接口可以突破這個限制。
接口也可以繼承接口,eg: interface B extends A {}, 此時接口B中也會有接口A的方法。
10.抽象類和接口對比
抽象類和接口非常相似,里面都有abstract修飾的抽象方法。抽象類中可以定義變量,也可也定義常量,還可以定義普通的方法,對於接口里面只能定義常量和抽象方法。接口比抽象類優秀的一點是可以突破單繼承的限制。接口和抽象類一般用作模板,其里面定義一些抽象方法,其子類必須實現這些抽象方法。
eg:
接口中寫int i = 10; 編譯器會把它變成 public static final int i = 10;
接口中直接寫成int getNum();編譯器會把它變成 public abstract int getNum();
也就是說這些關鍵字不寫,還是常量,還是抽象方法。
11.只有abstract修飾的抽象類中才可以使用abstract修飾成員方法為抽象方法。
12.java中只有單繼承,但是可以同時implements多個接口。
13.抽象類雖然不能直接實例化對象,但是同樣可以有構造函數,且被繼承時構造函數的調用次序和普通類相同。
14.抽象類的構造函數不能是抽象函數,也即不能加abstract修飾。
15,不可以同時實現接口和繼承(抽象)類, class P implements A, extends Person {} 報錯
16.abstract修飾的抽象類中若沒有實現的函數,必須使用abstract修飾。而且必須寫明權限(接口的默認是public abstract,所以可以可不寫),
17.abstract類implements接口可以不實現接口中的方法,普通類必須實現
abstract class Stub implements ILedService{ }
二、試驗demo
1.繼承
class Person { private int age; public void setAge(int age) { if (age < 0 || age > 200) age = 0; else { this.age = age; } } public int getAge() { return age; } public void printInfo() { System.out.println("age = "+age); } public Person () {System.out.println("Person ()");} public Person (int age) { System.out.println("Person (int age)"); this.age = age; } } class Student extends Person{ private String school; public void setSchool(String school) { this.school = school; } public String getSchool() { return school; } public Student(String school) { /* will call the super() */ //super(); super(5); System.out.println("Student(String school)"); this.school = school; } /* override */ public void printInfo() { System.out.println("school = "+school+"; age = "+getAge()); } } public class Ext4 { public static void main (String args[]) { Student stu = new Student("ustc"); stu.setAge(10); System.out.println(stu.getAge()); System.out.println(stu.getSchool()); stu.printInfo(); } }
2.抽象類
abstract class Father { private int money; public int getMoney() {return money; } public void setMoney(int money) {this.money = money; } public abstract void study(); } class Son extends Father{ public void study() {System.out.println("I am study"); } } public class Ext6 { public static void main (String args[]) { //Father f = new Father(); //Abstract classes are not allowed to be instantiated Son son = new Son(); son.study(); } }
3.接口
abstract class Father { private int money; public int getMoney() {return money; } public void setMoney(int money) {this.money = money; } public abstract void study(); } interface A { public static final int i = 10; public abstract int getNum(); } interface B { public static String name = "InterfaceB"; public abstract String getName(); } class Son extends Father implements A,B{ public int getNum() {return i;} public String getName() {return name;} public void study() {System.out.println("I am study"); } } public class Ext7 { public static void main (String args[]) { Son son = new Son(); System.out.println(son.getName()); son.study(); } }
補充:
抽象類和接口的區別:
| 參數 | 抽象類 | 接口 |
| 默認的方法實現 | 它可以有默認的方法實現 | 接口完全是抽象的。它根本不存在方法的實現 |
| 實現 | 子類使用extends關鍵字來繼承抽象類。如果子類不是抽象類的話,它需要提供抽象類中所有聲明的方法的實現。 | 子類使用關鍵字implements來實現接口。它需要提供接口中所有聲明的方法的實現(若實現類是abstract的也不需要全部實現) |
| 構造器 | 抽象類可以有構造器 | 接口不能有構造器 |
| 與正常Java類的區別 | 除了你不能實例化抽象類之外,它和普通Java類沒有任何區別 | 接口是完全不同的類型 |
| 訪問修飾符 | 抽象方法可以有public、protected和default這些修飾符 | 接口方法默認修飾符是public。你不可以使用其它修飾符。 |
| main方法 | 抽象方法可以有main方法並且我們可以運行它 | 接口沒有main方法,因此我們不能運行它。 |
| 多繼承 | 抽象方法可以繼承一個類和實現多個接口 | 接口只可以繼承一個或多個其它接口 |
| 速度 | 它比接口速度要快 | 接口是稍微有點慢的,因為它需要時間去尋找在類中實現的方法。 |
| 添加新方法 | 如果你往抽象類中添加新的方法,你可以給它提供默認的實現。因此你不需要改變你現在的代碼。 | 如果你往接口中添加方法,那么你必須改變實現該接口的類。 |
