為什么使用繼承
使用繼承
編寫父類
class Pet {
//公共的屬性和方法
}
編寫子類
class Dog extends Pet {
//子類特有的屬性和方法
}
class Penguin extends Pet {
}
子類訪問父類成員super
使用super關(guān)鍵字,super代表父類對象
訪問父類構(gòu)造方法
super(); --super調(diào)用構(gòu)造方法時届榄,只能是第一句
super(name);
訪問父類屬性
super.name;
訪問父類方法
super.print();
不能被子類繼承的父類成員
private成員
構(gòu)造方法
protected
可以修飾屬性和方法
本類亏推、同包欲间、子類可以訪問
訪問修飾符小結(jié)
多重繼承關(guān)系的初始化順序
1.父類屬性
2.父類構(gòu)造方法
3.子類屬性
4.子類構(gòu)造方法
class Person {
String name="李光";// 姓名
public Person() {
// super();//寫不寫該語句装黑,效果一樣
System.out.println("execute Person()");
}
public Person(String name) {
this.name = name;
System.out.println("execute Person(name)");
}
}
class Student extends Person {
String school="藍(lán)翔";// 學(xué)校
public Student() {
// super();//寫不寫該語句素标,效果一樣
System.out.println("execute Student() ");
}
public Student(String name, String school) {
super(name); // 顯示調(diào)用了父類有參構(gòu)造方法财异,將不執(zhí)行無參構(gòu)造方法
this.school = school;
System.out.println("execute Student(name,school)");
}
}
class PostGraduate extends Student {
String guide;// 導(dǎo)師
public PostGraduate() {
// super();//寫不寫該語句姻灶,效果一樣
System.out.println("execute PostGraduate()");
}
public PostGraduate(String name, String school, String guide) {
super(name, school);
this.guide = guide;
System.out.println("execute PostGraduate(name, school, guide)");
}
}
class TestInherit {
public static void main(String[] args) {
PostGraduate pgdt=null;
pgdt = new PostGraduate();
System.out.println();
pgdt=new PostGraduate("劉小光","北京大學(xué)","王老師");
}
}
繼承條件下構(gòu)造方法的調(diào)用規(guī)則如下:
如果子類的構(gòu)造方法中沒有通過super顯式調(diào)用父類的有參構(gòu)造方法红碑,也沒有通過this顯式調(diào)用自身的其他構(gòu)造方法名船,則系統(tǒng)會默認(rèn)先調(diào)用父類的無參構(gòu)造方法绰上。在這種情況下,寫不寫“super();”語句渠驼,效果是一樣的蜈块。
如果子類的構(gòu)造方法中通過super顯式調(diào)用父類的有參構(gòu)造方法,那將執(zhí)行父類相應(yīng)構(gòu)造方法迷扇,而不執(zhí)行父類無參構(gòu)造方法百揭。
如果子類的構(gòu)造方法中通過this顯式調(diào)用自身的其他構(gòu)造方法,在相應(yīng)構(gòu)造方法中應(yīng)用以上兩條規(guī)則蜓席。
特別注意的是器一,如果存在多級繼承關(guān)系,在創(chuàng)建一個子類對象時厨内,以上規(guī)則會多次向更高一級父類應(yīng)用祈秕,一直到執(zhí)行頂級父類Object類的無參構(gòu)造方法為止。
閱讀代碼雏胃,思考運(yùn)行結(jié)果
class Car {
private int site = 4; //座位數(shù)
Car(){
System.out.println ("載客量是"+site+"人);
}
public void setSite(int site){
this.site = site;
}
void print(){
System.out.print("載客量是"+site+"人");
}
}
class Bus extends Car {
Bus(int site){
setSite(site);
}
}
public static void main(String[] args) {
Bus bus = new Bus(20);
bus.print();
}
方法重寫
使用繼承之后
調(diào)用父類的print()方法请毛,不能顯示Dog的strain信息和Peguin的sex信息
以上效果如何實(shí)現(xiàn)
**子類重寫父類方法 ** @Override
方法重寫需注意的問題
1.構(gòu)造方法因?yàn)椴荒鼙焕^承,所以不能被重寫丑掺;
方法重寫的規(guī)則
方法名相同
參數(shù)列表相同
返回值類型相同或者是其子類获印;
訪問權(quán)限不能嚴(yán)于父類
抽象類
Pet pet = new Pet ("貝貝",20,40);
pet.print();
實(shí)例化Pet沒有意義
public abstract class Pet {
}
以下代碼的問題:
public abstract class Pet {
public void print() {
//…
}
}
每個子類的實(shí)現(xiàn)不同,抽象類中無法給出合理的print方法的實(shí)現(xiàn)
abstract也可用于方法——抽象方法
抽象方法沒有方法體
抽象方法必須在抽象類里
抽象方法必須在子類中被實(shí)現(xiàn)街州,除非子類是抽象類
public abstract class Pet {
public abstract void print() {
//…
}
}
修改Pet類為抽象類
修改Pet類的print()方法為抽象方法
輸出Dog信息
final用法
Penguin類不希望再被其他類繼承兼丰?
使用final類
public final class Penguin extends Pet {
//…
}
方法不希望被重寫?
使用final方法
public final void print () {
//…
}
屬性值不希望被修改唆缴?
使用常量
public class Penguin {
final String home ="南極";// 居住地
public void setHome(String name){
this.home=home; //錯誤鳍征,不可再賦值
}
}
練習(xí)
汽車租賃公司出租多種車輛,車型和租金情況如下表所示面徽。編寫程序?qū)崿F(xiàn)租賃價格的計算艳丛。
image.png
具體要求:車輛分為轎車和客車兩大類匣掸,它們都繼承自抽象類MotoVehicle,并實(shí)現(xiàn)其抽象方法calRent()氮双。請根據(jù)下面給出的類圖分別創(chuàng)建三個類碰酝,并在測試類TestRent中實(shí)現(xiàn)車輛的租賃。租賃過程如圖所示戴差。
第一個包
package nishishui;
/**
* Created by ttc on 2018/1/2.
*/
public class Bus extends MotoVehicle {
private int seatCount;
public int getSeatCount() {
return seatCount;
}
public void setSeatCount(int seatCount) {
this.seatCount = seatCount;
}
public Bus(String no, String brand, int seatCount)
{
super(no,brand);
this.seatCount = seatCount;
}
第二個包
package nishishui;
/**
* Created by ttc on 2018/1/2.
*/
public class Car extends MotoVehicle{
public Car(String no, String brand)
{
super(no,brand);
}
@Override
int calRent(int days) {
if(getBrand().equals("寶馬"))
{
return 500 * days;
}
else
{
return 600 * days;
}
}
}
第三個包
package nishishui;
import com.sun.org.apache.bcel.internal.generic.MONITORENTER;
/**
* Created by ttc on 2018/1/2.
*/
public abstract class MotoVehicle {
private String no;//車牌號
private String brand;//品牌
abstract int calRent(int days);//計算租金
public MotoVehicle()
{
}
public MotoVehicle(String no, String brand)
{
this.no = no;
this.brand = brand;
}
public String getNo() {
return no;
}
public void setNo(String no) {
this.no = no;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
}
第四個包
package nishishui;
import java.util.Scanner;
/**
* Created by ttc on 2018/1/2.
*/
public class TestRent {
public static void main(String[] args) {
System.out.println("歡迎");
System.out.println("請輸入天數(shù)");
Scanner scanner = new Scanner(System.in);
int days = scanner.nextInt();
System.out.println("請輸入汽車類型1.轎車送爸,2.客車");
int type = scanner.nextInt();
if(type == 1)
{
System.out.println("輸入品牌");
String brand = scanner.next();
Car car = new Car("遼N12345",brand);
int money = car.calRent(days);
System.out.println("租金為"+money);
}
else
{
// Bus bus = new Bus();
}
}
}