< 修飾符> class < 子類名稱> [extends < 父類>] { <屬性和方法的聲明> }
子類繼承了父類,就繼承了父類的方法和屬性。
在子類中,可使用父類中定義的方法和屬性,也能夠建立新的數據和方法。
於是,子類一般比父類的功能更多。
在Java中,繼承的關鍵字用的是「extends」,即子類不是父類的子集,而是對父類的「擴展」。java
Java只支持單繼承,不容許多重繼承
一個子類只能有一個父類
一個父類能夠派生出多個子類
子類不能繼承父類中私有的(private)的成員變量和方法app
package com.uncleyong; import java.util.Date; public class Person { public String name; public int age; public Date birth; private String lover = "lucy"; public String getInfo(){ return "name: " + name + ", " + "age: " + age + ", " + "birth: " + birth+ ", " + "lover: " + lover; } }
package com.uncleyong; public class Student extends Person{ public String school; }
package com.uncleyong; import java.util.Date; public class TestPerson { public static void main(String[] args) { Student student = new Student(); student.name = "Jerry"; student.birth = new Date(); student.age = 1; student.school = "清華"; System.out.println(student.getInfo()); Person person = new Person(); person.age = 1; person.birth = new Date(); person.name = "Tom"; System.out.println(person.getInfo()); } }
能夠對Java類中定義的屬性和方法進行訪問控制----規定不一樣的保護等級: public、protected、default、privateide
在子類中能夠根據須要對從父類中繼承來的方法進行改造—覆蓋方法(方法的重置、重寫),在程序執行時,子類的方法將覆蓋父類的方法。測試
覆蓋方法必須和被覆蓋方法具備相同的方法名稱、參數列表和返回值類型。this
覆蓋方法不能使用比被覆蓋方法更嚴格的訪問權限。spa
package com.uncleyong; /** * 定義一個ManKind類,包括 * 成員變量 int sex 和 int salary; * 方法 void manOrWorman():根據sex的值顯示「man」(sex==1)或者「women」(sex==0); * 方法 void employeed():根據salary的值顯示「no job」(salary==0)或者「 job」(salary!=0)。 */ public class ManKind { int sex; int salary; public void manOrWoman(){ if(sex == 0){ System.out.println("woman"); }else if(sex == 1){ System.out.println("man"); } } public void employeed(){ if(salary != 0){ System.out.println("job"); }else{ System.out.println("no job"); } } }
package com.uncleyong; /** * 定義類 Kids1 繼承ManKind,幷包括 * 成員變量 int yearsOld; * 方法 printAge() 打印 yearsOld 的值。 * * 在Kids1中從新定義employed() 方法,覆蓋父類ManKind中定義的employed()方法, * 輸出「Kids should study and no job.」 */ public class Kids1 extends ManKind { int yearsOld; void printAge(){ System.out.println("yearsOld: " + yearsOld); } // 方法重寫 public void employeed() { System.out.println("Kids should study and no job."); } //在Kids1類的main方法中實例化Kids1的對象 someKid,用該對象訪問其父類的成員變量及方法。 public static void main(String[] args) { Kids1 someKid = new Kids1(); someKid.sex = 1; someKid.salary = 5000; someKid.yearsOld = 25; someKid.manOrWoman(); someKid.employeed(); someKid.printAge(); } }
在Java類中使用super來引用父類的成分orm
super可用於訪問父類中定義的屬性
super可用於調用父類中定義的成員方法
super可用於在子類構造方法中調用父類的構造方法
super的追溯不只限於直接父類對象
子類繼承父類全部的成員變量和成員方法,但不繼承父類的構造方法
在一個Java類中能夠經過兩種方式得到構造方法:
使用系統默認的無參數構造方法
顯式定義一個或多個構造方法
一旦顯式定義了構造方法,則系統再也不提供默認構造方法blog
在子類的構造方法中可以使用super(參數列表)語句調用父類的構造方法
若是子類的構造方法中沒有顯示地調用父類構造方法,也沒有使用this關鍵字調用重載的其它構造方法,則系統默認調用父類無參數的構造方法
若是子類構造方法中既未顯式調用父類構造方法,而父類中又沒有無參的構造方法,則編譯出錯繼承
package com.uncleyong; public class Circle { protected double radius; public Circle() { this.radius = 1; System.out.println("父類構造方法"); } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double findArea(){ return 3.14 * radius * radius; } }
package com.uncleyong; public class Cylinder extends Circle{ private double length; public Cylinder() { this.length = 1; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } /** * 返回圓柱的體積 * @return */ public double findVolume(){ return super.findArea() * length; // 這裏要加super表示調父類的,不加super表示調本類中的findArea方法 } /** * 返回圓柱的表面積 */ @Override public double findArea() { return super.findArea() * 2 + 2 * 3.14 * radius * length; } }
package com.uncleyong; public class TestCylinder { public static void main(String[] args) { Cylinder cylinder = new Cylinder(); cylinder.setLength(2); //返回表面積 System.out.println(cylinder.findArea()); //返回體積 System.out.println(cylinder.findVolume()); } }
多態—在Java中,子類的對象能夠替代父類的對象使用(父類類型的變量能夠指向子類的對象)
一個變量只能有一種肯定的數據類型
一個引用類型變量可能指向(引用)多種不一樣類型的對象
Person p = new Student(); Object o = new Person();//Object類型的變量o,指向Person類型的對象 o = new Student(); //Object類型的變量o,指向Student類型的對象
一個引用類型變量若是聲明爲父類的類型,但實際引用的是子類對象,那麼該變量就不能再訪問子類中添加的屬性和方法
Student m = new Student(); m.school = 「pku」; //合法,Student類有school成員變量 Person e = new Student(); e.school = 「pku」; //非法,Person類沒有school成員變量
屬性是在編譯時肯定的,編譯時e爲Person類型,沒有school成員變量,於是編譯錯誤。
正常的方法調用
Person e = new Person(); e.getInfo(); Student e = new Student(); e.getInfo();
虛擬方法調用(多態狀況下)
Person e = new Student(); e.getInfo(); //調用Student類中重寫的getInfo()方法
編譯時類型和運行時類型:編譯時e爲Person類型,而方法的調用是在運行時肯定的,因此調用的是Student類的getInfo()方法。—— 動態綁定
x instanceof A:檢驗x是否爲類A的對象,返回值爲boolean型。
要求x所屬的類與類A必須是子類和父類的關係,不然編譯錯誤。
若是x屬於類A的子類B,x instanceof A值也爲true。
Boy b = new Boy(); System.out.println(">>>>>>>>>>>>>>>>"); // Boy繼承了Student // System.out.println(b instanceof Student); // true;若是Boy沒有繼承Student,報類型不兼容錯誤 // Boy2繼承了Boy System.out.println(b instanceof Boy2); // false,由於b不是Boy2的對象 System.out.println(b instanceof Boy); // true,由於b是Boy的對象 // Boy2繼承了Boy Boy2 b2 = new Boy2(); System.out.println(b2 instanceof Boy); // true,由於b2是Boy的對象
小的數據類型能夠自動轉換成大的數據類型
如long g=20; double d=12.0f
能夠把大的數據類型強制轉換(casting)成小的數據類型
如 floate f=(float)12.0 int a=(int)1200L
從子類到父類的類型轉換能夠自動進行
從父類到子類的類型轉換必須經過造型(強制類型轉換)實現
無繼承關係的引用類型間的轉換是非法的
在造型前可使用instanceof操做符測試一個對象的類型
package com.uncleyong; public class Person { protected String name="person"; protected int age=50; public String getInfo() { return "Name: "+ name + "\n" +"age: "+ age; } } class Student extends Person { protected String school="pku"; public String getInfo() { return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school; } } class Graduate extends Student{ public String major="IT"; public String getInfo() { return "Name: "+ name + "\nage: "+ age + "\nschool: "+ school+"\nmajor:"+major; } }
package com.uncleyong; public class TestInstance { /* 在類中定義方法method1(Person e); 在method1中: (1)根據e的類型調用相應類的getInfo()方法。 (2)根據e的類型執行: 若是e爲Person類的對象,輸出:「a person」; 若是e爲Student類的對象,輸出 「a student」 「a person 」 若是e爲Graduate類的對象,輸出: 「a graduated student」 「a student」 「a person」 */ public void method1(Person e){ // 多態的體現,Person類型的形參能夠接收實際Person子類對象 String info = e.getInfo(); // 動態綁定 System.out.println(info); if(e instanceof Graduate){ System.out.println("a graduated student"); } if(e instanceof Student){ System.out.println("a student"); } if(e instanceof Person){ System.out.print("a person"); } System.out.println("\n"); } public static void main(String[] args) { TestInstance ti = new TestInstance(); Person p1 = new Person(); ti.method1(p1); Person p2 = new Student(); ti.method1(p2); Person p3 = new Graduate(); ti.method1(p3); } }
Object類是全部Java類的根父類
若是在類的聲明中未使用extends關鍵字指明其父類,則默認父類爲Object類
public class Person {
...
}
等價於:
public class Person extends Object {
...
}
例:
method(Object obj){…} // 能夠接收任何類做爲其參數
Object o=new Person;
method(o);
==:引用類型比較引用(是否指向同一個對象);
Person p1=new Person();
Person p2=new Person();
if (p1==p2){…}
基本類型比較值:
int a=5; if(a==6){…}
用"=="進行比較時,符號兩邊的數據類型必須一致(可自動轉換的基本數據類型除外),不然編譯出錯;
equals()方法是Object類的方法,因爲全部類都繼承Object類,也就繼承了equals()方法。只能比較引用類型,其做用與「==」相同,比較是否指向同一個對象。格式:obj1.equals(obj2)
特例:當用equals()方法進行比較時,對類File、String、Date及封裝類(Wrapper Class)來講,是比較類型及內容而不考慮引用的是不是同一個對象;
緣由:在這些類中覆蓋了equals()方法。
toString()方法在Object類中定義,其返回值是String類型,返回類名和它的引用地址。在進行String與其它類型數據的鏈接操做時,自動調用toString()方法
Date now=new Date();
System.out.println(「now=」+now); 至關於 System.out.println(「now=」+now.toString()); // now=Date@122345
能夠根據須要在用戶自定義類型中重寫toString()方法,如String 類重寫了toString()方法,返回字符串的值。
s1=「hello」;
System.out.println(s1); // 至關於System.out.println(s1.toString());
基本類型數據轉換爲String類型時,調用了對應封裝類的 toString()方法,int a=10; System.out.println(「a=」+a);
示例
package com.uncleyong; public class GeometricObject { protected String color; protected double weight; }
package com.uncleyong; public class Circle1 extends GeometricObject{ private double radius; public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public Circle1() { this.radius = 1; this.weight = 1; this.color = "white"; } public Circle1(double radius) { this.radius = radius; this.weight = 1; this.color = "white"; } public Circle1(double radius, double weight, String color) { this.radius = radius; this.weight = weight; this.color = color; } public double findArea(){ return Math.PI * this.radius * this.radius; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if(obj == null){ return false; } if(!(obj instanceof Circle1)){ return false; } Circle1 c = (Circle1) obj; return c.getRadius() == this.radius; } @Override public String toString() { return "" + this.radius; // 寫爲return this.radius;不行,由於radius是double } }
package com.uncleyong; public class TestCircle1 { /** * 寫一個測試類,建立兩個Circle對象,判斷其顏色是否相等; * 利用equals方法判斷其半徑是否相等; * 利用toString()方法輸出其半徑。 */ public static void main(String[] args) { Circle1 c1 = new Circle1(1, 2, "Black"); Circle1 c2 = new Circle1(2, 3, "Black"); Circle1 c3 = new Circle1(2, 2, "Black"); Circle1 c4 = new Circle1(2, 3, "Red"); // 比顏色 System.out.println(c1.color.equals(c2.color)); // true // 比半徑 System.out.println(c1.equals(c2)); // false // 比顏色 System.out.println(c3.color.equals(c4.color)); // false // 比半徑 System.out.println(c3.equals(c4)); // true System.out.println(c1); // 1.0 打印對象,會自動調對象的toString方法 } }
針對八種基本定義相應的引用類型—封裝類
int i = 10; Integer j = 10; // Integer是封裝類,基本數據類型10賦給j,自動裝箱